文件分享(使用Content URI)

来源:互联网 发布:win10优化 编辑:程序博客网 时间:2024/04/29 19:22

一、在manifest文件中声明FileProvider,如:

<manifest xmlns: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"            android:grantUriPermissions="true"            android:exported="false">            <meta-data                android:name="android.support.FILE_PROVIDER_PATHS"                android:resource="@xml/filepaths" />        </provider>        ...    </application></manifest>

authorities属性指明FileProvider为content URI产生的URI域名部分,meta-data下的resource则指明你要分享的文件夹。


二、指明可分享的文件夹
在res文件夹下新建xml文件夹,在xml文件夹下新建resource属性指明的filepaths.xml文件,在其中声明可分享的文件夹,如:

<paths>    <files-path path="images/" name="myimages" /></paths>

<paths>标签可以有多个子节点,每个子节点指明了一个分享的文件夹;
<file-path>标签指示要分享的文件夹位于你的app的内存的files目录下,path属性表明一个子文件夹,name属性添加对应的路径到content URI;
<external-path>标签指示要分享的文件位于外部存储的文件夹;
<cache-path>标签指示要分享的文件位于app的缓存文件夹下。


三.设计一个文件选择的界面
在manifest文件中声明该界面,action为ACTION_PICK,category为CATEGORY_DEFAULT和CATEGORY_OPENABLE,也可以声明你的app可以分享的文件类型,如:

<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>




四、用具体代码定义你的文件分享界面,如用一个listview显示指定文件夹下所有的文件的路径,如:

public class FileSelectActivity 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();/*Display the file names in the ListView */...}}

五、当用户点击listview中的一条数据时,生成该文件的content URI:

 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(                            FileSelectActivity.this,                            "com.example.myapp.fileprovider",                            requestFile);                } catch (IllegalArgumentException e) {                    Log.e("File Selector",                          "The selected file can't be shared: " +                          clickedFilename);                }                ...            }        });        ...    }


六、为你的content URI保证用户使用权限,通过调用addFlags()方法:

if (fileUri != null) {                    // Grant temporary read permission to the content URI                    mResultIntent.addFlags(                        Intent.FLAG_GRANT_READ_URI_PERMISSION);                }


七、设置界面返回数据:

 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);                    }                }

八、finish该界面,可以在该界面显示一个Done按钮,当用户点击时关闭当前页面,如:

 public void onDoneClick(View v) {        // Associate a method with the Done button        finish();    }

这样我们就响应了其他应用获取文件的请求,并开启了相应的界面,并将content URI作为结果返回。

九、访问获取到的文件:
使用FileDescriptor查看返回的content URI,如:

@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();            ...        }    }



0 0
原创粉丝点击