2015-08-24 19 views
12

Ho appena iniziato con Android M e non riesco ad accedere alla memoria esterna. Ottengo il seguente erroreErrore autorizzazione utente Android M - LETTURA e SCRIVIA

Caused by: java.lang.SecurityException: Permission Denial: reading 
com.android.providers.media.MediaProvider uri 
content://media/external/images/media from pid=15355, uid=10053 requires 
android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission() 

Io sono l'aggiunta dall'utente l'autorizzazione a manifestare come

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 

e il mio file di configurazione è con le seguenti impostazioni:

compileSdkVersion 23 
buildToolsVersion "22.0.1" 

minSdkVersion 16 
targetSdkVersion 23 

Come leggere e scrivere da archiviazione esterna in Android M?

+1

Wow fatto una domanda e subito risposto da soli all'interno di millisecondi. Sei un vero genio. –

+3

Ciao @SharpEdge penso sia una buona pratica farlo. http://stackoverflow.com/help/self-answer Ho trascorso un'ora a trovare la soluzione e spero che in futuro risparmi un'altra volta. :) –

+0

Non lo sapevo .. questa affermazione esisteva ** "Se hai una domanda a cui già conosci la risposta, e vorresti documentarla in pubblico in modo che altri (incluso te stesso) possano trovarla più tardi "** Scusa per essere sarcastico. –

risposta

20

Lettura da documentation. Devo chiedere all'utente il permesso al runtime. Esempio di codice:

Aggiungi il permesso di android manifesta come siamo abituati a fare in precedenza:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 

Verificare se l'utente ha già concesso il permesso. Se sì, saltare chiedere il permesso e continuare con il vostro lavoro di flusso altro chiedere all'utente il permesso:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 
    if (!Settings.System.canWrite(this)) { 
     requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, 
      Manifest.permission.READ_EXTERNAL_STORAGE}, 2909); 
    } else { 
     // continue with your code 
    } 
} else { 
    // continue with your code 
} 

ora per verificare se l'utente ha concesso il permesso o negato @OverrideOnRequestPermissionResult per ottenere un callback:

@Override 
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { 
    switch (requestCode) { 
     case 2909: { 
      if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { 
       Log.e("Permission", "Granted"); 
      } else { 
       Log.e("Permission", "Denied"); 
      } 
      return; 
     } 
    } 
} 

Non è stato possibile leggere la memoria esterna solo richiedendo l'autorizzazione WRITE , quindi ho dovuto richiedere Manifest.permission.READ_EXTERNAL_STORAGE.


Inoltre, se si desidera raggiungere le versioni inferiori api 23, controllare Build VERSIONE in fase di esecuzione con IF dichiarazione e chiedere permessi solo se versione è uguale o superiore Android M.

+0

è valido solo il livello API minimo 23 giusto? –

+0

Ciao @ Ajit sei corretto, è valido solo con l'API minima 23! Comunque con una semplice versione controlla con l'istruzione 'if' in fase di runtime ... Puoi anche supportare la versione precedente .. Modificherò gli ans con il supporto pre M non appena torno sul mio computer .. –

+0

Oggi inserisco una domanda ma chiedendo di trovare una soluzione adeguata puoi aiutarmi a –

6

Nel caso si stia cercando un modo per gestire qualsiasi versione di Android (si sta compilando per M, ma alcuni dispositivi possono utilizzare altre versioni), esiste una versione di compatibilità.

if (ContextCompat.checkSelfPermission(CreatePlayerActivity.this, 
      Manifest.permission.READ_EXTERNAL_STORAGE) 
      != PackageManager.PERMISSION_GRANTED) { 

     // Should we show an explanation? 
     if (ActivityCompat.shouldShowRequestPermissionRationale(CreatePlayerActivity.this, 
       Manifest.permission.READ_EXTERNAL_STORAGE)) { 

      // Show an expanation to the user *asynchronously* -- don't block 
      // this thread waiting for the user's response! After the user 
      // sees the explanation, try again to request the permission. 

     } else { 

      // No explanation needed, we can request the permission. 

      ActivityCompat.requestPermissions(CreatePlayerActivity.this, 
        new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 
        MY_PERMISSIONS_REQUEST_READ_CONTACTS); 

      // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an 
      // app-defined int constant. The callback method gets the 
      // result of the request. 
     } 
    } 
1

ero alle prese con il permesso WRITE_EXTERNAL_STORAGE: dopo ho chiesto che, la finestra di dialogo non si è presentato e subito restituito DENIED.

Il problema era in una delle librerie incluse. Conteneva la stessa dichiarazione di autorizzazione nel suo AndroidManifest.xml, ma con maxSdkVersion="22". La dichiarazione nel file manifest dell'applicazione è stata sostituita dalla libreria.

Per ignorare il permesso dalla biblioteca ho usato il seguente:

<uses-permission 
    android:name="android.permission.WRITE_EXTERNAL_STORAGE" 
    tools:node="remove" 
    tools:selector="com.example.lib" /> 

Spero che questo potrebbe essere utile.

2

Per quanto riguarda la risposta selezionata:

Settings.System.canWrite(this) e WRITE_EXTERNAL_STORAGE sono due cose molto diverse! Dovrebbe essere:

boolean needsRead = ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) 
      != PackageManager.PERMISSION_GRANTED; 

    boolean needsWrite = ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) 
      != PackageManager.PERMISSION_GRANTED; 

    if (needsRead || needsWrite) 
     requestStoragePermission() 
-1

Ho usato questa utilità su github. Funziona con entrambe le API 22 e 23. Aggiungere autorizzazioni di runtime non è difficile ma dover separare il codice e spostare i metodi per catturare i callback è un po 'difficile. Questa libreria fornisce una API concatenata per fare tutto ciò che è necessario fare per supportare le autorizzazioni di runtime.

https://github.com/kayvannj/PermissionUtil