注:本文翻譯自Google官方的Android Developers Training文檔,譯者技術(shù)一般,由于喜愛安卓而產(chǎn)生了翻譯的念頭,純屬個(gè)人興趣愛好。
原文鏈接: http://developer.android.com/training/secure-file-sharing/request-file.html
當(dāng)一個(gè)希望訪問由其它應(yīng)用所共享的文件時(shí),需求應(yīng)用(即客戶端)經(jīng)常會向其它應(yīng)用(服務(wù)端)發(fā)送一個(gè)文件需求。在大多數(shù)情況下,這個(gè)需求會在服務(wù)端應(yīng)用啟動一個(gè) Activity 顯示可以共享的文件。當(dāng)服務(wù)應(yīng)用向客戶應(yīng)用返回了URI后,用戶即選擇了文件。
這節(jié)課向你展示一個(gè)客戶應(yīng)用如何向服務(wù)應(yīng)用需求一個(gè)文件,接受服務(wù)應(yīng)用發(fā)來的URI,然后使用這個(gè)URI打開這個(gè)文件。
一). 發(fā)送一個(gè)文件需求
為了向服務(wù)應(yīng)用發(fā)送文件需求,在客戶應(yīng)用,需要調(diào)用
startActivityForResult
,同時(shí)傳遞給這個(gè)方法一個(gè)
Intent
,它包含了客戶應(yīng)用能處理的某行為,比如
ACTION_PICK
;以及一個(gè)MIME類型。
例如,下面的代碼展示了如何向服務(wù)端應(yīng)用發(fā)送一個(gè)
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í),這個(gè) Intent 會傳遞給客戶應(yīng)用的覆寫的 onActivityResult() 方法當(dāng)中。一旦客戶應(yīng)用有了文件的URI,它就可以通過獲取其 FileDescriptor 來訪問文件。
文件的安全問題在這一過程中不用過多擔(dān)心,因?yàn)檫@個(gè)客戶應(yīng)用所受到的所有數(shù)據(jù)只有URI而已。由于URI不包含目錄路徑,客戶應(yīng)用無法查詢出或者打開任何服務(wù)應(yīng)用的其他文件。客戶應(yīng)用僅僅獲取了這個(gè)文件的訪問渠道和訪問的權(quán)限。同時(shí)訪問權(quán)限是臨時(shí)的,一旦這個(gè)客戶應(yīng)用的任務(wù)棧被完成了,這個(gè)文件將只能被服務(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() 返回一個(gè)文件的 ParcelFileDescriptor 。從這個(gè)對象中,客戶應(yīng)用可以獲取 FileDescriptor 對象,然后用戶就可以利用這個(gè)對象讀取這個(gè)文件。 ?
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

