READ_EXTERNAL_STORAGE permission is in manifest but still doesn't work
Solution 1
To request for any permission you can use the below code and add the permissions you need. This is how you handle runtime permissions by requesting them before accessing any data related to permission
public boolean isStoragePermissionGranted() {
if (Build.VERSION.SDK_INT >= 23) {
if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
Log.v(TAG,"Permission is granted");
return true;
} else {
Log.v(TAG,"Permission is revoked");
ActivityCompat.requestPermissions(this, new String[]{ Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
return false;
}
}
else { //permission is automatically granted on sdk<23 upon installation
Log.v(TAG,"Permission is granted");
return true;
}
}
Once you do that, for devices with API >=23 You will get popup at runtime and then once the user accepts the permission or rejects it, your onRequestPermissionsResult
method is called. so here you will have to handle your check whether user granted the app the permission. If yes you can continue with your logic
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case 0:
boolean isPerpermissionForAllGranted = false;
if (grantResults.length > 0 && permissions.length==grantResults.length) {
for (int i = 0; i < permissions.length; i++){
if (grantResults[i] == PackageManager.PERMISSION_GRANTED){
isPerpermissionForAllGranted=true;
}else{
isPerpermissionForAllGranted=false;
}
}
Log.e("value", "Permission Granted");
} else {
isPerpermissionForAllGranted=true;
Log.e("value", "Permission Denied");
}
if(isPerpermissionForAllGranted){
// do your stuff here
}
break;
}
}
UPDATE 1 For react Native
String[] perms = {
"android.permission.READ_EXTERNAL_STORAGE",
"android.permission.WRITE_EXTERNAL_STORAGE"
};
@Override
public void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Checking permissions on init
checkPerms();
}
public void checkPerms() {
// Checking if device version > 22 and we need to use new permission model
if(Build.VERSION.SDK_INT>Build.VERSION_CODES.LOLLIPOP_MR1) {
// Checking if we can draw window overlay
if (!Settings.canDrawOverlays(this)) {
// Requesting permission for window overlay(needed for all react-native apps)
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, OVERLAY_PERMISSION_REQ_CODE);
}
for(String perm : perms){
// Checking each persmission and if denied then requesting permissions
if(checkSelfPermission(perm) == PackageManager.PERMISSION_DENIED){
requestPermissions(perms, PERMISSION_REQ_CODE);
break;
}
}
}
}
// Window overlay permission intent result
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == OVERLAY_PERMISSION_REQ_CODE) {
checkPerms();
}
}
// Permission results
@Override
public void onRequestPermissionsResult(int permsRequestCode, String[] permissions, int[] grantResults){
switch(permsRequestCode){
case PERMISSION_REQ_CODE:
// example how to get result of permissions requests (there can be more then one permission dialog)
// boolean readAccepted = grantResults[0]==PackageManager.PERMISSION_GRANTED;
// boolean writeAccepted = grantResults[1]==PackageManager.PERMISSION_GRANTED;
// checking permissions to prevent situation when user denied some permission
checkPerms();
break;
}
}
Solution 2
Uses react-native PermissionAndroid class. https://facebook.github.io/react-native/docs/permissionsandroid
import { PermissionsAndroid } from 'react-native'
async requestExternalStoreageRead() {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE,
{
'title': 'Cool App ...',
'message': 'App needs access to external storage'
}
);
return granted == PermissionsAndroid.RESULTS.GRANTED
}
catch (err) {
//Handle this error
return false;
}
}
getPhotos = async () => {
//Before calling getPhotos, request permission
if (await this.requestExternalStoreageRead()){
CameraRoll.getPhotos({
first: 1000,
assetType: 'All'
})
.then((r) => {
this.setState({ photos: r.edges, summary: `Number of photos found ${r.edges.length}` })
})
.catch((error) => {
this.setState({errorMsg: error.message});
})
}
}
Solution 3
Add This code to your Activity on create
if (ContextCompat.checkSelfPermission(UserActivity.this,
Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(UserActivity.this,
Manifest.permission.READ_EXTERNAL_STORAGE)) {
} else {
ActivityCompat.requestPermissions(UserActivity.this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
a);
}
}
1110
Updated on June 05, 2022Comments
-
1110 almost 2 years
In androidmanifest.xml I have:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="23" />
In build.gradle I have:
android { compileSdkVersion 23 buildToolsVersion "23.0.1" defaultConfig { multiDexEnabled true applicationId "test" minSdkVersion 16 targetSdkVersion 23
If i try to call
CameraRoll.getPhotos()
to get library photos I get error:Could not get photos: need READ_EXTERNAL_STORAGE permission at createErrorFromErrorData
I am trying to run app on real device with android 6 and 7 on it, and I am trying to make it work like in IOS - when call getPhotos() to see permission request dialog.
What is wrong here? -
Davide Visentin about 5 yearsIn the second piece of code, it should be
case 1
to match the request code passed in the first snippet. Better, you can use a constant. -
Patrissol Kenfack almost 4 yearsThis answer would be definitively the best one. It saved me a lot of time!!