Lire l'autorisation de stockage externe 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 facile"hello world" -lecteur de musique.
j'ai suivi quelques tutoriels et ils donnent essentiellement le même code. Mais cela ne marchera pas; il continue de s'écraser et de me dire:
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()
....
Voici mon 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>
C'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 mettre ceci à différents endroits dans le fichier manifeste:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE”/>
pour ajouter android: maxSdkVersion à Read External storage premission:
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="21" />
pour le mettre dans le manifeste / demande/ activité-étiquette:
android:exported=“true”
Pour mettre grantUriPremission entre uri et cursro dans le javamethod:
grantUriPermission(null, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
pour utiliser ceci, il ne s'écrasera pas, mais le curseur devient null:
uri = MediaStore.Audio.Media.getContentUri("EXTERNAL_CONTENT_URI”);
pour utiliser l'uri de contenu interne, cela fonctionne comme prévu, mais il donne seulement "OS-sounds" tels que le bruit d'obturateur, faible batterie-son, bouton-clic et tel:
uri = MediaStore.Audio.Media.INTERNAL_CONTENT_URI;
Moyens de l'aide, cela ne devrait pas être un problème difficile je sais, mais je me sens tellement comme un débutant!
j'ai lu et j'ai essayé (ou je les ai considérés comme n'étant pas applicables à mon problème):
- Android READ_EXTERNAL_STORAGE permission not working
- N'ont besoin d'une permission que pour les anciennes versions android: maxSdkVersion ne fonctionne pas?
- obtenir le nom de fichier et le chemin D'URI de mediastore
- Android KitKat securityException lorsque vous essayez de lire à partir de MediaStore
- Android: java.lang.SecurityException: Autorisation de Déni: démarrer l'Intention de
trace de la 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
9 réponses
Vous avez deux solutions pour votre problème. Le plus rapide est de réduire targetApi à 22 (build.gradle fichier). Le second est d'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
vous avez demandé la permission à l'heure d'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.
}
}
}
Step1: ajouter permission sur Android manifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Etape 2: onCreate() la méthode
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();
}
Step3: outrepasser 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;
}
}
Note: readDataExternal () est une méthode pour obtenir des données à partir du stockage externe.
Merci.
j'ai aussi eu un journal d'erreurs similaire et voici ce que j'ai fait -
-
dans la méthode onCreate nous demandons une boîte de dialogue pour vérifier les permissions
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},1);
-
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 Demande d'Exécution des Autorisations
A votre problème résolu? Quelle est votre cible SDK? Essayez d'ajouter android;maxSDKVersion="21"
à <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
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 des médias
http://developer.android.com/reference/android/Manifest.permission.html#MEDIA_CONTENT_CONTROL
essayer de supprimer le <uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL"/>
d'abord et essayer à nouveau?
Veuillez cocher ci-dessous le code que l'utilisation que vous pouvez trouver tous les fichiers de musique 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 aussi ajouté la ligne suivante dans le AndroidManifest.fichier 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" />
En plus de toutes les réponses. Vous pouvez également spécifier le minsdk à appliquer avec cette annotation
@TargetApi(_apiLevel_)
j'ai utilisé ceci pour accepter cette requête même mon minsdk est 18. Ce qu'il fait est que la méthode ne fonctionne 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;
}
}
allez simplement à vos" paramètres", sous" Périphérique "sélectionnez" apps", puis allez à votre my_application et accordez la permission de" stockage".