Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

READ_EXTERNAL_STORAGE permission for Android

I'm trying to access media files (music) on the users device to play them; an easy "hello world"-music player app.

I've followed some tutorials and they basically give the same code. But it won't work; it keeps crashing and telling me:

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

Now, this is my manifest file:

<?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> 

This is my Java-method:

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

I have tried:

To put this at different places in the manifest file:

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

To add android:maxSdkVersion at Read external storage premission:

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

To put this in the manifest / application / activity-tag:

android:exported=“true” 

To put grantUriPremission between uri and cursro in the javamethod:

grantUriPermission(null, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION); 

To use this, it won't crash, but the cursor becomes null:

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

To use INTERNAL content uri, this works as expected, but it only gives "OS-sounds" such as shutter-sound, low-battery-sound, button-click and such:

uri = MediaStore.Audio.Media.INTERNAL_CONTENT_URI; 

Pleas help, this should not be a hard problem i know, but i feel like such a beginner!

I have read and tried (or considered them to be not applicable for my problem):

  • Android READ_EXTERNAL_STORAGE permission not working
  • Require permission only for older android versions: maxSdkVersion does not work?
  • Get filename and path from URI from mediastore
  • Android KitKat securityException when trying to read from MediaStore
  • Android: java.lang.SecurityException: Permission Denial: start Intent

Stack trace:

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 
like image 978
Slim Sim Avatar asked Sep 07 '15 05:09

Slim Sim


People also ask

How do I add read external storage permissions on Android?

To read and write data to external storage, the app required WRITE_EXTERNAL_STORAGE and READ_EXTERNAL_STORAGE system permission. These permissions are added to the AndroidManifest. xml file. Add these permissions just after the package name.

What is write external storage permission android?

Android 11 introduces the MANAGE_EXTERNAL_STORAGE permission, which provides write access to files outside the app-specific directory and MediaStore . To learn more about this permission, and why most apps don't need to declare it to fulfill their use cases, see the guide on how to manage all files on a storage device.

How do I manage external storage permissions in Android?

On the Settings > Privacy > Permission manager > Files and media page, each app that has the permission is listed under Allowed for all files. If your app targets Android 11, keep in mind that this access to "all files" is read-only.


1 Answers

You have two solutions for your problem. The quick one is to lower targetApi to 22 (build.gradle file). Second is to use new and wonderful ask-for-permission model:

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 found here: https://developer.android.com/training/permissions/requesting.html

Solutions 2: If it does not work try this:

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);  return; 

}

and then in callback

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

that is from comments. thanks

like image 169
piotrpo Avatar answered Oct 14 '22 12:10

piotrpo