1page.title=Scoped Directory Access
2page.keywords=pratinjau,sdk,scoped directory access
3page.tags=androidn
4
5@jd:body
6
7<div id="qv-wrapper">
8<div id="qv">
9  <h2>Dalam dokumen ini</h2>
10  <ol>
11    <li><a href="#accessing">Mengakses Direktori Penyimpanan Eksternal</a></li>
12    <li><a href="#removable">Mengakses Direktori pada Media Lepas-Pasang</a></li>
13    <li><a href="#best">Praktik Terbaik</a></li>
14  </ol>
15</div>
16</div>
17
18<p>Aplikasi seperti aplikasi foto biasanya hanya memerlukan akses ke direktori tertentu dalam
19penyimpanan eksternal, seperti direktori <code>Pictures</code>. Pendekatan
20yang ada dalam mengakses penyimpanan eksternal tidak didesain untuk memberi kemudahan
21akses direktori tertarget untuk tipe aplikasi ini. Misalnya:</p>
22
23<ul>
24<li>Meminta {@link android.Manifest.permission#READ_EXTERNAL_STORAGE}
25atau {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} dalam manifes Anda
26akan memungkinkan akses ke semua direktori publik pada penyimpanan eksternal, yang mungkin
27lebih banyak akses dari yang dibutuhkan aplikasi Anda.</li>
28<li>Menggunakan
29<a href="{@docRoot}guide/topics/providers/document-provider.html">Storage
30Access Framework</a> biasanya membuat pengguna Anda memilih direktori
31melalui UI sistem, yang tidak diperlukan jika aplikasi Anda selalu mengakses
32direktori eksternal yang sama.</li>
33</ul>
34
35<p>Android N menyediakan API baru yang disederhanakan untuk mengakses
36direktori penyimpanan eksternal umum. </p>
37
38<h2 id="accessing">Mengakses Direktori Penyimpanan Eksternal</h2>
39
40<p>Gunakan kelas <code>StorageManager</code> untuk mendapatkan instance
41<code>StorageVolume</code> yang tepat. Kemudian, buat intent dengan memanggil metode
42<code>StorageVolume.createAccessIntent()</code> dari instance itu.
43Gunakan intent ini untuk mengakses direktori penyimpanan eksternal. Untuk mendapatkan daftar
44semua volume yang tersedia, termasuk volume media lepas-pasang, gunakan
45<code>StorageManager.getVolumesList()</code>.</p>
46
47<p>Jika Anda memiliki informasi tentang file spesifik, gunakan
48<code>StorageManager.getStorageVolume(File)</code> untuk mendapatkan
49<code>StorageVolume</code> yang berisi file tersebut. Panggil
50<code>createAccessIntent()</code> pada <code>StorageVolume</code> ini untuk mengakses
51direktori penyimpanan eksternal untuk file tersebut.</p>
52
53<p>
54Di volume kedua, seperti kartu SD eksternal, teruskan null saat memanggil
55<code>StorageVolume.createAccessIntent()</code> untuk meminta akses ke seluruh
56volume, sebagai ganti direktori spesifik.
57<code>StorageVolume.createAccessIntent()</code> akan mengembalikan null jika Anda meneruskan
58null ke volume utama, atau jika Anda meneruskan nama direktori yang tidak valid.
59</p>
60
61<p>Cuplikan kode berikut adalah contoh cara membuka direktori
62<code>Pictures</code> dalam penyimpanan bersama utama:</p>
63
64<pre>
65StorageManager sm = (StorageManager)getSystemService(Context.STORAGE_SERVICE);
66StorageVolume volume = sm.getPrimaryVolume();
67Intent intent = volume.createAccessIntent(Environment.DIRECTORY_PICTURES);
68startActivityForResult(intent, request_code);
69</pre>
70
71<p>Sistem ini mencoba untuk memberikan akses ke direktori eksternal, dan jika
72diperlukan mengonfirmasi akses dengan pengguna menggunakan UI yang disederhanakan:</p>
73
74<img src="{@docRoot}preview/images/scoped-folder-access-framed.png" srcset="{@docRoot}preview/images/scoped-folder-access-framed.png 1x,
75{@docRoot}preview/images/scoped-folder-access-framed_2x.png 2x" />
76<p class="img-caption"><strong>Gambar 1.</strong> Sebuah aplikasi yang meminta
77akses ke direktori Pictures.</p>
78
79<p>Jika pengguna memberi akses, sistem akan memanggil penggantian
80<code>onActivityResult()</code> Anda dengan kode hasil
81<code>Activity.RESULT_OK</code>, dan data intent yang berisi URI. Gunakan
82URI yang disediakan untuk mengakses informasi direktori, serupa dengan menggunakan URI
83yang dikembalikan oleh
84<a href="{@docRoot}guide/topics/providers/document-provider.html">Storage
85Access Framework</a>.</p>
86
87<p>Jika pengguna tidak memberi akses, sistem akan memanggil penggantian
88<code>onActivityResult()</code> Anda dengan kode hasil
89<code>Activity.RESULT_CANCELED</code>, dan data intent nol.</p>
90
91<p class="note"><b>Catatan</b>: Mendapatkan akses ke direktori eksternal tertentu
92juga akan memperoleh akses ke subdirektori dalam direktori tersebut.</p>
93
94<h2 id="removable">Mengakses Direktori pada Media Lepas-Pasang</h2>
95
96<p>Untuk menggunakan Scoped Directory Access guna mengakses direktori pada media lepas-pasang,
97pertama tambahkan {@link android.content.BroadcastReceiver} yang akan mendengarkan pemberitahuan
98{@link android.os.Environment#MEDIA_MOUNTED}, misalnya:</p>
99
100<pre>
101&lt;receiver
102    android:name=".MediaMountedReceiver"
103    android:enabled="true"
104    android:exported="true" &gt;
105    &lt;intent-filter&gt;
106        &lt;action android:name="android.intent.action.MEDIA_MOUNTED" /&gt;
107        &lt;data android:scheme="file" /&gt;
108    &lt;/intent-filter&gt;
109&lt;/receiver&gt;
110</pre>
111
112<p>Bila pengguna memasang media lepas-pasang, seperti kartu SD, sistem akan mengirimkan pemberitahuan
113{@link android.os.Environment#MEDIA_MOUNTED}. Pemberitahuan ini
114memberikan sebuah objek <code>StorageVolume</code> dalam data intent yang bisa
115Anda gunakan untuk mengakses direktori pada media lepas-pasang. Contoh berikut
116mengakses direktori <code>Pictures</code> pada media lepas-pasang:</p>
117
118<pre>
119// BroadcastReceiver has already cached the MEDIA_MOUNTED
120// notification Intent in mediaMountedIntent
121StorageVolume volume = (StorageVolume)
122    mediaMountedIntent.getParcelableExtra(StorageVolume.EXTRA_STORAGE_VOLUME);
123volume.createAccessIntent(Environment.DIRECTORY_PICTURES);
124startActivityForResult(intent, request_code);
125</pre>
126
127<h2 id="best">Praktik Terbaik</h2>
128
129<p>Bila memungkinkan, pertahankan URI akses direktori eksternal sehingga Anda tidak perlu
130berulang kali meminta akses ke pengguna. Setelah pengguna memberikan akses, panggil
131<code>getContentResolver().takePersistableUriPermssion()</code> bersama
132URI akses direktori. Sistem akan mempertahankan URI dan permintaan
133akses berikutnya akan mengembalikan <code>RESULT_OK</code> dan tidak menampilkan UI konfirmasi kepada
134pengguna.</p>
135
136<p>Jika pengguna menolak akses ke direktori eksternal, jangan langsung
137meminta akses lagi. Berulang kali meminta akses akan menghasilkan pengalaman
138pengguna yang buruk. Jika permintaan ditolak oleh pengguna, dan aplikasi meminta akses
139lagi, UI akan menampilkan kotak centang <b>Don't ask again</b>:</p>
140
141<img src="{@docRoot}preview/images/scoped-folder-access-dont-ask.png" srcset="{@docRoot}preview/images/scoped-folder-access-dont-ask.png 1x,
142{@docRoot}preview/images/scoped-folder-access-dont-ask_2x.png 2x" />
143<p class="img-caption"><strong>Gambar 1.</strong> Sebuah aplikasi membuat
144permintaan kedua untuk mengakses media lepas-pasang.</p>
145
146<p>Jika pengguna memilih <b>Don't ask again</b> dan menolak permintaan,
147semua permintaan berikutnya untuk direktori yang diberikan dari aplikasi
148Anda secara otomatis akan ditolak, dan tidak ada UI permintaan yang akan ditampilkan ke pengguna.</p>