page.title=Acesso a diretórios com escopo page.keywords=preview,sdk,scoped directory access page.tags=androidn @jd:body
Alguns aplicativos, como aplicativos de fotos, normalmente só precisam acessar diretórios específicos de um
armazenamento externo, como o diretório Pictures
. As abordagens
existentes para o acesso de armazenamentos externos não foram desenvolvidas para fornecer com facilidade
acesso direcionado a diretórios para esses tipos de aplicativos. Por exemplo:
O Android N fornece uma nova API simplificada para acessar diretórios de armazenamento externo comuns.
Use a classe StorageManager
para obter a instância
StorageVolume
apropriada. Em seguida, crie uma intenção chamando o método
StorageVolume.createAccessIntent()
dessa instância.
Use essa intenção para acessar os diretórios de armazenamento externo. Para obter uma lista de
todos os volumes disponíveis, incluindo volumes de mídias removíveis, use
StorageManager.getVolumesList()
.
Se você tiver informações sobre um arquivo específico, use
StorageManager.getStorageVolume(File)
para obter o
StorageVolume
que contém o arquivo. Chame
createAccessIntent()
neste StorageVolume
para acessar
o diretório de armazenamento externo para o arquivo.
Em volumes secundários, como cartões SD externos, passe nulo ao chamar
StorageVolume.createAccessIntent()
para solicitar acesso ao
volume todo em vez de um diretório específico.
StorageVolume.createAccessIntent()
retornará nulo se você passar
nulo no volume principal ou se passar um nome de diretório inválido.
O fragmento de código a seguir é um exemplo de como abrir o diretório
Pictures
no armazenamento compartilhado principal:
StorageManager sm = (StorageManager)getSystemService(Context.STORAGE_SERVICE); StorageVolume volume = sm.getPrimaryVolume(); Intent intent = volume.createAccessIntent(Environment.DIRECTORY_PICTURES); startActivityForResult(intent, request_code);
O sistema tenta conceder acesso ao diretório externo e, se necessário, confirma o acesso com o usuário usando uma IU simplificada:
Figura 1. Um aplicativo solicitando acesso ao diretório Pictures.
Se o usuário conceder o acesso, o sistema chamará sua substituição de
onActivityResult()
com um código de resultado de
Activity.RESULT_OK
e os dados de intenção que contêm o URI. Use
o URI fornecido para acessar as informações do diretório, o que é semelhante a usar URIs
retornados pela
Estrutura de
acesso ao armazenamento.
Se o usuário não conceder o acesso, o sistema chamará sua substituição de
onActivityResult()
com um código de resultado de
Activity.RESULT_CANCELED
e dados de intenção nulos.
Observação: Ao obter acesso a um diretório externo específico, você também obtém acesso aos subdiretórios dentro do diretório em questão.
Para usar o Acesso a diretórios com escopo para acessar diretórios em uma mídia removível, primeiro adicione um {@link android.content.BroadcastReceiver} que escute a notificação {@link android.os.Environment#MEDIA_MOUNTED}. Por exemplo:
<receiver android:name=".MediaMountedReceiver" android:enabled="true" android:exported="true" > <intent-filter> <action android:name="android.intent.action.MEDIA_MOUNTED" /> <data android:scheme="file" /> </intent-filter> </receiver>
Quando o usuário monta uma mídia removível, como um cartão SD, o sistema envia uma notificação
{@link android.os.Environment#MEDIA_MOUNTED}. Essa notificação
fornece um objeto StorageVolume
nos dados de intenção que
você pode usar para acessar os diretórios na mídia removível. O exemplo a seguir
acessa o diretório Pictures
na mídia removível:
// BroadcastReceiver has already cached the MEDIA_MOUNTED // notification Intent in mediaMountedIntent StorageVolume volume = (StorageVolume) mediaMountedIntent.getParcelableExtra(StorageVolume.EXTRA_STORAGE_VOLUME); volume.createAccessIntent(Environment.DIRECTORY_PICTURES); startActivityForResult(intent, request_code);
Quando possível, mantenha o URI de acesso a diretórios externos para que você não precise
solicitar acesso ao usuário várias vezes. Quando o usuário conceder o acesso, chame
getContentResolver().takePersistableUriPermssion()
com o
URI de acesso ao diretório. O sistema manterá o URI e as solicitações de acesso
subsequentes retornarão RESULT_OK
e não mostrarão a IU de confirmação para o
usuário.
Se o usuário negar acesso a um diretório externo, não repita a solicitação imediatamente. Insistir em solicitações de acesso repetidas vezes gera uma experiência negativa para o usuário. Se uma solicitação for negada pelo usuário e o aplicativo solicitar acesso novamente, a IU exibirá uma caixa de seleção Não perguntar novamente.
Figura 1. Um aplicativo que faz uma segunda solicitação para acesso à mídia removível.
Se o usuário selecionar Não perguntar novamente e negar a solicitação, todas as solicitações futuras para o diretório provenientes do aplicativo serão automaticamente negadas e a IU de solicitação não será apresentada ao usuário.