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
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
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.
}
}
}
É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.
J'ai également eu un journal d'erreur similaire et voici ce que j'ai fait-
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);
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
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" />
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?
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;
}
}
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" />