Molte buone domande, approfondiamo. :)
Come lo usi?
Ecco un ottimo tutorial per interagire con Storage Access Framework in KitKat:
https://developer.android.com/guide/topics/providers/document-provider.html#client
L'interazione con le nuove API in Lollipop è molto simile. Per richiedere all'utente di scegliere un albero di directory, puoi avviare un intento come questo:
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
startActivityForResult(intent, 42);
Quindi nel tuo onActivityResult (), puoi passare l'Uri selezionato dall'utente alla nuova classe helper DocumentFile. Ecco un rapido esempio che elenca i file nella directory selezionata e quindi crea un nuovo file:
public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
if (resultCode == RESULT_OK) {
Uri treeUri = resultData.getData();
DocumentFile pickedDir = DocumentFile.fromTreeUri(this, treeUri);
// List all existing files inside picked directory
for (DocumentFile file : pickedDir.listFiles()) {
Log.d(TAG, "Found file " + file.getName() + " with size " + file.length());
}
// Create a new file and write into it
DocumentFile newFile = pickedDir.createFile("text/plain", "My Novel");
OutputStream out = getContentResolver().openOutputStream(newFile.getUri());
out.write("A long time ago...".getBytes());
out.close();
}
}
L'URI restituito da DocumentFile.getUri()
è abbastanza flessibile da poter essere utilizzato con diverse API della piattaforma. Ad esempio, potresti condividerlo usando Intent.setData()
con Intent.FLAG_GRANT_READ_URI_PERMISSION
.
Se si desidera accedere a quell'URI dal codice nativo, è possibile chiamare ContentResolver.openFileDescriptor()
e quindi utilizzare ParcelFileDescriptor.getFd()
o detachFd()
per ottenere un intero descrittore di file POSIX tradizionale.
Come controlli se puoi accedere ai file / cartelle?
Per impostazione predefinita, gli intenti Uris restituiti tramite Storage Access Frameworks non vengono mantenuti durante i riavvii. La piattaforma "offre" la possibilità di mantenere il permesso, ma è comunque necessario "prendere" il permesso se lo si desidera. Nel nostro esempio sopra, chiameresti:
getContentResolver().takePersistableUriPermission(treeUri,
Intent.FLAG_GRANT_READ_URI_PERMISSION |
Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
Puoi sempre capire a cosa concede l'accesso alla tua app tramite l' ContentResolver.getPersistedUriPermissions()
API. Se non è più necessario accedere a un Uri persistente, è possibile rilasciarlo con ContentResolver.releasePersistableUriPermission()
.
È disponibile su KitKat?
No, non possiamo aggiungere retroattivamente nuove funzionalità alle versioni precedenti della piattaforma.
Posso vedere quali app hanno accesso a file / cartelle?
Al momento non esiste un'interfaccia utente che lo mostri, ma puoi trovare i dettagli nella sezione "Autorizzazioni Uri concesse" adb shell dumpsys activity providers
dell'output.
Cosa succede se un'app viene installata per più utenti sullo stesso dispositivo?
Le concessioni di autorizzazione di Uri sono isolate per utente, proprio come tutte le altre funzionalità della piattaforma multiutente. Ovvero, la stessa app in esecuzione con due utenti diversi non ha concessioni di autorizzazioni Uri sovrapposte o condivise.
Le autorizzazioni possono essere revocate?
Il DocumentProvider di supporto può revocare l'autorizzazione in qualsiasi momento, ad esempio quando viene eliminato un documento basato su cloud. Il modo più comune per scoprire queste autorizzazioni revocate è quando scompaiono da quelle ContentResolver.getPersistedUriPermissions()
sopra menzionate.
Le autorizzazioni vengono revocate anche ogni volta che i dati dell'app vengono cancellati per entrambe le app coinvolte nella concessione.
Chiedere l'autorizzazione funzionerebbe in modo ricorsivo su una cartella selezionata?
Sì, l' ACTION_OPEN_DOCUMENT_TREE
intento ti dà accesso ricorsivo a file e directory esistenti e appena creati.
Ciò consente la selezione multipla?
Sì, la selezione multipla è stata supportata da KitKat e puoi consentirla impostando EXTRA_ALLOW_MULTIPLE
quando inizi il tuo ACTION_OPEN_DOCUMENT
intento. Puoi usare Intent.setType()
o EXTRA_MIME_TYPES
per restringere i tipi di file che possono essere selezionati:
http://developer.android.com/reference/android/content/Intent.html#ACTION_OPEN_DOCUMENT
C'è un modo sull'emulatore per provare la nuova API?
Sì, il dispositivo di archiviazione condiviso principale dovrebbe apparire nel selettore, anche sull'emulatore. Se l'applicazione utilizza solo l'accesso quadro di archiviazione per l'accesso storage condiviso, non è più necessario i READ/WRITE_EXTERNAL_STORAGE
permessi a tutti e possibile rimuoverli o utilizzare la android:maxSdkVersion
funzione per solo a loro richiesta sulle versioni più vecchie di piattaforma.
Cosa succede quando l'utente sostituisce la scheda SD con un'altra?
Quando è coinvolto un supporto fisico, l'UUID (come il numero di serie FAT) del supporto sottostante viene sempre masterizzato nell'URI restituito. Il sistema lo utilizza per connettersi al supporto selezionato originariamente dall'utente, anche se l'utente scambia il supporto tra più slot.
Se l'utente sostituisce una seconda carta, dovrai chiedere di ottenere l'accesso alla nuova carta. Poiché il sistema ricorda le concessioni per UUID, continuerai ad avere l'accesso concesso in precedenza alla carta originale se l'utente la reinserisce in un secondo momento.
http://en.wikipedia.org/wiki/Volume_serial_number