| Joe Malin | 45edbb7 | 2013-08-26 14:55:54 -0700 | [diff] [blame] | 1 | page.title=Setting Up File Sharing |
| 2 | trainingnavtop=true |
| 3 | @jd:body |
| 4 | |
| 5 | |
| 6 | <div id="tb-wrapper"> |
| 7 | <div id="tb"> |
| 8 | |
| 9 | <!-- table of contents --> |
| 10 | <h2>This lesson teaches you to</h2> |
| 11 | <ol> |
| 12 | <li><a href="#DefineProvider">Specify the FileProvider</a></li> |
| 13 | <li><a href="#DefineMetaData">Specify Sharable Directories</a></li> |
| 14 | </ol> |
| 15 | |
| 16 | <h2>You should also read</h2> |
| 17 | <ul> |
| 18 | <li><a href="{@docRoot}guide/topics/data/data-storage.html">Storage Options</a></li> |
| 19 | <li><a href="{@docRoot}training/basics/data-storage/files.html">Saving Files</a> |
| 20 | </ul> |
| 21 | |
| 22 | </div> |
| 23 | </div> |
| 24 | |
| 25 | <p> |
| 26 | To securely offer a file from your app to another app, you need to configure your app to offer |
| 27 | a secure handle to the file, in the form of a content URI. The Android |
| 28 | {@link android.support.v4.content.FileProvider} component generates content URIs for |
| 29 | files, based on specifications you provide in XML. This lesson shows you how to add the default |
| 30 | implementation of {@link android.support.v4.content.FileProvider} to your app, and how to |
| 31 | specify the files you want to offer to other apps. |
| 32 | </p> |
| Joe Fernandez | 2d96a0d | 2013-10-16 15:05:48 -0700 | [diff] [blame] | 33 | |
| 34 | <p class="note"> |
| 35 | <strong>Note:</strong> The {@link android.support.v4.content.FileProvider} class is part of the |
| 36 | <a href="{@docRoot}tools/support-library/features.html#v4">v4 Support Library</a>. For information |
| 37 | about including this library in your application, see |
| 38 | <a href="{@docRoot}tools/support-library/setup.html">Support Library Setup</a>. |
| 39 | </p> |
| 40 | |
| Joe Malin | 45edbb7 | 2013-08-26 14:55:54 -0700 | [diff] [blame] | 41 | <h2 id="DefineProvider">Specify the FileProvider</h2> |
| 42 | <p> |
| 43 | Defining a {@link android.support.v4.content.FileProvider} for your app requires an entry in |
| 44 | your manifest. This entry specifies the authority to use in generating content URIs, as well as |
| 45 | the name of an XML file that specifies the directories your app can share. |
| 46 | </p> |
| 47 | <p> |
| 48 | The following snippet shows you how to add to your manifest the |
| 49 | <code><a href="{@docRoot}guide/topics/manifest/provider-element.html" |
| 50 | ><provider></a></code> element that specifies the |
| 51 | {@link android.support.v4.content.FileProvider} class, the authority, and the |
| 52 | XML file name: |
| 53 | </p> |
| 54 | <pre> |
| 55 | <manifest xmlns:android="http://schemas.android.com/apk/res/android" |
| 56 | package="com.example.myapp"> |
| 57 | <application |
| 58 | ...> |
| 59 | <provider |
| 60 | android:name="android.support.v4.content.FileProvider" |
| 61 | android:authorities="com.example.myapp.fileprovider" |
| 62 | android:grantUriPermissions="true" |
| 63 | android:exported="false"> |
| 64 | <meta-data |
| 65 | android:name="android.support.FILE_PROVIDER_PATHS" |
| 66 | android:resource="@xml/filepaths" /> |
| 67 | </provider> |
| 68 | ... |
| 69 | </application> |
| 70 | </manifest></pre> |
| 71 | <p> |
| 72 | In this example, the <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#auth" |
| 73 | >android:authorities</a></code> attribute specifies the URI authority |
| 74 | that you want to use for content URIs generated by the |
| 75 | {@link android.support.v4.content.FileProvider}. |
| 76 | In the example, the authority is <code>com.example.myapp.fileprovider</code>. For your own |
| 77 | app, specify an authority consisting of the app's |
| 78 | <code><a href="{@docRoot}guide/topics/manifest/manifest-element.html#package" |
| 79 | >android:package</a></code> value with the string "fileprovider" appended to it. To learn more |
| 80 | about the authority value, see the topic |
| 81 | <a href="{@docRoot}guide/topics/providers/content-provider-basics.html#ContentURIs" |
| 82 | >Content URIs</a> and the documentation for the |
| 83 | <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#auth" |
| 84 | >android:authorities</a></code> attribute. |
| 85 | </p> |
| 86 | <p> |
| 87 | The <code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html" |
| 88 | ><meta-data></a></code> child element of the |
| 89 | <code><a href="{@docRoot}guide/topics/manifest/provider-element.html" |
| 90 | ><provider></a></code> points to an XML file that specifies the directories you want to |
| 91 | share. The <code>android:resource</code> attribute is the path and name of the file, without |
| 92 | the <code>.xml</code> extension.The contents of this file are described in the next section. |
| 93 | </p> |
| 94 | <h2 id="DefineMetaData">Specify Sharable Directories</h2> |
| 95 | <p> |
| 96 | Once you have added the {@link android.support.v4.content.FileProvider} to your app manifest, |
| 97 | you need to specify the directories that contain the files you want to share. To specify the |
| 98 | directories, start by creating the file <code>filepaths.xml</code> in the <code>res/xml/</code> |
| 99 | subdirectory of your project. In this file, specify the directories by adding an XML element for |
| 100 | each directory. The following snippet shows you an example of the contents of |
| 101 | <code>res/xml/filepaths.xml</code>. The snippet also demonstrates how to share a subdirectory |
| 102 | of the <code>files/</code> directory in your internal storage area: |
| 103 | </p> |
| 104 | <pre> |
| 105 | <paths> |
| 106 | <files-path path="images/" name="myimages" /> |
| 107 | </paths></pre> |
| 108 | <p> |
| 109 | In this example, the <code><files-path></code> tag shares directories within the |
| 110 | <code>files/</code> directory of your app's internal storage. The <code>path</code> attribute |
| 111 | shares the <code>images/</code> subdirectory of <code>files/</code>. The <code>name</code> |
| 112 | attribute tells the {@link android.support.v4.content.FileProvider} to add the path segment |
| 113 | <code>myimages</code> to content URIs for files in the <code>files/images/</code> subdirectory. |
| 114 | </p> |
| 115 | <p> |
| 116 | The <code><paths></code> element can have multiple children, each specifying a different |
| 117 | directory to share. In addition to the <code><files-path></code> element, you can |
| 118 | use the <code><external-path></code> element to share directories in external storage, and |
| 119 | the <code><cache-path></code> element to share directories in your internal cache |
| 120 | directory. To learn more about the child elements that specify shared directories, see the |
| 121 | {@link android.support.v4.content.FileProvider} reference documentation. |
| 122 | </p> |
| 123 | <p class="note"> |
| 124 | <strong>Note:</strong> The XML file is the only way you can specify the directories you want to |
| 125 | share; you can't programmatically add a directory. |
| 126 | </p> |
| 127 | <p> |
| 128 | You now have a complete specification of a {@link android.support.v4.content.FileProvider} |
| 129 | that generates content URIs for files in the <code>files/</code> directory of your app's |
| 130 | internal storage or for files in subdirectories of <code>files/</code>. When your app generates |
| 131 | a content URI for a file, it contains the authority specified in the |
| 132 | <code><a href="{@docRoot}guide/topics/manifest/provider-element.html" |
| 133 | ><provider></a></code> element (<code>com.example.myapp.fileprovider</code>), |
| 134 | the path <code>myimages/</code>, and the name of the file. |
| 135 | </p> |
| 136 | <p> |
| 137 | For example, if you define a {@link android.support.v4.content.FileProvider} according to the |
| 138 | snippets in this lesson, and you request a content URI for the file |
| 139 | <code>default_image.jpg</code>, {@link android.support.v4.content.FileProvider} returns the |
| 140 | following URI: |
| 141 | </p> |
| 142 | <pre> |
| 143 | content://com.example.myapp.fileprovider/myimages/default_image.jpg</pre> |
| 144 | |