Home | History | Annotate | Download | only in features
      1 page.title=Acesso a diretrios com escopo
      2 page.keywords=preview,sdk,scoped directory access
      3 page.tags=androidn
      4 
      5 @jd:body
      6 
      7 <div id="qv-wrapper">
      8 <div id="qv">
      9   <h2>Neste documento</h2>
     10   <ol>
     11     <li><a href="#accessing">Acessar um diretrio de armazenamento externo</a></li>
     12     <li><a href="#removable">Acessar um diretrio em uma mdia removvel</a></li>
     13     <li><a href="#best">Prticas recomendadas</a></li>
     14   </ol>
     15 </div>
     16 </div>
     17 
     18 <p>Alguns aplicativos, como aplicativos de fotos, normalmente s precisam acessar diretrios especficos de um
     19 armazenamento externo, como o diretrio <code>Pictures</code>. As abordagens
     20 existentes para o acesso de armazenamentos externos no foram desenvolvidas para fornecer com facilidade
     21 acesso direcionado a diretrios para esses tipos de aplicativos. Por exemplo:</p>
     22 
     23 <ul>
     24 <li>Solicitar {@link android.Manifest.permission#READ_EXTERNAL_STORAGE}
     25 ou {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} em seu manifesto
     26 permite o acesso a todos os diretrios pblicos no armazenamento externo, o que pode ser mais do
     27 que o aplicativo precisa.</li>
     28 <li>Usar a 
     29 <a href="{@docRoot}guide/topics/providers/document-provider.html">Estrutura de
     30 acesso ao armazenamento</a> geralmente faz com que o usurio selecione diretrios
     31 por meio de uma IU de sistema, o que  desnecessrio se seu aplicativo sempre acessa o mesmo
     32 diretrio externo.</li>
     33 </ul>
     34 
     35 <p>O Android N fornece uma nova API simplificada para acessar
     36 diretrios de armazenamento externo comuns. </p>
     37 
     38 <h2 id="accessing">Acessar um diretrio de armazenamento externo</h2>
     39 
     40 <p>Use a classe <code>StorageManager</code> para obter a instncia
     41 <code>StorageVolume</code> apropriada. Em seguida, crie uma inteno chamando o mtodo
     42 <code>StorageVolume.createAccessIntent()</code> dessa instncia.
     43 Use essa inteno para acessar os diretrios de armazenamento externo. Para obter uma lista de
     44 todos os volumes disponveis, incluindo volumes de mdias removveis, use
     45 <code>StorageManager.getVolumesList()</code>.</p>
     46 
     47 <p>Se voc tiver informaes sobre um arquivo especfico, use
     48 <code>StorageManager.getStorageVolume(File)</code> para obter o
     49 <code>StorageVolume</code> que contm o arquivo. Chame
     50 <code>createAccessIntent()</code> neste <code>StorageVolume</code> para acessar
     51 o diretrio de armazenamento externo para o arquivo.</p>
     52 
     53 <p>
     54 Em volumes secundrios, como cartes SD externos, passe nulo ao chamar
     55 <code>StorageVolume.createAccessIntent()</code> para solicitar acesso ao
     56 volume todo em vez de um diretrio especfico.
     57 <code>StorageVolume.createAccessIntent()</code> retornar nulo se voc passar 
     58 nulo no volume principal ou se passar um nome de diretrio invlido.
     59 </p>
     60 
     61 <p>O fragmento de cdigo a seguir  um exemplo de como abrir o diretrio
     62 <code>Pictures</code> no armazenamento compartilhado principal:</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>O sistema tenta conceder acesso ao diretrio externo e,
     72 se necessrio, confirma o acesso com o usurio usando uma IU simplificada:</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>Figura 1.</strong> Um aplicativo solicitando
     77 acesso ao diretrio Pictures.</p>
     78 
     79 <p>Se o usurio conceder o acesso, o sistema chamar sua substituio de
     80 <code>onActivityResult()</code> com um cdigo de resultado de
     81 <code>Activity.RESULT_OK</code> e os dados de inteno que contm o URI. Use
     82 o URI fornecido para acessar as informaes do diretrio, o que  semelhante a usar URIs
     83 retornados pela 
     84 <a href="{@docRoot}guide/topics/providers/document-provider.html">Estrutura de
     85 acesso ao armazenamento</a>.</p>
     86 
     87 <p>Se o usurio no conceder o acesso, o sistema chamar sua substituio de
     88 <code>onActivityResult()</code> com um cdigo de resultado de
     89 <code>Activity.RESULT_CANCELED</code> e dados de inteno nulos.</p>
     90 
     91 <p class="note"><b>Observao</b>: Ao obter acesso a um diretrio externo especfico,
     92 voc tambm obtm acesso aos subdiretrios dentro do diretrio em questo.</p>
     93 
     94 <h2 id="removable">Acessar um diretrio em uma mdia removvel</h2>
     95 
     96 <p>Para usar o Acesso a diretrios com escopo para acessar diretrios em uma mdia removvel,
     97 primeiro adicione um {@link android.content.BroadcastReceiver} que escute a notificao
     98 {@link android.os.Environment#MEDIA_MOUNTED}. Por exemplo:</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>Quando o usurio monta uma mdia removvel, como um carto SD, o sistema envia uma notificao
    113 {@link android.os.Environment#MEDIA_MOUNTED}. Essa notificao
    114 fornece um objeto <code>StorageVolume</code> nos dados de inteno que
    115 voc pode usar para acessar os diretrios na mdia removvel. O exemplo a seguir
    116 acessa o diretrio <code>Pictures</code> na mdia removvel:</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">Prticas recomendadas</h2>
    128 
    129 <p>Quando possvel, mantenha o URI de acesso a diretrios externos para que voc no precise
    130 solicitar acesso ao usurio vrias vezes. Quando o usurio conceder o acesso, chame
    131 <code>getContentResolver().takePersistableUriPermssion()</code> com o
    132 URI de acesso ao diretrio. O sistema manter o URI e as solicitaes de acesso
    133 subsequentes retornaro <code>RESULT_OK</code> e no mostraro a IU de confirmao para o
    134 usurio.</p>
    135 
    136 <p>Se o usurio negar acesso a um diretrio externo, no repita a
    137 solicitao imediatamente. Insistir em solicitaes de acesso repetidas vezes gera uma experincia
    138 negativa para o usurio. Se uma solicitao for negada pelo usurio e o aplicativo solicitar acesso
    139 novamente, a IU exibir uma caixa de seleo <b>No perguntar novamente</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>Figura 1.</strong> Um aplicativo que faz uma
    144 segunda solicitao para acesso  mdia removvel.</p>
    145 
    146 <p>Se o usurio selecionar <b>No perguntar novamente</b> e negar a solicitao, todas
    147 as solicitaes futuras para o diretrio provenientes do aplicativo sero automaticamente
    148 negadas e a IU de solicitao no ser apresentada ao usurio.</p>