web-dev-qa-db-fra.com

Autorisation READ_EXTERNAL_STORAGE pour Android

J'essaie d'accéder aux fichiers multimédia (musique) sur le périphérique de l'utilisateur pour les lire; une application de lecteur de musique "bonjour monde" facile.

J'ai suivi des tutoriels et ils donnent essentiellement le même code. Mais ça ne marchera pas. il n'arrête pas de s'écraser et me dit:

error.....
Caused by: Java.lang.SecurityException: Permission Denial: reading com.Android.providers.media.MediaProvider uri content://media/external/audio/media from pid=27696, uid=10059 requires Android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission()
....

Maintenant, voici mon fichier manifeste:

<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    package="slimsimapps.troff" >

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


<application
    Android:allowBackup="true"
    Android:icon="@mipmap/ic_launcher"
    Android:label="@string/app_name"
    Android:theme="@style/AppTheme" >
    <activity
        Android:name=".MainActivity"
        Android:label="@string/app_name" >
        <intent-filter>
            <action Android:name="Android.intent.action.MAIN" />

            <category Android:name="Android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>
</manifest>

Ceci est ma méthode Java:

public void initialize() {
    ContentResolver contentResolver = getContentResolver();
    Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
    Cursor cursor = contentResolver.query(uri, null, null, null, null);
    if (cursor == null) {
        // query failed, handle error.
    } else if (!cursor.moveToFirst()) {
        // no media on the device
    } else {
        do {
            addSongToXML(cursor);
        } while (cursor.moveToNext());
    }
}

J'ai essayé:

Pour placer ceci à différents endroits dans le fichier manifeste:

<uses-permission Android:name="Android.permission.READ_EXTERNAL_STORAGE”/>

Pour ajouter Android: maxSdkVersion au niveau de la lecture du stockage externe:

<uses-permission
    Android:name="Android.permission.READ_EXTERNAL_STORAGE"
    Android:maxSdkVersion="21" />

Pour mettre cela dans le manifeste/application/activity-tag:

Android:exported=“true”

Pour placer grantUriPremission entre uri et cursro dans la méthode javam:

grantUriPermission(null, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);

Pour l'utiliser, cela ne plantera pas, mais le curseur deviendra nul:

uri = MediaStore.Audio.Media.getContentUri("EXTERNAL_CONTENT_URI”);

Pour utiliser le contenu INTERNAL uri, cela fonctionne comme prévu, mais il ne donne que les "sons du système d'exploitation" tels que le son de l'obturateur, le son de batterie faible, le clic du bouton, etc.:

uri = MediaStore.Audio.Media.INTERNAL_CONTENT_URI;

Pour aider, cela ne devrait pas être un problème difficile, je le sais, mais je me sens comme un débutant!

j'ai lu et essayé (ou considéré comme non applicable pour mon problème):

Trace de pile:

09-08 06:59:36.619    2009-2009/slimsimapps.troff D/AndroidRuntime﹕ Shutting down VM
    --------- beginning of crash
09-08 06:59:36.619    2009-2009/slimsimapps.troff E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: slimsimapps.troff, PID: 2009
    Java.lang.IllegalStateException: Could not execute method for Android:onClick
            at Android.view.View$DeclaredOnClickListener.onClick(View.Java:4452)
            at Android.view.View.performClick(View.Java:5198)
            at Android.view.View$PerformClick.run(View.Java:21147)
            at Android.os.Handler.handleCallback(Handler.Java:739)
            at Android.os.Handler.dispatchMessage(Handler.Java:95)
            at Android.os.Looper.loop(Looper.Java:148)
            at Android.app.ActivityThread.main(ActivityThread.Java:5417)
            at Java.lang.reflect.Method.invoke(Native Method)
            at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:726)
            at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:616)
     Caused by: Java.lang.reflect.InvocationTargetException
            at Java.lang.reflect.Method.invoke(Native Method)
            at Android.view.View$DeclaredOnClickListener.onClick(View.Java:4447)
            at Android.view.View.performClick(View.Java:5198)
            at Android.view.View$PerformClick.run(View.Java:21147)
            at Android.os.Handler.handleCallback(Handler.Java:739)
            at Android.os.Handler.dispatchMessage(Handler.Java:95)
            at Android.os.Looper.loop(Looper.Java:148)
            at Android.app.ActivityThread.main(ActivityThread.Java:5417)
            at Java.lang.reflect.Method.invoke(Native Method)
            at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:726)
            at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:616)
     Caused by: Java.lang.SecurityException: Permission Denial: reading com.Android.providers.media.MediaProvider uri content://media/external/audio/media from pid=2009, uid=10059 requires Android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission()
            at Android.os.Parcel.readException(Parcel.Java:1599)
            at Android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.Java:183)
            at Android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.Java:135)
            at Android.content.ContentProviderProxy.query(ContentProviderNative.Java:421)
            at Android.content.ContentResolver.query(ContentResolver.Java:491)
            at Android.content.ContentResolver.query(ContentResolver.Java:434)
            at slimsimapps.troff.MainActivity.initialize(MainActivity.Java:106)
            at slimsimapps.troff.MainActivity.InitializeExternal(MainActivity.Java:80)
            at Java.lang.reflect.Method.invoke(Native Method)
            at Android.view.View$DeclaredOnClickListener.onClick(View.Java:4447)
            at Android.view.View.performClick(View.Java:5198)
            at Android.view.View$PerformClick.run(View.Java:21147)
            at Android.os.Handler.handleCallback(Handler.Java:739)
            at Android.os.Handler.dispatchMessage(Handler.Java:95)
            at Android.os.Looper.loop(Looper.Java:148)
            at Android.app.ActivityThread.main(ActivityThread.Java:5417)
            at Java.lang.reflect.Method.invoke(Native Method)
            at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:726)
            at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:616)
    --------- beginning of system
70
Slim Sim

Vous avez deux solutions à votre problème. Le plus rapide est d'abaisser targetApi à 22 (fichier build.gradle). Deuxièmement, il faut utiliser un nouveau et merveilleux modèle de demande de permission:

if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
        != PackageManager.PERMISSION_GRANTED) {

    // Should we show an explanation?
    if (shouldShowRequestPermissionRationale(
            Manifest.permission.READ_EXTERNAL_STORAGE)) {
        // Explain to the user why we need to read the contacts
    }

    requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
            MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);

    // MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE is an
    // app-defined int constant that should be quite unique

    return;
}

Sniplet trouvé ici: https://developer.Android.com/training/permissions/requesting.html

69
piotrpo

Vous avez demandé la permission au moment de l'exécution:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
        && ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
            REQUEST_PERMISSION);
    dialog.dismiss();
    return;
}

Et dans le rappel ci-dessous, vous pouvez accéder au stockage sans problème.

@Override
public void onRequestPermissionsResult(final int requestCode, @NonNull final String[] permissions, @NonNull final int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == REQUEST_PERMISSION) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            // Permission granted.
        } else {
            // User refused to grant permission.
        }
    }
}
14
maclir

Étape 1: ajoutez la permission sur Android manifest.xml

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

Étape 2: méthode onCreate ()

int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);

    if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST_READ_MEDIA);
    } else {
        readDataExternal();
    }

Étape 3: substituez la méthode onRequestPermissionsResult pour obtenir le rappel

 @Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_READ_MEDIA:
            if ((grantResults.length > 0) && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
                readDataExternal();
            }
            break;

        default:
            break;
    }
}

Remarque: readDataExternal () est une méthode permettant d’obtenir des données à partir d’un stockage externe.

Merci.

6
sonnv1368

J'ai également eu un journal d'erreur similaire et voici ce que j'ai fait-

  1. Dans la méthode onCreate, nous demandons une boîte de dialogue pour la vérification des autorisations.

    ActivityCompat.requestPermissions(MainActivity.this,
    new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},1);
    
  2. Méthode pour vérifier le résultat

    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case 1: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // permission granted and now can proceed
             mymethod(); //a sample method called
    
            } else {
    
                // permission denied, boo! Disable the
                // functionality that depends on this permission.
                Toast.makeText(MainActivity.this, "Permission denied to read your External storage", Toast.LENGTH_SHORT).show();
            }
            return;
        }
        // add other cases for more permissions
        }
    }
    

La documentation officielle de Requesting Runtime Permissions

4
user7020107

Votre problème a-t-il été résolu? Quel est votre SDK cible? Essayez d'ajouter Android;maxSDKVersion="21" à <uses-permission Android:name="Android.permission.READ_EXTERNAL_STORAGE" />

1
Jerry Ejonavi

http://developer.Android.com/reference/Android/provider/MediaStore.Audio.AudioColumns.html

Essayez de changer la ligne contentResolver.query

//change it to the columns you need
String[] columns = new String[]{MediaStore.Audio.AudioColumns.DATA}; 
Cursor cursor = contentResolver.query(uri, columns, null, null, null);

public static final String MEDIA_CONTENT_CONTROL

Ne pas utiliser par des applications tierces en raison de la confidentialité de la consommation de médias

http://developer.Android.com/reference/Android/Manifest.permission.html#MEDIA_CONTENT_CONTROL

essayez de supprimer le <uses-permission Android:name="Android.permission.MEDIA_CONTENT_CONTROL"/> en premier et réessayez?

0
Derek Fung

En plus de toutes les réponses. Vous pouvez également spécifier le minsdk à appliquer avec cette annotation.

@TargetApi(_apiLevel_)

J'ai utilisé cela afin d'accepter cette demande même si mon minsdk a 18 ans. La méthode ne s'exécute que lorsque le périphérique cible "_apilevel_" et supérieur. Voici ma méthode:

    @TargetApi(23)
void solicitarPermisos(){

    if (ContextCompat.checkSelfPermission(this,permiso)
            != PackageManager.PERMISSION_GRANTED) {

        // Should we show an explanation?
        if (shouldShowRequestPermissionRationale(
                Manifest.permission.READ_EXTERNAL_STORAGE)) {
            // Explain to the user why we need to read the contacts
        }

        requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                1);

        // MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE is an
        // app-defined int constant that should be quite unique

        return;
    }

}
0
Gian Gomen

Veuillez vérifier ci-dessous le code qui vous permet de trouver tous les fichiers musicaux de sdcard:

public class MainActivity extends Activity{

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_animations);
    getAllSongsFromSDCARD();

}

public void getAllSongsFromSDCARD() {
    String[] STAR = { "*" };
    Cursor cursor;
    Uri allsongsuri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
    String selection = MediaStore.Audio.Media.IS_MUSIC + " != 0";

    cursor = managedQuery(allsongsuri, STAR, selection, null, null);

    if (cursor != null) {
        if (cursor.moveToFirst()) {
            do {
                String song_name = cursor
                        .getString(cursor
                                .getColumnIndex(MediaStore.Audio.Media.DISPLAY_NAME));
                int song_id = cursor.getInt(cursor
                        .getColumnIndex(MediaStore.Audio.Media._ID));

                String fullpath = cursor.getString(cursor
                        .getColumnIndex(MediaStore.Audio.Media.DATA));

                String album_name = cursor.getString(cursor
                        .getColumnIndex(MediaStore.Audio.Media.ALBUM));
                int album_id = cursor.getInt(cursor
                        .getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));

                String artist_name = cursor.getString(cursor
                        .getColumnIndex(MediaStore.Audio.Media.ARTIST));
                int artist_id = cursor.getInt(cursor
                        .getColumnIndex(MediaStore.Audio.Media.ARTIST_ID));
                System.out.println("sonng name"+fullpath);
            } while (cursor.moveToNext());

        }
        cursor.close();
    }
}


}

J'ai également ajouté la ligne suivante dans le fichier AndroidManifest.xml comme ci-dessous:

<uses-sdk
    Android:minSdkVersion="16"
    Android:targetSdkVersion="17" />

<uses-permission Android:name="Android.permission.MEDIA_CONTENT_CONTROL" />
<uses-permission Android:name="Android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission Android:name="Android.permission.WRITE_EXTERNAL_STORAGE" />
0
Rajan Bhavsar