blob: 51a4c4d55f79110bec45f1952d76c6cab7932afd [file] [log] [blame]
David Friedman8f1f66f2016-04-13 18:11:00 -07001page.title=Доступ к выделенным каталогам
2page.keywords=preview,sdk,scoped directory access
3page.tags=androidn
4
5@jd:body
6
7<div id="qv-wrapper">
8<div id="qv">
9 <h2>Содержание документа</h2>
10 <ol>
11 <li><a href="#accessing">Доступ к каталогу во внешнем хранилище</a></li>
12 <li><a href="#removable">Доступ к каталогу на съемном носителе</a></li>
13 <li><a href="#best">Советы и рекомендации</a></li>
14 </ol>
15</div>
16</div>
17
18<p>Некоторым приложениям (например, фотоприложениям) обычно требуется доступ только к отдельным каталогам
19внешнего хранилища, например, к каталогу <code>Pictures</code>. Существующие
20методы доступа к внешним хранилищам не предназначены для обеспечения приложениям такого типа удобного
21доступа к выделенным каталогам. Например:</p>
22
23<ul>
24<li>Запросы {@link android.Manifest.permission#READ_EXTERNAL_STORAGE}
25или {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} в манифесте
26разрешают доступ ко всем общедоступным каталогам внешнего хранилища, хотя
27вашему приложению может не требоваться такой уровень доступа.</li>
28<li>При использовании инфраструктуры
29<a href="{@docRoot}guide/topics/providers/document-provider.html">Storage
30Access Framework</a> пользователь обычно выбирает каталоги через
31системный пользовательский интерфейс, что не требуется, если приложение всегда использует один
32и тот же внешний каталог.</li>
33</ul>
34
35<p>Android N предоставляет новый упрощенный API для доступа
36к распространенным каталогам внешнего хранилища. </p>
37
38<h2 id="accessing">Доступ к каталогу во внешнем хранилище</h2>
39
40<p>Используйте класс <code>StorageManager</code> для получения соответствующего экземпляра
41<code>StorageVolume</code>. Затем создайте намерение, вызвав метод
42<code>StorageVolume.createAccessIntent()</code> этого экземпляра.
43Используйте это намерение для доступа к каталогам внешнего хранилища. Чтобы получить список
44всех доступных томов, в том числе томов на съемных носителях, используйте
45<code>StorageManager.getVolumesList()</code>.</p>
46
47<p>В следующем фрагменте кода приведен пример того, как открывать каталог
48<code>Pictures</code> в главном общем хранилище:</p>
49
50<pre>
51StorageManager sm = (StorageManager)getSystemService(Context.STORAGE_SERVICE);
52StorageVolume volume = sm.getPrimaryVolume();
53Intent intent = volume.createAccessIntent(Environment.DIRECTORY_PICTURES);
54startActivityForResult(intent, request_code);
55</pre>
56
57<p>Система пытается предоставить доступ к внешнему каталогу и, при необходимости,
58запрашивает подтверждение доступа у пользователя с помощью упрощенного пользовательского интерфейса:</p>
59
60<img src="{@docRoot}preview/images/scoped-folder-access-framed.png" srcset="{@docRoot}preview/images/scoped-folder-access-framed.png 1x,
61{@docRoot}preview/images/scoped-folder-access-framed_2x.png 2x" />
62<p class="img-caption"><strong>Рисунок 1.</strong> Приложение запрашивает
63доступ к каталогу Pictures.</p>
64
65<p>Если пользователь предоставляет доступ, система вызывает переопределенный метод
66<code>onActivityResult()</code> с кодом результата
67<code>Activity.RESULT_OK</code>, а также данные намерения, содержащие URI. Используйте
68предоставленный URI для доступа к данным каталога аналогично использованию URI,
69возвращаемых
70<a href="{@docRoot}guide/topics/providers/document-provider.html">Storage
71Access Framework</a>.</p>
72
73<p>Если пользователь не предоставляет доступ, система вызывает переопределенный метод
74<code>onActivityResult()</code> с кодом результата
75<code>Activity.RESULT_CANCELED</code> и отсутствующими данными намерения.</p>
76
77<p class="note"><b>Примечание.</b> При получении доступа к определенному внешнему каталогу
78приложение также получает доступ к вложенным в него каталогам.</p>
79
80<h2 id="removable">Доступ к каталогу на съемном носителе</h2>
81
82<p>Чтобы использовать доступ к выделенным каталогам на съемном носителе,
83сначала нужно добавить объект {@link android.content.BroadcastReceiver}, отслеживающий уведомления
84{@link android.os.Environment#MEDIA_MOUNTED}, например:</p>
85
86<pre>
87&lt;receiver
88 android:name=".MediaMountedReceiver"
89 android:enabled="true"
90 android:exported="true" &gt;
91 &lt;intent-filter&gt;
92 &lt;action android:name="android.intent.action.MEDIA_MOUNTED" /&gt;
93 &lt;data android:scheme="file" /&gt;
94 &lt;/intent-filter&gt;
95&lt;/receiver&gt;
96</pre>
97
98<p>Когда пользователь подключает съемный носитель, например SD-карту, система отправляет уведомление
99{@link android.os.Environment#MEDIA_MOUNTED}. Это уведомление
100предоставляет в данных намерения объект <code>StorageVolume</code>, который вы можете использовать
101для доступа к каталогам на съемном носителе. В следующем примере показано,
102как осуществляется доступ к каталогу <code>Pictures</code> на съемном носителе:</p>
103
104<pre>
105// BroadcastReceiver has already cached the MEDIA_MOUNTED
106// notification Intent in mediaMountedIntent
107StorageVolume volume = (StorageVolume)
108 mediaMountedIntent.getParcelableExtra(StorageVolume.EXTRA_STORAGE_VOLUME);
109volume.createAccessIntent(Environment.DIRECTORY_PICTURES);
110startActivityForResult(intent, request_code);
111</pre>
112
113<h2 id="best">Советы и рекомендации</h2>
114
115<p>По возможности оставляйте постоянный URI для доступа к внешнему каталогу, чтобы приложению не
Mark Luc4a01392016-07-18 10:42:11 -0700116приходилось многократно запрашивать у пользователя разрешение на доступ. После предоставления доступа пользователем вызовите метод
David Friedman8f1f66f2016-04-13 18:11:00 -0700117<code>getContentResolver().takePersistableUriPermssion()</code> для
118URI доступа к каталогу. Система сохранит постоянный URI и при последующих запросах
119доступа будет возвращать ответ <code>RESULT_OK</code>. Таким образом, приложение не будет постоянно выводить
120окно с запросом подтверждения пользователя.</p>
121
122<p>Если пользователь запрещает доступ к внешнему каталогу, не нужно сразу
123же запрашивать доступ повторно. Пользователю может не понравиться, если приложение будет постоянно настаивать на
124получении доступа.</p>