2015-08-24 12 views
12

Ich habe gerade mit Android M gestartet und ich kann nicht auf den externen Speicher zugreifen. Ich erhalte die folgenden FehlerAndroid M User Permission Error - Lesen und Schreiben

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() 

I Benutzer-Erlaubnis in manifest ist Hinzufügen wie

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

und meine Build-Datei mit folgenden Einstellungen ist:

compileSdkVersion 23 
buildToolsVersion "22.0.1" 

minSdkVersion 16 
targetSdkVersion 23 

Wie Lese und Schreiben von externer Speicher in android M?

+1

Wow Sie eine Frage gestellt und es sofort beantwortet sich innerhalb miliseconds. Du bist ein wahres Genie. –

+3

Hi @SharpEdge Ich denke, es ist eine gute Praxis, dies zu tun. http://StackOverflow.com/Help/self-answer Ich verbrachte eine Stunde damit, die Lösung zu finden und hoffe, dass es in Zukunft jemand anderen Zeit spart. :) –

+0

Ich wusste nicht, dass .. diese Aussage existiert ** "Wenn Sie eine Frage haben, wissen Sie bereits die Antwort, und Sie möchten dieses Wissen in der Öffentlichkeit dokumentieren, so dass andere (einschließlich Sie selbst) es finden können später "** Tut mir leid, dass ich sarkastisch bin. –

Antwort

20

Lesen von der documentation. Ich muss den Benutzer zur Laufzeit um Erlaubnis fragen. Code-Beispiel:

hinzufügen Erlaubnis Manifest für Android wie wir früher zu tun pflegte:

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

Überprüfen Sie, ob der Benutzer bereits die Erlaubnis erteilt hat. Wenn ja, fahren Sie um Erlaubnis zu fragen und fahren Sie mit Ihrer Arbeit fließen sonst Benutzer um Erlaubnis bitten:

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 
} 

nun zu prüfen, ob der Benutzer die Berechtigung erteilt oder verweigert es @OverrideOnRequestPermissionResult einen Rückruf zu erhalten:

@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; 
     } 
    } 
} 

Ich war nicht in der Lage, externen Speicher nur lesen, indem Sie WRITE Erlaubnis, so musste ich für Manifest.permission.READ_EXTERNAL_STORAGE auch anfordern.


Auch wenn Sie Versionen unter api 23 ausrichten möchten, prüfen Sie die Build- VERSION zur Laufzeit mit IF Anweisung und nur für Berechtigungen fragen, ob VERSION gleich oder höher Android M ist.

+0

es ist nur gültig min API Level 23 richtig? –

+0

Hi @ajit du bist richtig, es gilt nur für min API 23! Allerdings mit einer einfachen Version Überprüfung durch 'if' Anweisung zur Laufzeit .. Sie können auch vorherige Version unterstützen .. Ich werde die Ans mit Pre-M-Unterstützung bearbeiten, sobald ich wieder auf meinem Computer .. –

+0

Heute poste ich eine Frage aber wundern Sie sich für die Suche nach der richtigen Lösung können Sie mir helfen –

6

Falls Sie nach einem Weg suchen, um in jeder Android-Version (Sie kompilieren für M, aber einige Geräte können auch andere Versionen verwenden) zu behandeln gibt es eine Kompatibilitätsversion.

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

Ich war mit WRITE_EXTERNAL_STORAGE Erlaubnis zu kämpfen: nachdem ich es angefordert wird, hat der Dialog angezeigt nicht und kehrte sofort DENIED.

Das Problem war in einer der enthaltenen Bibliotheken. Es enthielt die gleiche Erlaubnisserklärung in seiner AndroidManifest.xml, aber mit maxSdkVersion="22". Die Deklaration in der Manifestdatei der Anwendung wurde von der Bibliothek überschrieben.

Um Erlaubnis aus der Bibliothek überschreiben ich folgendes verwendet:

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

Ich hoffe, dass dies hilfreich sein könnte.

2

In Bezug auf die gewählte Antwort:

Settings.System.canWrite(this) und WRITE_EXTERNAL_STORAGE sind zwei sehr verschiedene Dinge! Sollte sein:

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

Ich habe dieses Dienstprogramm auf Github verwendet. Es funktioniert mit beiden API 22 und 23. Das Hinzufügen von Laufzeitberechtigungen ist nicht schwer, aber den Code zu trennen und die Methoden zu verschieben, um Rückrufe zu erfassen, ist ein wenig schmerzhaft. Diese Bibliothek stellt eine verkettete API bereit, um alles zu tun, was zur Unterstützung von Laufzeitberechtigungen erforderlich ist.

https://github.com/kayvannj/PermissionUtil