I'm attempting to perform a fragment transaction after requesting permissions in Android - however the app continually crashes. How might this code be changed in order to avoid this?
Any assistance is appreciated.
CHECK PERMISSIONS BEFORE SENDING EMAIL:
private void emailShare() {
if (mayRequestContacts()) {
emailShareImpl();
}
}
CHECK PERMISSIONS:
private boolean mayRequestContacts() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
return true;
}
requestPermissions(new String[]{READ_CONTACTS}, REQUEST_READ_CONTACTS);
return false;
}
PERMISSION CHECK RESULT:
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == REQUEST_READ_CONTACTS) {
if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
emailShareImpl();
}
}
}
INITIATE FRAGMENT TRANSACTION IF PERMISSION GRANTED:
private void emailShareImpl() {
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
EmailReferDialog mEmailReferDialog = new EmailReferDialog();
mEmailReferDialog.setCancelable(true);
mEmailReferDialog.show(fragmentManager, "EMAIL_REFER_DIALOG");
}
LOGCAT:
05-11 09:04:58.859 16113-16113/com.example E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example, PID: 16113
java.lang.RuntimeException: Failure delivering result ResultInfo{who=@android:requestPermissions:, request=65536, result=-1, data=Intent { act=android.content.pm.action.REQUEST_PERMISSIONS (has extras) }} to activity {com.example/com.example.DashboardActivity}: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.app.ActivityThread.deliverResults(ActivityThread.java:3743)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3786)
at android.app.ActivityThread.-wrap16(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1412)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5466)
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.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1493)
at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1511)
at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:638)
at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:617)
at android.support.v4.app.DialogFragment.show(DialogFragment.java:139)
at com.example.ReferFragment.emailShareImpl(ReferFragment.java:222)
at com.example.ReferFragment.onRequestPermissionsResult(ReferFragment.java:140)
at android.support.v4.app.FragmentActivity.onRequestPermissionsResult(FragmentActivity.java:894)
at android.app.Activity.dispatchRequestPermissionsResult(Activity.java:6582)
at android.app.Activity.dispatchActivityResult(Activity.java:6460)
at android.app.ActivityThread.deliverResults(ActivityThread.java:3739)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3786)
at android.app.ActivityThread.-wrap16(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1412)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5466)
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)
This happens because onRequestPermissionresult
is called before activity's onResume
. You can simply fix this by following:
private boolean mShareEmail = false;
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == REQUEST_READ_CONTACTS) {
if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
mShareEmail = true;
}
}
}
@Override
public void onResume() {
super.onResume();
if (mShareEmail) {
emailShareImpl();
mShareEmail = false;
}
}
Maybe the following tip is a bit late, but instead of a workaround, if you don't use the activity's state (for example, the permission model should be stateless), you should use commitAllowingStateLoss during fragment transition.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With