用户在运行时权限对话框中单击拒绝时显示DialogFragment

时间:2015-10-17 02:01:20

标签: android android-dialogfragment android-6.0-marshmallow

我正在尝试在用户在android 6的“允许/拒绝权限”对话框上单击“拒绝”后显示DialogFragment但是我收到此错误:

    Caused by: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
  at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1448)
  at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1466)
  at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:634)
  at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:613)
  at android.support.v4.app.DialogFragment.show(DialogFragment.java:139)
  at android.support.v4.app.FragmentActivity.onRequestPermissionsResult(FragmentActivity.java:802)
  at android.app.Activity.dispatchRequestPermissionsResult(Activity.java:6553)
  at android.app.Activity.dispatchActivityResult(Activity.java:6432)
  at android.app.ActivityThread.deliverResults(ActivityThread.java:3695)
  at android.app.ActivityThread.handleSendResult(ActivityThread.java:3742) 
  at android.app.ActivityThread.-wrap16(ActivityThread.java) 
  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1393) 
  at android.os.Handler.dispatchMessage(Handler.java:102) 
  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) 

我的对话框代码很标准

  protected void showDialog(DialogFragment diag)
    {
        if (diag != null && !diag.isAdded())
            diag.show(getSupportFragmentManager(), "dialog");
    }

如何解决这个问题?

3 个答案:

答案 0 :(得分:1)

所以,有几个解决方案,没有特别漂亮。这意味着您的Activity的FragmentManager尚未处于以安全方式提交FragmentTransactions的有效状态(尽管在这种特殊情况下,它应该始终是。)

1)使用$IFS代替.commitAllowingStateLoss()

这是最简单的解决方法,虽然我不完全清楚不使用.show()方法产生的差异,这些方法在内部设置了一些标志。似乎工作正常。

.show()

1)将getSupportFragmentManager() .beginTransaction() .add(diag, "dialog") .commitAllowingStateLoss(); 作为.show()发布在Runnable上:

Handler

2)设置一个标志并在onResume()

中显示对话框
// Initialize a Handler ahead of time and keep it around
private Handler mHandler = new Handler();

...

// after getting denied:
mHandler.post(new Runnable() {
    @Override
    public void run() {
        // Show your dialog
    }
}

...

@Override
protected void onStop() {
    super.onStop();

    // Clear out the Runnable for an unlikely edge case where your
    // Activity goes to stopped state before the Runnable executes
    mHandler.removeCallbacksAndMessages(null);
}

答案 1 :(得分:0)

我还想添加一些我刚发现的东西。如果我使用ng-selected切换现有代码上的getSupportFragmentManager(),则可以正常使用。代码

getSupportFragmentManager().beginTransaction()

不知道为什么这会像我想的那样有效。

答案 2 :(得分:-1)

在用户点击拒绝后显示对话框并不是指南所说的。您应该在第二个请求之前显示权限rational。您可以在此处查看自动管理:Permission library