1

I am trying to get permissions for reading calendar, after getting the permissions I am trying to call another fragment. I am stuck with the following exception.This happens for the first launch of the application only.For the next launch application works fine.

5488-5488/com.mindtree.calenderevents E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.mindtree.calenderevents, PID: 5488
java.lang.RuntimeException: Failure delivering result ResultInfo{who=@android:requestPermissions:, request=2, result=-1, data=Intent { act=android.content.pm.action.REQUEST_PERMISSIONS (has extras) }} to activity {com.mindtree.calenderevents/com.mindtree.calenderevents.MainActivity}: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
   at android.app.ActivityThread.deliverResults(ActivityThread.java:4998)
   at android.app.ActivityThread.handleSendResult(ActivityThread.java:5041)
   at android.app.ActivityThread.access$1600(ActivityThread.java:229)
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1875)
   at android.os.Handler.dispatchMessage(Handler.java:102)
   at android.os.Looper.loop(Looper.java:148)
   at android.app.ActivityThread.main(ActivityThread.java:7325)
   at java.lang.reflect.Method.invoke(Native Method)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
Caused by: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
   at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1533)
   at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1551)
   at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:696)
   at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:662)
   at com.mindtree.calenderevents.MainActivity.onRequestPermissionsResult(MainActivity.java:59)
   at android.app.Activity.dispatchRequestPermissionsResult(Activity.java:7291)
   at android.app.Activity.dispatchActivityResult(Activity.java:7169)
   at android.app.ActivityThread.deliverResults(ActivityThread.java:4994)
   at android.app.ActivityThread.handleSendResult(ActivityThread.java:5041) 
   at android.app.ActivityThread.access$1600(ActivityThread.java:229) 
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1875) 
   at android.os.Handler.dispatchMessage(Handler.java:102) 
   at android.os.Looper.loop(Looper.java:148) 
   at android.app.ActivityThread.main(ActivityThread.java:7325) 
   at java.lang.reflect.Method.invoke(Native Method) 
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230) 
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120) 

This is my code

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
        TopSectionFragment fragment = TopSectionFragment.newInstance();
    getSupportFragmentManager().beginTransaction().replace(R.id.fragment, fragment)
            .commit();

}

@Override
public void getEvents() {
    Log.i("mainacteventmethod ","mainacteventmethod");
    //TODO: implement method to fetch events from calendar and add as fragment arguments
    getPermissionToReadCalender();

}

@Override
public void onRequestPermissionsResult(int requestCode,
                                       @NonNull String permissions[], @NonNull int[] grantResults) {
    switch (requestCode) {
        case READ_CALENDER: {

            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // permission was granted, yay! Do the
                // contacts-related task you need to do.
                RuntimeData.setsCalendarData(getCalender(null));
                if (RuntimeData.getsCalendarData() != null) {
                    BottomSectionFragment bottomFragment = new BottomSectionFragment();
                    getSupportFragmentManager().beginTransaction().replace(R.id.fragment2,
                            bottomFragment).commit();
                }

            } else {
                // permission denied, boo! Disable the
                // functionality that depends on this permission.
            }
            return;
        }
        // other 'case' lines to check for other
        // permissions this app might request
    }
}

private void getPermissionToReadCalender() {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CALENDAR) != PackageManager.PERMISSION_GRANTED) {

        if (shouldShowRequestPermissionRationale(
                Manifest.permission.READ_CALENDAR)) {
        }
        requestPermissions(new String[]{Manifest.permission.READ_CALENDAR},
                READ_CALENDER);

    }else{
        RuntimeData.setsCalendarData(getCalender(null));
        if (RuntimeData.getsCalendarData() != null) {
            BottomSectionFragment bottomFragment = new BottomSectionFragment();
            getSupportFragmentManager().beginTransaction().replace(R.id.fragment2,
                    bottomFragment).commit();
        }
    }

}
Ajay S
  • 48,003
  • 27
  • 91
  • 111
yacky
  • 313
  • 1
  • 6
  • 19

1 Answers1

6

This exception occurs if you try to perform a fragment transition after your fragment activity's onSaveInstanceState() gets called.

To test if this is the case here, override onSaveInstanceState() so it doesn't call the super method.

@Override
protected void onSaveInstanceState(Bundle outState) {
    //No call for super(). 
}

If this fixes the problem, instead of commit() on your fragment manager, use commitAllowingStateLoss();

Shadesblade
  • 782
  • 5
  • 5
  • 4
    Note that one of the main reasons this happens, is if you have an AsyncTask (or Thread) running when an activity gets stopped. Make sure you handle onSavedInstanceState() correctly in this case – Shadesblade Oct 26 '16 at 17:02
  • [I checked this answe](https://stackoverflow.com/a/32272180/9053942) and [this answer](https://stackoverflow.com/a/43777241/9053942), so you need to save some variables in onSaveInstanceState(), restore them on onViewStateRestored(), maybe set a flag in onRequestPermissionsResult() but don't start bottomFragment here, and finally, inside onResume(), you start the bottomFragment. Answer is disabled so I am writing this comment. – Qazi Fahim Farhan Jul 05 '21 at 12:11