(1)指定FileProvider
<manifestxmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp">
<application
...>
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.example.myapp.fileprovider" //分享的URI地址
android:grantUriPermissions="true"
android:exported="false">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
//filepaths是一个xml文件,记录分享的文件路径
//resource属性不能直接设置成文件路径,XML文件时唯一的指定方式
</provider>
...
</application>
</manifest>
res/xml/filepaths.xml
<paths>
<files-pathpath="images/" name="myimages" /> <!-- 内置存储路径-->
<external-path> <!-- 外存储路径-->
<cache-path> <!--内置存储缓存路径-->
</paths>
假设要获取images/文件夹下的default_image.jpg,最后获取的资源路径为:
content://com.example.myapp.fileprovider/myimages/default_image.jpg
创建选择页面Activity
(1)配置清单文件,action设置为pick,category设置为DEFAULT和OPENABLE,数据类型设置为分享的文件类型
<manifestxmlns:android="http://schemas.android.com/apk/res/android">
...
<application>
...
<activity
android:name=".FileSelectActivity"
android:label="@"FileSelector" >
<intent-filter>
<action
android:name="android.intent.action.PICK"/>
<category
android:name="android.intent.category.DEFAULT"/>
<category
android:name="android.intent.category.OPENABLE"/>
<dataandroid:mimeType="text/plain"/>
<dataandroid:mimeType="image/*"/>
</intent-filter>
</activity>
(2)Activity中代码
public classMainActivity extends Activity {
// The path to the root of thisapp's internal storage
private File mPrivateRootDir;
// The path to the"images" subdirectory
private File mImagesDir;
// Array of files in the imagessubdirectory
File[] mImageFiles;
// Array of filenames correspondingto mImageFiles
String[] mImageFilenames;
// Initialize the Activity
@Override
protected void onCreate(BundlesavedInstanceState) {
...
// Setup an Intent to send back to apps that request a file
mResultIntent = newIntent("com.example.myapp.ACTION_RETURN_FILE");
// Getthe files/ subdirectory of internal storage
mPrivateRootDir = getFilesDir();
// Getthe files/images subdirectory;
mImagesDir = new File(mPrivateRootDir, "images");
// Getthe files in the images subdirectory
mImageFiles = mImagesDir.listFiles();
//-------------把 mImageFiles 放到 ListView 中-----------------------------------------------------------
//Define a listener that responds to clicks on a file in the ListView
mFileListView.setOnItemClickListener(
newAdapterView.OnItemClickListener() {
@Override
/*
* When a filename in the ListView is clicked, get its
* content URI and send it to the requesting app
*/
public void onItemClick(AdapterView<?>adapterView,
Viewview,
intposition,
longrowId) {
/*
* Get a File for the selected filename.
* Assume that the file names are inthe
* mImageFilename array.
*/
File requestFile = new File(mImageFiles [position]);
/*
* Most file-related method calls needto be in
* try-catch blocks.
*/
// Use the FileProvider to get acontent URI
try {
fileUri = FileProvider.getUriForFile( MainActivity.this,
"com.example.myapp.fileprovider",
requestFile);
if (fileUri != null){
//---------------------设置文件权限-----------------------------------
mResultIntent.addFlags( Intent.FLAG_GRANT_READ_URI_PERMISSION);
// ----------------Put the Uri and MIME type in the resultIntent --------------------------------
mResultIntent.setDataAndType( fileUri, getContentResolver().getType(fileUri));
// Set the result
MainActivity.this.setResult(Activity.RESULT_OK, mResultIntent);
} else {
mResultIntent.setDataAndType(null, "");
MainActivity.this.setResult(RESULT_CANCELED, mResultIntent);
}
} catch (IllegalArgumentException e){
Log.e("File Selector",
"The selected file can't be shared: " +
clickedFilename);
}
}
});
}
}
获取共享文件
使用startActivityForResult指定action和MIME类型
public classMainActivity extends Activity {
private IntentmRequestFileIntent;
private ParcelFileDescriptormInputPFD;
...
@Override
protected void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRequestFileIntent = new Intent(Intent.ACTION_PICK);
mRequestFileIntent.setType("image/jpg");
...
}
...
protected void requestFile() {
/**
* When theuser requests a file, send an Intent to the
* server app.
* files.
*/
startActivityForResult(mRequestFileIntent,0);
...
}
/*
* When the Activity of the app thathosts files sets a result and calls
* finish(), this method is invoked.The returned Intent contains the
* content URI of a selected file. Theresult code indicates if the
* selection worked or not.
*/
@Override
public void onActivityResult(intrequestCode, int resultCode, Intent returnIntent) {
// Ifthe 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
UrireturnUri = returnIntent.getData(); //从返回的Intent中获取文件Uri
/*
* 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 instancefor this context, and use it
* to get a ParcelFileDescriptor forthe file.
*/
mInputPFD = getContentResolver().openFileDescriptor(returnUri,"r");
} catch(FileNotFoundException e) {
e.printStackTrace();
Log.e("MainActivity","File not found.");
return;
}
// 获取文件描述器
FileDescriptor fd = mInputPFD.getFileDescriptor();
// 获取 MIME 类型
String mimeType =getContentResolver().getType(returnUri);
...
/**
* FileProvider 提供默认的query()方法实现,返回名称(DISPLAY_NAME)和文件大小(SIZE)两列
* DISPLAY_NAME:是一个字符串跟File.getName()返回值一样
* SIZE:文件字节大小long型,跟File.length() 返回一样
*/
Cursor returnCursor= getContentResolver().query(returnUri,null, null, null, null);
/*
* Get thecolumn indexes of the data in the Cursor,
* move to thefirst row in the Cursor, get the data,
* and displayit.
*/
intnameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
intsizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE);
returnCursor.moveToFirst();
TextView nameView = (TextView) findViewById(R.id.filename_text);
TextView sizeView = (TextView) findViewById(R.id.filesize_text);
nameView.setText(returnCursor.getString(nameIndex));
sizeView.setText(Long.toString(returnCursor.getLong(sizeIndex)));
...
}
}
}