Struggling with a 'run-time' Android WRITE_EXTERNAL_STORAGE permission












2















I have a fragment. In this fragment I use onActivityResult() to catch an intent when the user chooses to select a photo and import that photo into my app:



Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CAMERA) {
if (resultCode == Activity.RESULT_OK) {
Uri takenPhotoUri = ImageUtils.getInstance().getPhotoFileUri(getContext(), imageFileName);
actionsListener.onSignalPhotoSelected(takenPhotoUri.getPath());
}
}

if (requestCode == REQUEST_GALLERY && resultCode == Activity.RESULT_OK && data != null && data.getData() != null) {

Uri fileUri = data.getData();
String path = null;
File photoFile = new File(fileUri.toString());

// Differentiate between SDK versions
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

// Code for Android 6 and > goes here
if(getActivity().checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
//showPermissionDialog(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE_FOR_CLOUDE);
ActivityCompat.requestPermissions(getActivity(), new String {Manifest.permission.WRITE_EXTERNAL_STORAGE}, WRITE_EXTERNAL_STORAGE_FOR_CLOUDE);
}
try {
ParcelFileDescriptor parcelFileDesc = getActivity().getContentResolver().openFileDescriptor(fileUri, "r");
FileDescriptor fileDesc = parcelFileDesc.getFileDescriptor();
Bitmap photo = BitmapFactory.decodeFileDescriptor(fileDesc);
path = MediaStore.Images.Media.insertImage(getContext().getContentResolver(), photo, "temp", null);
parcelFileDesc.close();

// DRY!!
photoFile = ImageUtils.getInstance().getFromMediaUri(getContext(), getContext().getContentResolver(), Uri.parse(path));

} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

}
else {
// DRY!!
photoFile = ImageUtils.getInstance().getFromMediaUri(getContext(), getContext().getContentResolver(), data.getData());
}
if(photoFile != null) {
actionsListener.onSignalPhotoSelected(Uri.fromFile(photoFile).getPath());
}
}

if (requestCode == REQUEST_SIGNAL_DETAILS) {
if (resultCode == Activity.RESULT_OK) {
Signal signal = data.getParcelableExtra("signal");
if (signal != null) {
actionsListener.onSignalStatusUpdated(signal);
}
}
}
}


My problem is this: when the user selects a photo from Google Photos (a photo that only exists on the cloud and it has not been downloaded locally) my app crashes with the following error:




E/MediaStore: Failed to insert image
java.lang.SecurityException: Permission Denial: writing com.android.providers.media.MediaProvider uri content://media/external/images/media from pid=9851, uid=10091 requires android.permission.WRITE_EXTERNAL_STORAGE, or grantUriPermission()
at android.os.Parcel.readException(Parcel.java:1943)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:183)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:135)
at android.content.ContentProviderProxy.insert(ContentProviderNative.java:476)
at android.content.ContentResolver.insert(ContentResolver.java:1539)
at android.provider.MediaStore$Images$Media.insertImage(MediaStore.java:984)
at org.helpapaw.helpapaw.signalsmap.SignalsMapFragment.onActivityResult(SignalsMapFragment.java:738)
at android.support.v4.app.FragmentActivity.onActivityResult(FragmentActivity.java:151)
at android.app.Activity.dispatchActivityResult(Activity.java:7235)
at android.app.ActivityThread.deliverResults(ActivityThread.java:4320)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4367)
at android.app.ActivityThread.-wrap19(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1649)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: org.helpapaw.helpapaw, PID: 9851
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=196611, result=-1, data=Intent { dat=content://com.google.android.apps.photos.contentprovider/0/1/mediakey:/local%3Aabc88a06-d518-4fae-b85d-73f727595a90/ORIGINAL/NONE/1144559444 flg=0x1 clip={text/uri-list U:content://com.google.android.apps.photos.contentprovider/0/1/mediakey%3A%2Flocal%253Aabc88a06-d518-4fae-b85d-73f727595a90/ORIGINAL/NONE/1144559444} }} to activity {org.helpapaw.helpapaw/org.helpapaw.helpapaw.signalsmap.SignalsMapActivity}: java.lang.NullPointerException: uriString
at android.app.ActivityThread.deliverResults(ActivityThread.java:4324)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4367)
at android.app.ActivityThread.-wrap19(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1649)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Caused by: java.lang.NullPointerException: uriString
at android.net.Uri$StringUri.(Uri.java:476)
at android.net.Uri$StringUri.(Unknown Source:0)
at android.net.Uri.parse(Uri.java:438)
at org.helpapaw.helpapaw.signalsmap.SignalsMapFragment.onActivityResult(SignalsMapFragment.java:742)
at android.support.v4.app.FragmentActivity.onActivityResult(FragmentActivity.java:151)
at android.app.Activity.dispatchActivityResult(Activity.java:7235)
at android.app.ActivityThread.deliverResults(ActivityThread.java:4320)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4367) 
at android.app.ActivityThread.-wrap19(Unknown Source:0) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1649) 
at android.os.Handler.dispatchMessage(Handler.java:105) 
at android.os.Looper.loop(Looper.java:164) 
at android.app.ActivityThread.main(ActivityThread.java:6541) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767) 




The first line of that error makes me think of a WRITE_TO_EXTERNAL permission error:




E/MediaStore: Failed to insert image
java.lang.SecurityException: Permission Denial: writing com.android.providers.media.MediaProvider uri content://media/external/images/media from pid=9851, uid=10091 requires android.permission.WRITE_EXTERNAL_STORAGE, or grantUriPermission()




So I check to make sure that this API version needs "run-time" permission (as you can see in the code above), and the line:



ActivityCompat.requestPermissions(getActivity(), new String {Manifest.permission.WRITE_EXTERNAL_STORAGE}, WRITE_EXTERNAL_STORAGE_FOR_CLOUDE);


gets hit, but no confirmation dialog appears on the screen.
Another interesting fact, the error only happens the very first time I run the app, (on API 8.0) and works fine on 5.1, 6.0, 7.1 and 8.1 but crashes on 8.0 (emulator). What am I missing?










share|improve this question

























  • nobody has any suggestions, huh? :S

    – Nactus
    Nov 27 '18 at 23:47


















2















I have a fragment. In this fragment I use onActivityResult() to catch an intent when the user chooses to select a photo and import that photo into my app:



Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CAMERA) {
if (resultCode == Activity.RESULT_OK) {
Uri takenPhotoUri = ImageUtils.getInstance().getPhotoFileUri(getContext(), imageFileName);
actionsListener.onSignalPhotoSelected(takenPhotoUri.getPath());
}
}

if (requestCode == REQUEST_GALLERY && resultCode == Activity.RESULT_OK && data != null && data.getData() != null) {

Uri fileUri = data.getData();
String path = null;
File photoFile = new File(fileUri.toString());

// Differentiate between SDK versions
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

// Code for Android 6 and > goes here
if(getActivity().checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
//showPermissionDialog(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE_FOR_CLOUDE);
ActivityCompat.requestPermissions(getActivity(), new String {Manifest.permission.WRITE_EXTERNAL_STORAGE}, WRITE_EXTERNAL_STORAGE_FOR_CLOUDE);
}
try {
ParcelFileDescriptor parcelFileDesc = getActivity().getContentResolver().openFileDescriptor(fileUri, "r");
FileDescriptor fileDesc = parcelFileDesc.getFileDescriptor();
Bitmap photo = BitmapFactory.decodeFileDescriptor(fileDesc);
path = MediaStore.Images.Media.insertImage(getContext().getContentResolver(), photo, "temp", null);
parcelFileDesc.close();

// DRY!!
photoFile = ImageUtils.getInstance().getFromMediaUri(getContext(), getContext().getContentResolver(), Uri.parse(path));

} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

}
else {
// DRY!!
photoFile = ImageUtils.getInstance().getFromMediaUri(getContext(), getContext().getContentResolver(), data.getData());
}
if(photoFile != null) {
actionsListener.onSignalPhotoSelected(Uri.fromFile(photoFile).getPath());
}
}

if (requestCode == REQUEST_SIGNAL_DETAILS) {
if (resultCode == Activity.RESULT_OK) {
Signal signal = data.getParcelableExtra("signal");
if (signal != null) {
actionsListener.onSignalStatusUpdated(signal);
}
}
}
}


My problem is this: when the user selects a photo from Google Photos (a photo that only exists on the cloud and it has not been downloaded locally) my app crashes with the following error:




E/MediaStore: Failed to insert image
java.lang.SecurityException: Permission Denial: writing com.android.providers.media.MediaProvider uri content://media/external/images/media from pid=9851, uid=10091 requires android.permission.WRITE_EXTERNAL_STORAGE, or grantUriPermission()
at android.os.Parcel.readException(Parcel.java:1943)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:183)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:135)
at android.content.ContentProviderProxy.insert(ContentProviderNative.java:476)
at android.content.ContentResolver.insert(ContentResolver.java:1539)
at android.provider.MediaStore$Images$Media.insertImage(MediaStore.java:984)
at org.helpapaw.helpapaw.signalsmap.SignalsMapFragment.onActivityResult(SignalsMapFragment.java:738)
at android.support.v4.app.FragmentActivity.onActivityResult(FragmentActivity.java:151)
at android.app.Activity.dispatchActivityResult(Activity.java:7235)
at android.app.ActivityThread.deliverResults(ActivityThread.java:4320)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4367)
at android.app.ActivityThread.-wrap19(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1649)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: org.helpapaw.helpapaw, PID: 9851
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=196611, result=-1, data=Intent { dat=content://com.google.android.apps.photos.contentprovider/0/1/mediakey:/local%3Aabc88a06-d518-4fae-b85d-73f727595a90/ORIGINAL/NONE/1144559444 flg=0x1 clip={text/uri-list U:content://com.google.android.apps.photos.contentprovider/0/1/mediakey%3A%2Flocal%253Aabc88a06-d518-4fae-b85d-73f727595a90/ORIGINAL/NONE/1144559444} }} to activity {org.helpapaw.helpapaw/org.helpapaw.helpapaw.signalsmap.SignalsMapActivity}: java.lang.NullPointerException: uriString
at android.app.ActivityThread.deliverResults(ActivityThread.java:4324)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4367)
at android.app.ActivityThread.-wrap19(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1649)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Caused by: java.lang.NullPointerException: uriString
at android.net.Uri$StringUri.(Uri.java:476)
at android.net.Uri$StringUri.(Unknown Source:0)
at android.net.Uri.parse(Uri.java:438)
at org.helpapaw.helpapaw.signalsmap.SignalsMapFragment.onActivityResult(SignalsMapFragment.java:742)
at android.support.v4.app.FragmentActivity.onActivityResult(FragmentActivity.java:151)
at android.app.Activity.dispatchActivityResult(Activity.java:7235)
at android.app.ActivityThread.deliverResults(ActivityThread.java:4320)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4367) 
at android.app.ActivityThread.-wrap19(Unknown Source:0) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1649) 
at android.os.Handler.dispatchMessage(Handler.java:105) 
at android.os.Looper.loop(Looper.java:164) 
at android.app.ActivityThread.main(ActivityThread.java:6541) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767) 




The first line of that error makes me think of a WRITE_TO_EXTERNAL permission error:




E/MediaStore: Failed to insert image
java.lang.SecurityException: Permission Denial: writing com.android.providers.media.MediaProvider uri content://media/external/images/media from pid=9851, uid=10091 requires android.permission.WRITE_EXTERNAL_STORAGE, or grantUriPermission()




So I check to make sure that this API version needs "run-time" permission (as you can see in the code above), and the line:



ActivityCompat.requestPermissions(getActivity(), new String {Manifest.permission.WRITE_EXTERNAL_STORAGE}, WRITE_EXTERNAL_STORAGE_FOR_CLOUDE);


gets hit, but no confirmation dialog appears on the screen.
Another interesting fact, the error only happens the very first time I run the app, (on API 8.0) and works fine on 5.1, 6.0, 7.1 and 8.1 but crashes on 8.0 (emulator). What am I missing?










share|improve this question

























  • nobody has any suggestions, huh? :S

    – Nactus
    Nov 27 '18 at 23:47
















2












2








2








I have a fragment. In this fragment I use onActivityResult() to catch an intent when the user chooses to select a photo and import that photo into my app:



Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CAMERA) {
if (resultCode == Activity.RESULT_OK) {
Uri takenPhotoUri = ImageUtils.getInstance().getPhotoFileUri(getContext(), imageFileName);
actionsListener.onSignalPhotoSelected(takenPhotoUri.getPath());
}
}

if (requestCode == REQUEST_GALLERY && resultCode == Activity.RESULT_OK && data != null && data.getData() != null) {

Uri fileUri = data.getData();
String path = null;
File photoFile = new File(fileUri.toString());

// Differentiate between SDK versions
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

// Code for Android 6 and > goes here
if(getActivity().checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
//showPermissionDialog(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE_FOR_CLOUDE);
ActivityCompat.requestPermissions(getActivity(), new String {Manifest.permission.WRITE_EXTERNAL_STORAGE}, WRITE_EXTERNAL_STORAGE_FOR_CLOUDE);
}
try {
ParcelFileDescriptor parcelFileDesc = getActivity().getContentResolver().openFileDescriptor(fileUri, "r");
FileDescriptor fileDesc = parcelFileDesc.getFileDescriptor();
Bitmap photo = BitmapFactory.decodeFileDescriptor(fileDesc);
path = MediaStore.Images.Media.insertImage(getContext().getContentResolver(), photo, "temp", null);
parcelFileDesc.close();

// DRY!!
photoFile = ImageUtils.getInstance().getFromMediaUri(getContext(), getContext().getContentResolver(), Uri.parse(path));

} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

}
else {
// DRY!!
photoFile = ImageUtils.getInstance().getFromMediaUri(getContext(), getContext().getContentResolver(), data.getData());
}
if(photoFile != null) {
actionsListener.onSignalPhotoSelected(Uri.fromFile(photoFile).getPath());
}
}

if (requestCode == REQUEST_SIGNAL_DETAILS) {
if (resultCode == Activity.RESULT_OK) {
Signal signal = data.getParcelableExtra("signal");
if (signal != null) {
actionsListener.onSignalStatusUpdated(signal);
}
}
}
}


My problem is this: when the user selects a photo from Google Photos (a photo that only exists on the cloud and it has not been downloaded locally) my app crashes with the following error:




E/MediaStore: Failed to insert image
java.lang.SecurityException: Permission Denial: writing com.android.providers.media.MediaProvider uri content://media/external/images/media from pid=9851, uid=10091 requires android.permission.WRITE_EXTERNAL_STORAGE, or grantUriPermission()
at android.os.Parcel.readException(Parcel.java:1943)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:183)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:135)
at android.content.ContentProviderProxy.insert(ContentProviderNative.java:476)
at android.content.ContentResolver.insert(ContentResolver.java:1539)
at android.provider.MediaStore$Images$Media.insertImage(MediaStore.java:984)
at org.helpapaw.helpapaw.signalsmap.SignalsMapFragment.onActivityResult(SignalsMapFragment.java:738)
at android.support.v4.app.FragmentActivity.onActivityResult(FragmentActivity.java:151)
at android.app.Activity.dispatchActivityResult(Activity.java:7235)
at android.app.ActivityThread.deliverResults(ActivityThread.java:4320)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4367)
at android.app.ActivityThread.-wrap19(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1649)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: org.helpapaw.helpapaw, PID: 9851
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=196611, result=-1, data=Intent { dat=content://com.google.android.apps.photos.contentprovider/0/1/mediakey:/local%3Aabc88a06-d518-4fae-b85d-73f727595a90/ORIGINAL/NONE/1144559444 flg=0x1 clip={text/uri-list U:content://com.google.android.apps.photos.contentprovider/0/1/mediakey%3A%2Flocal%253Aabc88a06-d518-4fae-b85d-73f727595a90/ORIGINAL/NONE/1144559444} }} to activity {org.helpapaw.helpapaw/org.helpapaw.helpapaw.signalsmap.SignalsMapActivity}: java.lang.NullPointerException: uriString
at android.app.ActivityThread.deliverResults(ActivityThread.java:4324)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4367)
at android.app.ActivityThread.-wrap19(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1649)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Caused by: java.lang.NullPointerException: uriString
at android.net.Uri$StringUri.(Uri.java:476)
at android.net.Uri$StringUri.(Unknown Source:0)
at android.net.Uri.parse(Uri.java:438)
at org.helpapaw.helpapaw.signalsmap.SignalsMapFragment.onActivityResult(SignalsMapFragment.java:742)
at android.support.v4.app.FragmentActivity.onActivityResult(FragmentActivity.java:151)
at android.app.Activity.dispatchActivityResult(Activity.java:7235)
at android.app.ActivityThread.deliverResults(ActivityThread.java:4320)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4367) 
at android.app.ActivityThread.-wrap19(Unknown Source:0) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1649) 
at android.os.Handler.dispatchMessage(Handler.java:105) 
at android.os.Looper.loop(Looper.java:164) 
at android.app.ActivityThread.main(ActivityThread.java:6541) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767) 




The first line of that error makes me think of a WRITE_TO_EXTERNAL permission error:




E/MediaStore: Failed to insert image
java.lang.SecurityException: Permission Denial: writing com.android.providers.media.MediaProvider uri content://media/external/images/media from pid=9851, uid=10091 requires android.permission.WRITE_EXTERNAL_STORAGE, or grantUriPermission()




So I check to make sure that this API version needs "run-time" permission (as you can see in the code above), and the line:



ActivityCompat.requestPermissions(getActivity(), new String {Manifest.permission.WRITE_EXTERNAL_STORAGE}, WRITE_EXTERNAL_STORAGE_FOR_CLOUDE);


gets hit, but no confirmation dialog appears on the screen.
Another interesting fact, the error only happens the very first time I run the app, (on API 8.0) and works fine on 5.1, 6.0, 7.1 and 8.1 but crashes on 8.0 (emulator). What am I missing?










share|improve this question
















I have a fragment. In this fragment I use onActivityResult() to catch an intent when the user chooses to select a photo and import that photo into my app:



Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CAMERA) {
if (resultCode == Activity.RESULT_OK) {
Uri takenPhotoUri = ImageUtils.getInstance().getPhotoFileUri(getContext(), imageFileName);
actionsListener.onSignalPhotoSelected(takenPhotoUri.getPath());
}
}

if (requestCode == REQUEST_GALLERY && resultCode == Activity.RESULT_OK && data != null && data.getData() != null) {

Uri fileUri = data.getData();
String path = null;
File photoFile = new File(fileUri.toString());

// Differentiate between SDK versions
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

// Code for Android 6 and > goes here
if(getActivity().checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
//showPermissionDialog(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE_FOR_CLOUDE);
ActivityCompat.requestPermissions(getActivity(), new String {Manifest.permission.WRITE_EXTERNAL_STORAGE}, WRITE_EXTERNAL_STORAGE_FOR_CLOUDE);
}
try {
ParcelFileDescriptor parcelFileDesc = getActivity().getContentResolver().openFileDescriptor(fileUri, "r");
FileDescriptor fileDesc = parcelFileDesc.getFileDescriptor();
Bitmap photo = BitmapFactory.decodeFileDescriptor(fileDesc);
path = MediaStore.Images.Media.insertImage(getContext().getContentResolver(), photo, "temp", null);
parcelFileDesc.close();

// DRY!!
photoFile = ImageUtils.getInstance().getFromMediaUri(getContext(), getContext().getContentResolver(), Uri.parse(path));

} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

}
else {
// DRY!!
photoFile = ImageUtils.getInstance().getFromMediaUri(getContext(), getContext().getContentResolver(), data.getData());
}
if(photoFile != null) {
actionsListener.onSignalPhotoSelected(Uri.fromFile(photoFile).getPath());
}
}

if (requestCode == REQUEST_SIGNAL_DETAILS) {
if (resultCode == Activity.RESULT_OK) {
Signal signal = data.getParcelableExtra("signal");
if (signal != null) {
actionsListener.onSignalStatusUpdated(signal);
}
}
}
}


My problem is this: when the user selects a photo from Google Photos (a photo that only exists on the cloud and it has not been downloaded locally) my app crashes with the following error:




E/MediaStore: Failed to insert image
java.lang.SecurityException: Permission Denial: writing com.android.providers.media.MediaProvider uri content://media/external/images/media from pid=9851, uid=10091 requires android.permission.WRITE_EXTERNAL_STORAGE, or grantUriPermission()
at android.os.Parcel.readException(Parcel.java:1943)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:183)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:135)
at android.content.ContentProviderProxy.insert(ContentProviderNative.java:476)
at android.content.ContentResolver.insert(ContentResolver.java:1539)
at android.provider.MediaStore$Images$Media.insertImage(MediaStore.java:984)
at org.helpapaw.helpapaw.signalsmap.SignalsMapFragment.onActivityResult(SignalsMapFragment.java:738)
at android.support.v4.app.FragmentActivity.onActivityResult(FragmentActivity.java:151)
at android.app.Activity.dispatchActivityResult(Activity.java:7235)
at android.app.ActivityThread.deliverResults(ActivityThread.java:4320)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4367)
at android.app.ActivityThread.-wrap19(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1649)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: org.helpapaw.helpapaw, PID: 9851
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=196611, result=-1, data=Intent { dat=content://com.google.android.apps.photos.contentprovider/0/1/mediakey:/local%3Aabc88a06-d518-4fae-b85d-73f727595a90/ORIGINAL/NONE/1144559444 flg=0x1 clip={text/uri-list U:content://com.google.android.apps.photos.contentprovider/0/1/mediakey%3A%2Flocal%253Aabc88a06-d518-4fae-b85d-73f727595a90/ORIGINAL/NONE/1144559444} }} to activity {org.helpapaw.helpapaw/org.helpapaw.helpapaw.signalsmap.SignalsMapActivity}: java.lang.NullPointerException: uriString
at android.app.ActivityThread.deliverResults(ActivityThread.java:4324)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4367)
at android.app.ActivityThread.-wrap19(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1649)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Caused by: java.lang.NullPointerException: uriString
at android.net.Uri$StringUri.(Uri.java:476)
at android.net.Uri$StringUri.(Unknown Source:0)
at android.net.Uri.parse(Uri.java:438)
at org.helpapaw.helpapaw.signalsmap.SignalsMapFragment.onActivityResult(SignalsMapFragment.java:742)
at android.support.v4.app.FragmentActivity.onActivityResult(FragmentActivity.java:151)
at android.app.Activity.dispatchActivityResult(Activity.java:7235)
at android.app.ActivityThread.deliverResults(ActivityThread.java:4320)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4367) 
at android.app.ActivityThread.-wrap19(Unknown Source:0) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1649) 
at android.os.Handler.dispatchMessage(Handler.java:105) 
at android.os.Looper.loop(Looper.java:164) 
at android.app.ActivityThread.main(ActivityThread.java:6541) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767) 




The first line of that error makes me think of a WRITE_TO_EXTERNAL permission error:




E/MediaStore: Failed to insert image
java.lang.SecurityException: Permission Denial: writing com.android.providers.media.MediaProvider uri content://media/external/images/media from pid=9851, uid=10091 requires android.permission.WRITE_EXTERNAL_STORAGE, or grantUriPermission()




So I check to make sure that this API version needs "run-time" permission (as you can see in the code above), and the line:



ActivityCompat.requestPermissions(getActivity(), new String {Manifest.permission.WRITE_EXTERNAL_STORAGE}, WRITE_EXTERNAL_STORAGE_FOR_CLOUDE);


gets hit, but no confirmation dialog appears on the screen.
Another interesting fact, the error only happens the very first time I run the app, (on API 8.0) and works fine on 5.1, 6.0, 7.1 and 8.1 but crashes on 8.0 (emulator). What am I missing?







android android-fragments






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Dec 11 '18 at 5:11









Saikrishna Rajaraman

1,382419




1,382419










asked Nov 22 '18 at 19:51









NactusNactus

428928




428928













  • nobody has any suggestions, huh? :S

    – Nactus
    Nov 27 '18 at 23:47





















  • nobody has any suggestions, huh? :S

    – Nactus
    Nov 27 '18 at 23:47



















nobody has any suggestions, huh? :S

– Nactus
Nov 27 '18 at 23:47







nobody has any suggestions, huh? :S

– Nactus
Nov 27 '18 at 23:47














1 Answer
1






active

oldest

votes


















0














For anyone who struggles with something similar; the key is to request the necessary permission(s) all at once, using (in my case) the Fragment.requestPermissions(String permissions, int requestCode); method. This method allows passing an array of permissions into its first parameter:



    String permissions = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE};
if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(permissions, READ_WRITE_EXTERNAL_STORAGE_FOR_GALLERY);
}




  • What I wish I knew:



    once a new activity gets called by an intent, be it the camera or the photo-gallery; trying to ask the user for permissions doesn't work anymore; meaning - once the camera or the photo-gallery is open, we lose our own app's context and therefore we can not prompt the user for permissions any-longer. It is paramount that all permissions are requested before the user leaves our app (in my case the use of an array was necessary to request permissions to both read and write to the external storage. Ask for all necessary permissions at the same-time before the user leaves the current context, then redirect to a new Activity via an intent.




I hope this helps someone.






share|improve this answer

























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53437311%2fstruggling-with-a-run-time-android-write-external-storage-permission%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    For anyone who struggles with something similar; the key is to request the necessary permission(s) all at once, using (in my case) the Fragment.requestPermissions(String permissions, int requestCode); method. This method allows passing an array of permissions into its first parameter:



        String permissions = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE};
    if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED &&
    ContextCompat.checkSelfPermission(getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
    requestPermissions(permissions, READ_WRITE_EXTERNAL_STORAGE_FOR_GALLERY);
    }




    • What I wish I knew:



      once a new activity gets called by an intent, be it the camera or the photo-gallery; trying to ask the user for permissions doesn't work anymore; meaning - once the camera or the photo-gallery is open, we lose our own app's context and therefore we can not prompt the user for permissions any-longer. It is paramount that all permissions are requested before the user leaves our app (in my case the use of an array was necessary to request permissions to both read and write to the external storage. Ask for all necessary permissions at the same-time before the user leaves the current context, then redirect to a new Activity via an intent.




    I hope this helps someone.






    share|improve this answer






























      0














      For anyone who struggles with something similar; the key is to request the necessary permission(s) all at once, using (in my case) the Fragment.requestPermissions(String permissions, int requestCode); method. This method allows passing an array of permissions into its first parameter:



          String permissions = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE};
      if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED &&
      ContextCompat.checkSelfPermission(getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
      requestPermissions(permissions, READ_WRITE_EXTERNAL_STORAGE_FOR_GALLERY);
      }




      • What I wish I knew:



        once a new activity gets called by an intent, be it the camera or the photo-gallery; trying to ask the user for permissions doesn't work anymore; meaning - once the camera or the photo-gallery is open, we lose our own app's context and therefore we can not prompt the user for permissions any-longer. It is paramount that all permissions are requested before the user leaves our app (in my case the use of an array was necessary to request permissions to both read and write to the external storage. Ask for all necessary permissions at the same-time before the user leaves the current context, then redirect to a new Activity via an intent.




      I hope this helps someone.






      share|improve this answer




























        0












        0








        0







        For anyone who struggles with something similar; the key is to request the necessary permission(s) all at once, using (in my case) the Fragment.requestPermissions(String permissions, int requestCode); method. This method allows passing an array of permissions into its first parameter:



            String permissions = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE};
        if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED &&
        ContextCompat.checkSelfPermission(getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
        requestPermissions(permissions, READ_WRITE_EXTERNAL_STORAGE_FOR_GALLERY);
        }




        • What I wish I knew:



          once a new activity gets called by an intent, be it the camera or the photo-gallery; trying to ask the user for permissions doesn't work anymore; meaning - once the camera or the photo-gallery is open, we lose our own app's context and therefore we can not prompt the user for permissions any-longer. It is paramount that all permissions are requested before the user leaves our app (in my case the use of an array was necessary to request permissions to both read and write to the external storage. Ask for all necessary permissions at the same-time before the user leaves the current context, then redirect to a new Activity via an intent.




        I hope this helps someone.






        share|improve this answer















        For anyone who struggles with something similar; the key is to request the necessary permission(s) all at once, using (in my case) the Fragment.requestPermissions(String permissions, int requestCode); method. This method allows passing an array of permissions into its first parameter:



            String permissions = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE};
        if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED &&
        ContextCompat.checkSelfPermission(getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
        requestPermissions(permissions, READ_WRITE_EXTERNAL_STORAGE_FOR_GALLERY);
        }




        • What I wish I knew:



          once a new activity gets called by an intent, be it the camera or the photo-gallery; trying to ask the user for permissions doesn't work anymore; meaning - once the camera or the photo-gallery is open, we lose our own app's context and therefore we can not prompt the user for permissions any-longer. It is paramount that all permissions are requested before the user leaves our app (in my case the use of an array was necessary to request permissions to both read and write to the external storage. Ask for all necessary permissions at the same-time before the user leaves the current context, then redirect to a new Activity via an intent.




        I hope this helps someone.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Dec 11 '18 at 5:18

























        answered Dec 11 '18 at 5:00









        NactusNactus

        428928




        428928
































            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53437311%2fstruggling-with-a-run-time-android-write-external-storage-permission%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            這個網誌中的熱門文章

            Tangent Lines Diagram Along Smooth Curve

            Yusuf al-Mu'taman ibn Hud

            Zucchini