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

