Home | History | Annotate | Download | only in articles
      1 page.title=Scoped Directory Access
      2 page.keywords=pratinjau,sdk,scoped directory access
      3 page.tags=androidn
      4 
      5 @jd:body
      6 
      7 <div id="tb-wrapper">
      8 <div id="tb">
      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
     19 penyimpanan eksternal, seperti direktori <code>Pictures</code>. Pendekatan
     20 yang ada dalam mengakses penyimpanan eksternal tidak didesain untuk memberi kemudahan
     21 akses direktori tertarget untuk tipe aplikasi ini. Misalnya:</p>
     22 
     23 <ul>
     24 <li>Meminta {@link android.Manifest.permission#READ_EXTERNAL_STORAGE}
     25 atau {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} dalam manifes Anda
     26 akan memungkinkan akses ke semua direktori publik pada penyimpanan eksternal, yang mungkin
     27 lebih banyak akses dari yang dibutuhkan aplikasi Anda.</li>
     28 <li>Menggunakan
     29 <a href="{@docRoot}guide/topics/providers/document-provider.html">Storage
     30 Access Framework</a> biasanya membuat pengguna Anda memilih direktori
     31 melalui UI sistem, yang tidak diperlukan jika aplikasi Anda selalu mengakses
     32 direktori eksternal yang sama.</li>
     33 </ul>
     34 
     35 <p>Android N menyediakan API baru yang disederhanakan untuk mengakses
     36 direktori 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.
     43 Gunakan intent ini untuk mengakses direktori penyimpanan eksternal. Untuk mendapatkan daftar
     44 semua 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
     51 direktori penyimpanan eksternal untuk file tersebut.</p>
     52 
     53 <p>
     54 Di volume kedua, seperti kartu SD eksternal, teruskan null saat memanggil
     55 <code>StorageVolume.createAccessIntent()</code> untuk meminta akses ke seluruh
     56 volume, sebagai ganti direktori spesifik.
     57 <code>StorageVolume.createAccessIntent()</code> akan mengembalikan null jika Anda meneruskan
     58 null 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>
     65 StorageManager sm = (StorageManager)getSystemService(Context.STORAGE_SERVICE);
     66 StorageVolume volume = sm.getPrimaryVolume();
     67 Intent intent = volume.createAccessIntent(Environment.DIRECTORY_PICTURES);
     68 startActivityForResult(intent, request_code);
     69 </pre>
     70 
     71 <p>Sistem ini mencoba untuk memberikan akses ke direktori eksternal, dan jika
     72 diperlukan mengonfirmasi akses dengan pengguna menggunakan UI yang disederhanakan:</p>
     73 
     74 <img src="{@docRoot}images/android-7.0/scoped-directory-access-framed.png" srcset="{@docRoot}images/android-7.0/scoped-directory-access-framed.png 1x,
     75 {@docRoot}images/android-7.0/scoped-directory-access-framed_2x.png 2x" />
     76 <p class="img-caption"><strong>Gambar 1.</strong> Sebuah aplikasi yang meminta
     77 akses 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
     82 URI yang disediakan untuk mengakses informasi direktori, serupa dengan menggunakan URI
     83 yang dikembalikan oleh
     84 <a href="{@docRoot}guide/topics/providers/document-provider.html">Storage
     85 Access 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
     92 juga 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,
     97 pertama 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
    114 memberikan sebuah objek <code>StorageVolume</code> dalam data intent yang bisa
    115 Anda gunakan untuk mengakses direktori pada media lepas-pasang. Contoh berikut
    116 mengakses 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
    121 StorageVolume volume = (StorageVolume)
    122     mediaMountedIntent.getParcelableExtra(StorageVolume.EXTRA_STORAGE_VOLUME);
    123 volume.createAccessIntent(Environment.DIRECTORY_PICTURES);
    124 startActivityForResult(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
    130 berulang kali meminta akses ke pengguna. Setelah pengguna memberikan akses, panggil
    131 <code>getContentResolver().takePersistableUriPermssion()</code> bersama
    132 URI akses direktori. Sistem akan mempertahankan URI dan permintaan
    133 akses berikutnya akan mengembalikan <code>RESULT_OK</code> dan tidak menampilkan UI konfirmasi kepada
    134 pengguna.</p>
    135 
    136 <p>Jika pengguna menolak akses ke direktori eksternal, jangan langsung
    137 meminta akses lagi. Berulang kali meminta akses akan menghasilkan pengalaman
    138 pengguna yang buruk. Jika permintaan ditolak oleh pengguna, dan aplikasi meminta akses
    139 lagi, UI akan menampilkan kotak centang <b>Don't ask again</b>:</p>
    140 
    141 <img src="{@docRoot}images/android-7.0/scoped-directory-access-dont-ask.png" srcset="{@docRoot}images/android-7.0/scoped-directory-access-dont-ask.png 1x,
    142 {@docRoot}images/android-7.0/scoped-directory-access-dont-ask_2x.png 2x" />
    143 <p class="img-caption"><strong>Gambar 1.</strong> Sebuah aplikasi membuat
    144 permintaan kedua untuk mengakses media lepas-pasang.</p>
    145 
    146 <p>Jika pengguna memilih <b>Don't ask again</b> dan menolak permintaan,
    147 semua permintaan berikutnya untuk direktori yang diberikan dari aplikasi
    148 Anda secara otomatis akan ditolak, dan tidak ada UI permintaan yang akan ditampilkan ke pengguna.</p>