注:本文翻譯自Google官方的Android Developers Training文檔,譯者技術(shù)一般,由于喜愛安卓而產(chǎn)生了翻譯的念頭,純屬個人興趣愛好。
原文鏈接: http://developer.android.com/training/secure-file-sharing/request-file.html
當(dāng)一個希望訪問由其它應(yīng)用所共享的文件時(shí),需求應(yīng)用(即客戶端)經(jīng)常會向其它應(yīng)用(服務(wù)端)發(fā)送一個文件需求。在大多數(shù)情況下,這個需求會在服務(wù)端應(yīng)用啟動一個 Activity 顯示可以共享的文件。當(dāng)服務(wù)應(yīng)用向客戶應(yīng)用返回了URI后,用戶即選擇了文件。
這節(jié)課向你展示一個客戶應(yīng)用如何向服務(wù)應(yīng)用需求一個文件,接受服務(wù)應(yīng)用發(fā)來的URI,然后使用這個URI打開這個文件。
一). 發(fā)送一個文件需求
為了向服務(wù)應(yīng)用發(fā)送文件需求,在客戶應(yīng)用,需要調(diào)用
startActivityForResult
,同時(shí)傳遞給這個方法一個
Intent
,它包含了客戶應(yīng)用能處理的某行為,比如
ACTION_PICK
;以及一個MIME類型。
例如,下面的代碼展示了如何向服務(wù)端應(yīng)用發(fā)送一個
Intent
,來啟動在
Sharing a File
(博客鏈接:
http://www.cnblogs.com/jdneo/p/3480677.html
)中提到的
Activity
:
public class MainActivity extends Activity { private Intent mRequestFileIntent; private ParcelFileDescriptor mInputPFD; ... @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); mRequestFileIntent = new Intent(Intent.ACTION_PICK); mRequestFileIntent.setType( "image/jpg" ); ... } ... protected void requestFile() { /** * When the user requests a file, send an Intent to the * server app. * files. */ startActivityForResult(mRequestFileIntent, 0 ); ... } ... }
二). 訪問需求的文件 ?
當(dāng)服務(wù)應(yīng)用向客戶應(yīng)用發(fā)回包含URI的 Intent 時(shí),這個 Intent 會傳遞給客戶應(yīng)用的覆寫的 onActivityResult() 方法當(dāng)中。一旦客戶應(yīng)用有了文件的URI,它就可以通過獲取其 FileDescriptor 來訪問文件。
文件的安全問題在這一過程中不用過多擔(dān)心,因?yàn)檫@個客戶應(yīng)用所受到的所有數(shù)據(jù)只有URI而已。由于URI不包含目錄路徑,客戶應(yīng)用無法查詢出或者打開任何服務(wù)應(yīng)用的其他文件。客戶應(yīng)用僅僅獲取了這個文件的訪問渠道和訪問的權(quán)限。同時(shí)訪問權(quán)限是臨時(shí)的,一旦這個客戶應(yīng)用的任務(wù)棧被完成了,這個文件將只能被服務(wù)應(yīng)用訪問。
下面的例子展示了客戶應(yīng)用如何處理發(fā)自服務(wù)應(yīng)用的
Intent
,以及如何客戶應(yīng)用使用URI獲取
FileDescriptor
:
/* * When the Activity of the app that hosts files sets a result and calls * finish(), this method is invoked. The returned Intent contains the * content URI of a selected file. The result code indicates if the * selection worked or not. */ @Override public void onActivityResult( int requestCode, int resultCode, Intent returnIntent) { // If the selection didn't work if (resultCode != RESULT_OK) { // Exit without doing anything else return ; } else { // Get the file's content URI from the incoming Intent Uri returnUri = returnIntent.getData(); /* * Try to open the file for "read" access using the * returned URI. If the file isn't found, write to the * error log and return. */ try { /* * Get the content resolver instance for this context, and use it * to get a ParcelFileDescriptor for the file. */ mInputPFD = getContentResolver().openFileDescriptor(returnUri, "r" ); } catch (FileNotFoundException e) { e.printStackTrace(); Log.e( "MainActivity", "File not found." ); return ; } // Get a regular file descriptor for the file FileDescriptor fd = mInputPFD.getFileDescriptor(); ... } }
方法 openFileDescriptor() 返回一個文件的 ParcelFileDescriptor 。從這個對象中,客戶應(yīng)用可以獲取 FileDescriptor 對象,然后用戶就可以利用這個對象讀取這個文件。 ?
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
