本文共 4798 字,大约阅读时间需要 15 分钟。
在收到其他app要求共享文件的需求后,你的app 返回一个URI。你的app应该提供一个activity 来让 其他app选择文件.其他app 通过startActivityForResult(Intent)来启动这个activity,其中Intent的action是ACTION_PICK.这时候你就返回给其他app一个被选择文件的URI。 Create a File Selection Activity <manifest xmlns:android="http://schemas.android.com/apk/res/android"> ... <application> ... <activity android:name=".FileSelectActivity" android:label="@File Selector" > <intent-filter> <action android:name="android.intent.action.PICK"/> <category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.OPENABLE"/> <data android:mimeType="text/plain"/> <data android:mimeType="image/*"/> </intent-filter> </activity> 最重要的是ACTION 一定要是action.PICK。category 一定要是DEFAULT 和 OPENABLE。mimeType提供文件的类型为text/plain 和image/*. Define the file selection Activity in code public class MainActivity extends Activity { // The path to the root of this app's internal storage private File mPrivateRootDir; // The path to the "images" subdirectory private File mImagesDir; // Array of files in the images subdirectory File[] mImageFiles; // Array of filenames corresponding to mImageFiles String[] mImageFilenames; // Initialize the Activity @Override protected void onCreate(Bundle savedInstanceState) { ... // Set up an Intent to send back to apps that request a file mResultIntent = new Intent("com.example.myapp.ACTION_RETURN_FILE"); // Get the files/ subdirectory of internal storage mPrivateRootDir = getFilesDir(); // Get the files/images subdirectory; mImagesDir = new File(mPrivateRootDir, "images"); // Get the files in the images subdirectory mImageFiles = mImagesDir.listFiles(); // Set the Activity's result to null to begin with setResult(Activity.RESULT_CANCELED, null); /* * Display the file names in the ListView mFileListView. * Back the ListView with the array mImageFilenames, which * you can create by iterating through mImageFiles and * calling File.getAbsolutePath() for each File */ ... } ... } 没啥特别之处. Respond to a File Selection activity 可以用listview来显示可以共享的文件.当用户点击文件的时候,我们可以在onItemClick()中的到用户选择的文件. protected void onCreate(Bundle savedInstanceState) { ... // Define a listener that responds to clicks on a file in the ListView mFileListView.setOnItemClickListener( new AdapterView.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, View view, int position, long rowId) { /* * Get a File for the selected file name. * Assume that the file names are in the * mImageFilename array. */ File requestFile = new File(mImageFilename[position]); /* * Most file-related method calls need to be in * try-catch blocks. */ // Use the FileProvider to get a content URI try { fileUri = FileProvider.getUriForFile( MainActivity.this, "com.example.myapp.fileprovider", requestFile); } catch (IllegalArgumentException e) { Log.e("File Selector", "The selected file can't be shared: " + clickedFilename); } ... } }); ... } 在onItemClick中调用getUriForFile就可以返回uri,第一个参数传this,二个参数是你在<provide>中指定的authority,第三个参数是选择文件 你只能为<paths> 下的文件产生Uri,如果传人的文件不再<paths>中getUriForFile 会返回一个IllegalArgumentException。 Grant Permissions for the File 用Intent 为其他app访问文件添加权限. protected void onCreate(Bundle savedInstanceState) { ... // Define a listener that responds to clicks in the ListView mFileListView.setOnItemClickListener( new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int position, long rowId) { ... if (fileUri != null) { // Grant temporary read permission to the content URI mResultIntent.addFlags( Intent.FLAG_GRANT_READ_URI_PERMISSION); } ... } ... }); ... } 尽量避免调用Context.grantUriPermission()来准许权限。调用这种方法得到的权限只能调用Context.RevokeUriPermission()来取消. Share the File with the Requesting App 共享其他app要求文件,需要用Intent 发送写到content uri,且用setResult告知其他app操作ok. protected void onCreate(Bundle savedInstanceState) { ... // Define a listener that responds to clicks on a file in the ListView mFileListView.setOnItemClickListener( new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int position, long rowId) { ... if (fileUri != null) { ... // Put the Uri and MIME type in the result Intent 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); } } }); 当用户选择文件后,应该立刻停止提供文件选择的Activity,一般是提供一个button来用户点击。在button的回调函数中我们结束当前Activity. 在layout文件中通过android:onClick 指定button的回调函数为onDoneClick。然后调用finish()结束当前Activity. public void onDoneClick(View v) { // Associate a method with the Done button finish(); }转载地址:http://ntcmi.baihongyu.com/