Training—Sharing Files

阅读:http://developer.android.com/training/secure-file-sharing/index.html

 

首先要先注册一个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,resource对应的是下面即将提到的路径问题。

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

In this example, the <files-path> tag shares directories within the files/ directory of your app's internal storage.

其实就是定义了internal storage里的files的images文件,最后的URI形式是:content://com.example.myapp.fileprovider/myimages/default_image.jpg

 

要分享,就是为他人提供文件地址嘛,因此要使用带有ACTION_PICK的过滤器:

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

接下来官方说了一大堆,代码我就不贴了,直接说重点。

既然对方Activity是使用startActivityForResult() 的,因此我们必须返回相关的数据给它。

找到File的地址然后生成File对象,然后使用:

                    fileUri = FileProvider.getUriForFile(
                            MainActivity.this,
                            "com.example.myapp.fileprovider",
                            requestFile);

获得URI,当然还要有权限:

                    mResultIntent.addFlags(
                        Intent.FLAG_GRANT_READ_URI_PERMISSION);

接下来设置一下就行了:

                    mResultIntent.setDataAndType(
                            fileUri,
                            getContentResolver().getType(fileUri));
                    // Set the result
                    MainActivity.this.setResult(Activity.RESULT_OK,
                            mResultIntent);

一般处理完之后,这个Activity就不用了,直接finish就行了。

 

同样,有发就有得收。

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

其实这个过程似乎有些麻烦,不过这是因为,我们能读取该文件的权限是临时的,一旦当前程序栈结束,就再没有权限访问了。

通过URI还能获取文件信息,不再累述,这里看:http://developer.android.com/training/secure-file-sharing/retrieve-info.html

 

 

 

 

posted @ 2013-12-01 19:19  yutoulck  阅读(307)  评论(0编辑  收藏  举报