1page.title=Acesso a diretórios com escopo 2page.keywords=preview,sdk,scoped directory access 3page.tags=androidn 4 5@jd:body 6 7<div id="tb-wrapper"> 8<div id="tb"> 9 <h2>Neste documento</h2> 10 <ol> 11 <li><a href="#accessing">Acessar um diretório de armazenamento externo</a></li> 12 <li><a href="#removable">Acessar um diretório em uma mídia removível</a></li> 13 <li><a href="#best">Práticas recomendadas</a></li> 14 </ol> 15</div> 16</div> 17 18<p>Alguns aplicativos, como aplicativos de fotos, normalmente só precisam acessar diretórios específicos de um 19armazenamento externo, como o diretório <code>Pictures</code>. As abordagens 20existentes para o acesso de armazenamentos externos não foram desenvolvidas para fornecer com facilidade 21acesso direcionado a diretórios para esses tipos de aplicativos. Por exemplo:</p> 22 23<ul> 24<li>Solicitar {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} 25ou {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} em seu manifesto 26permite o acesso a todos os diretórios públicos no armazenamento externo, o que pode ser mais do 27que o aplicativo precisa.</li> 28<li>Usar a 29<a href="{@docRoot}guide/topics/providers/document-provider.html">Estrutura de 30acesso ao armazenamento</a> geralmente faz com que o usuário selecione diretórios 31por meio de uma IU de sistema, o que é desnecessário se seu aplicativo sempre acessa o mesmo 32diretório externo.</li> 33</ul> 34 35<p>O Android N fornece uma nova API simplificada para acessar 36diretórios de armazenamento externo comuns. </p> 37 38<h2 id="accessing">Acessar um diretório de armazenamento externo</h2> 39 40<p>Use a classe <code>StorageManager</code> para obter a instância 41<code>StorageVolume</code> apropriada. Em seguida, crie uma intenção chamando o método 42<code>StorageVolume.createAccessIntent()</code> dessa instância. 43Use essa intenção para acessar os diretórios de armazenamento externo. Para obter uma lista de 44todos os volumes disponíveis, incluindo volumes de mídias removíveis, use 45<code>StorageManager.getVolumesList()</code>.</p> 46 47<p>Se você tiver informações sobre um arquivo específico, use 48<code>StorageManager.getStorageVolume(File)</code> para obter o 49<code>StorageVolume</code> que contém o arquivo. Chame 50<code>createAccessIntent()</code> neste <code>StorageVolume</code> para acessar 51o diretório de armazenamento externo para o arquivo.</p> 52 53<p> 54Em volumes secundários, como cartões SD externos, passe nulo ao chamar 55<code>StorageVolume.createAccessIntent()</code> para solicitar acesso ao 56volume todo em vez de um diretório específico. 57<code>StorageVolume.createAccessIntent()</code> retornará nulo se você passar 58nulo no volume principal ou se passar um nome de diretório inválido. 59</p> 60 61<p>O fragmento de código a seguir é um exemplo de como abrir o diretório 62<code>Pictures</code> no armazenamento compartilhado principal:</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>O sistema tenta conceder acesso ao diretório externo e, 72se necessário, confirma o acesso com o usuário usando uma IU simplificada:</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>Figura 1.</strong> Um aplicativo solicitando 77acesso ao diretório Pictures.</p> 78 79<p>Se o usuário conceder o acesso, o sistema chamará sua substituição de 80<code>onActivityResult()</code> com um código de resultado de 81<code>Activity.RESULT_OK</code> e os dados de intenção que contêm o URI. Use 82o URI fornecido para acessar as informações do diretório, o que é semelhante a usar URIs 83retornados pela 84<a href="{@docRoot}guide/topics/providers/document-provider.html">Estrutura de 85acesso ao armazenamento</a>.</p> 86 87<p>Se o usuário não conceder o acesso, o sistema chamará sua substituição de 88<code>onActivityResult()</code> com um código de resultado de 89<code>Activity.RESULT_CANCELED</code> e dados de intenção nulos.</p> 90 91<p class="note"><b>Observação</b>: Ao obter acesso a um diretório externo específico, 92você também obtém acesso aos subdiretórios dentro do diretório em questão.</p> 93 94<h2 id="removable">Acessar um diretório em uma mídia removível</h2> 95 96<p>Para usar o Acesso a diretórios com escopo para acessar diretórios em uma mídia removível, 97primeiro adicione um {@link android.content.BroadcastReceiver} que escute a notificação 98{@link android.os.Environment#MEDIA_MOUNTED}. Por exemplo:</p> 99 100<pre> 101<receiver 102 android:name=".MediaMountedReceiver" 103 android:enabled="true" 104 android:exported="true" > 105 <intent-filter> 106 <action android:name="android.intent.action.MEDIA_MOUNTED" /> 107 <data android:scheme="file" /> 108 </intent-filter> 109</receiver> 110</pre> 111 112<p>Quando o usuário monta uma mídia removível, como um cartão SD, o sistema envia uma notificação 113{@link android.os.Environment#MEDIA_MOUNTED}. Essa notificação 114fornece um objeto <code>StorageVolume</code> nos dados de intenção que 115você pode usar para acessar os diretórios na mídia removível. O exemplo a seguir 116acessa o diretório <code>Pictures</code> na mídia removível:</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">Práticas recomendadas</h2> 128 129<p>Quando possível, mantenha o URI de acesso a diretórios externos para que você não precise 130solicitar acesso ao usuário várias vezes. Quando o usuário conceder o acesso, chame 131<code>getContentResolver().takePersistableUriPermssion()</code> com o 132URI de acesso ao diretório. O sistema manterá o URI e as solicitações de acesso 133subsequentes retornarão <code>RESULT_OK</code> e não mostrarão a IU de confirmação para o 134usuário.</p> 135 136<p>Se o usuário negar acesso a um diretório externo, não repita a 137solicitação imediatamente. Insistir em solicitações de acesso repetidas vezes gera uma experiência 138negativa para o usuário. Se uma solicitação for negada pelo usuário e o aplicativo solicitar acesso 139novamente, a IU exibirá uma caixa de seleção <b>Não perguntar novamente</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>Figura 1.</strong> Um aplicativo que faz uma 144segunda solicitação para acesso à mídia removível.</p> 145 146<p>Se o usuário selecionar <b>Não perguntar novamente</b> e negar a solicitação, todas 147as solicitações futuras para o diretório provenientes do aplicativo serão automaticamente 148negadas e a IU de solicitação não será apresentada ao usuário.</p>