docs: Migrating Scoped Dir Access preview docs into DAC

For Android N release, migrating and updating Scoped Directory Access
docs into regular DAC docs. Updated TOC and added redirect.
Removed preview/features doc. Updated and moved images.

Bug: 30257320
Change-Id: I3440fe1b74947cbfbd1ada6f5d6bee5e49847927
This commit is contained in:
Daniel Yu
2016-07-22 15:50:58 -07:00
parent bb0f35306e
commit 8a481eaf20
12 changed files with 66 additions and 36 deletions

View File

@@ -1214,3 +1214,5 @@ redirects:
to: /training/tv/tif/content-recording.html to: /training/tv/tif/content-recording.html
- from: /preview/features/direct-boot.html - from: /preview/features/direct-boot.html
to: /training/articles/direct-boot.html to: /training/articles/direct-boot.html
- from: /preview/features/scoped-folder-access.html
to: /training/articles/scoped-directory-access.html

View File

@@ -252,6 +252,17 @@ external storage on a computer or removes the media, and there's no security enf
save to the external storage. All applications can read and write files placed on the external save to the external storage. All applications can read and write files placed on the external
storage and the user can remove them.</p> storage and the user can remove them.</p>
<h3 id="ScopedDirAccess">Using Scoped Directory Access</h3>
On Android 7.0 or later, if you need access to a specific directory on
external storage, use scoped directory access. Scoped directory access
simplifies how your application accesses standard external storage directories,
such as the <code>Pictures</code> directory, and provides a simple
permissions UI that clearly details what directory the application is
requesting access to. For more details on scoped directory access, see
<a href="{@docRoot}training/articles/scoped-directory-access.html">Using
Scoped Directory Access</a>.
<h3 id="ExternalPermissions">Getting access to external storage</h3> <h3 id="ExternalPermissions">Getting access to external storage</h3>
<p>In order to read or write files on the external storage, your app must acquire the <p>In order to read or write files on the external storage, your app must acquire the

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 239 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 221 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 249 KiB

View File

@@ -1397,6 +1397,11 @@ toc:
path_attributes: path_attributes:
- name: description - name: description
value: How use device encrypted storage during Direct Boot mode. value: How use device encrypted storage during Direct Boot mode.
- title: Using Scoped Directory Access
path: /training/articles/scoped-directory-access.html
path_attributes:
- name: description
value: How to use scoped directory access to request access to external storage directories.
- title: Best Practices for Permissions & Identifiers - title: Best Practices for Permissions & Identifiers
path: /training/best-permissions-ids.html path: /training/best-permissions-ids.html

View File

@@ -1,11 +1,10 @@
page.title=Scoped Directory Access page.title=Using Scoped Directory Access
page.keywords=preview,sdk,scoped directory access page.keywords=scoped directory access
page.tags=androidn
@jd:body @jd:body
<div id="qv-wrapper"> <div id="tb-wrapper">
<div id="qv"> <div id="tb">
<h2>In this document</h2> <h2>In this document</h2>
<ol> <ol>
<li><a href="#accessing">Accessing an External Storage Directory</a></li> <li><a href="#accessing">Accessing an External Storage Directory</a></li>
@@ -32,29 +31,37 @@ via a system UI, which is unnecessary if your app always accesses the same
external directory.</li> external directory.</li>
</ul> </ul>
<p>Android N provides a new simplified API to access <p>Android 7.0 provides a simplified API to access common external storage
common external storage directories. </p> directories.</p>
<h2 id="accessing">Accessing an External Storage Directory</h2> <h2 id="accessing">Accessing an External Storage Directory</h2>
<p>Use the <code>StorageManager</code> class to get the appropriate <p>Use the {@link android.os.storage.StorageManager} class to get the
<code>StorageVolume</code> instance. Then, create an intent by calling the appropriate {@link android.os.storage.StorageVolume} instance. Then, create
<code>StorageVolume.createAccessIntent()</code> method of that instance. an intent by calling the
{@link android.os.storage.StorageVolume#createAccessIntent
StorageVolume.createAccessIntent()} method of that instance.
Use this intent to access external storage directories. To get a list of Use this intent to access external storage directories. To get a list of
all available volumes, including removable media volumes, use all available volumes, including removable media
<code>StorageManager.getVolumesList()</code>.</p> volumes, use {@link android.os.storage.StorageManager#getStorageVolumes
StorageManager.getStorageVolumes()}.</p>
<p>If you have information about a specific file, use <p>If you have information about a specific file, use
<code>StorageManager.getStorageVolume(File)</code> to get the {@link android.os.storage.StorageManager#getStorageVolume
<code>StorageVolume</code> that contains the file. Call StorageManager.getStorageVolume(File)} to get the
<code>createAccessIntent()</code> on this <code>StorageVolume</code> to access {@link android.os.storage.StorageVolume} that contains the file. Call
{@link android.os.storage.StorageVolume#createAccessIntent
createAccessIntent()} on this
{@link android.os.storage.StorageVolume} to access
the external storage directory for the file.</p> the external storage directory for the file.</p>
<p> <p>
On secondary volumes, such as external SD cards, pass in null when calling On secondary volumes, such as external SD cards, pass in null when calling
<code>StorageVolume.createAccessIntent()</code> to request access to the entire {@link android.os.storage.StorageVolume#createAccessIntent
createAccessIntent()} to request access to the entire
volume, instead of a specific directory. volume, instead of a specific directory.
<code>StorageVolume.createAccessIntent()</code> returns null if you pass in {@link android.os.storage.StorageVolume#createAccessIntent
createAccessIntent()} returns null if you pass in
null to the primary volume, or if you pass in an invalid directory name. null to the primary volume, or if you pass in an invalid directory name.
</p> </p>
@@ -63,7 +70,7 @@ null to the primary volume, or if you pass in an invalid directory name.
<pre> <pre>
StorageManager sm = (StorageManager)getSystemService(Context.STORAGE_SERVICE); StorageManager sm = (StorageManager)getSystemService(Context.STORAGE_SERVICE);
StorageVolume volume = sm.getPrimaryVolume(); StorageVolume volume = sm.getPrimaryStorageVolume();
Intent intent = volume.createAccessIntent(Environment.DIRECTORY_PICTURES); Intent intent = volume.createAccessIntent(Environment.DIRECTORY_PICTURES);
startActivityForResult(intent, request_code); startActivityForResult(intent, request_code);
</pre> </pre>
@@ -71,25 +78,27 @@ startActivityForResult(intent, request_code);
<p>The system attempts to grant access to the external directory, and if <p>The system attempts to grant access to the external directory, and if
necessary confirms access with the user using a simplified UI:</p> necessary confirms access with the user using a simplified UI:</p>
<img src="{@docRoot}preview/images/scoped-folder-access-framed.png" <img src="{@docRoot}images/android-7.0/scoped-directory-access-framed.png"
srcset="{@docRoot}preview/images/scoped-folder-access-framed.png 1x, srcset="{@docRoot}images/android-7.0/scoped-directory-access-framed.png 1x,
{@docRoot}preview/images/scoped-folder-access-framed_2x.png 2x" /> {@docRoot}images/android-7.0/scoped-directory-access-framed_2x.png 2x" />
<p class="img-caption"><strong>Figure 1.</strong> An application requesting <p class="img-caption"><strong>Figure 1.</strong> An application requesting
access to the Pictures directory.</p> access to the Pictures directory.</p>
<p>If the user grants access, the system calls your <p>If the user grants access, the system calls your
<code>onActivityResult()</code> override with a result code of {@link android.app.Activity#onActivityResult onActivityResult()} override
<code>Activity.RESULT_OK</code>, and intent data that contains the URI. Use with a result code of {@link android.app.Activity#RESULT_OK
RESULT_OK}, and intent data that contains the URI. Use
the provided URI to access directory information, similar to using URIs the provided URI to access directory information, similar to using URIs
returned by the returned by the
<a href="{@docRoot}guide/topics/providers/document-provider.html">Storage <a href="{@docRoot}guide/topics/providers/document-provider.html">Storage
Access Framework</a>.</p> Access Framework</a>.</p>
<p>If the user doesn't grant access, the system calls your <p>If the user doesn't grant access, the system calls your
<code>onActivityResult()</code> override with a result code of {@link android.app.Activity#onActivityResult onActivityResult()} override
<code>Activity.RESULT_CANCELED</code>, and null intent data.</p> with a result code of {@link android.app.Activity#RESULT_CANCELED
RESULT_CANCELED}, and null intent data.</p>
<p class="note"><b>Note</b>: Getting access to a specific external directory <p>Getting access to a specific external directory
also gains access to subdirectories within that directory.</p> also gains access to subdirectories within that directory.</p>
<h2 id="removable">Accessing a Directory on Removable Media</h2> <h2 id="removable">Accessing a Directory on Removable Media</h2>
@@ -112,9 +121,9 @@ first add a {@link android.content.BroadcastReceiver} that listens for the
<p>When the user mounts removable media, like an SD card, the system sends a <p>When the user mounts removable media, like an SD card, the system sends a
{@link android.os.Environment#MEDIA_MOUNTED} notification. This notification {@link android.os.Environment#MEDIA_MOUNTED} notification. This notification
provides a <code>StorageVolume</code> object in the intent data that you can provides a {@link android.os.storage.StorageVolume} object in the intent data
use to access directories on the removable media. The following example that you can use to access directories on the removable media. The following
accesses the <code>Pictures</code> directory on removable media:</p> example accesses the <code>Pictures</code> directory on removable media:</p>
<pre> <pre>
// BroadcastReceiver has already cached the MEDIA_MOUNTED // BroadcastReceiver has already cached the MEDIA_MOUNTED
@@ -129,19 +138,22 @@ startActivityForResult(intent, request_code);
<p>Where possible, persist the external directory access URI so you don't have <p>Where possible, persist the external directory access URI so you don't have
to repeatedly ask the user for access. Once the user has granted access, call to repeatedly ask the user for access. Once the user has granted access, call
<code>getContentResolver().takePersistableUriPermssion()</code> with the {@link android.content.Context#getContentResolver getContentResolver()} and
directory access URI. The system will persist the URI and subsequent access with the returned {@link android.content.ContentResolver} call
requests will return <code>RESULT_OK</code> and not show confirmation UI to the {@link android.content.ContentResolver#takePersistableUriPermission
user.</p> takePersistableUriPermission()} with the directory access URI. The system will
persist the URI and subsequent access requests will return
{@link android.app.Activity#RESULT_OK RESULT_OK} and not show confirmation
UI to the user.</p>
<p>If the user denies access to an external directory, do not immediately <p>If the user denies access to an external directory, do not immediately
request access again. Repeatedly insisting on access results in a poor user request access again. Repeatedly insisting on access results in a poor user
experience. If a request is denied by the user, and the app requests access experience. If a request is denied by the user, and the app requests access
again, the UI displays a <b>Don't ask again</b> checkbox:</p> again, the UI displays a <b>Don't ask again</b> checkbox:</p>
<img src="{@docRoot}preview/images/scoped-folder-access-dont-ask.png" <img src="{@docRoot}images/android-7.0/scoped-directory-access-dont-ask.png"
srcset="{@docRoot}preview/images/scoped-folder-access-dont-ask.png 1x, srcset="{@docRoot}images/android-7.0/scoped-directory-access-dont-ask.png 1x,
{@docRoot}preview/images/scoped-folder-access-dont-ask_2x.png 2x" /> {@docRoot}images/android-7.0/scoped-directory-access-dont-ask_2x.png 2x" />
<p class="img-caption"><strong>Figure 1.</strong> An application making a <p class="img-caption"><strong>Figure 1.</strong> An application making a
second request for access to removable media.</p> second request for access to removable media.</p>