onRequestPermissionsResult导致失败交付结果

时间:2017-10-03 06:34:08

标签: android

我正在尝试在我添加到活动的Fragment中请求位置权限。我在我的活动中处理@override onRequestPermissionsResult然后我尝试通过调用来关闭我的片段:

我创建了一个片段,用于在我的活动的onCreate中显示和请求权限:

    public class HomeActivity extends BaseTabBarActivity {
private static final int ACCESS_LOCATION = 1;
private ActivityHomeBinding binding;

PermissionFragment permissionFragment;
FragmentManager fragmentManager;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    permissionFragment = new PermissionFragment();
    fragmentManager = getSupportFragmentManager();

    binding = DataBindingUtil.setContentView(this, R.layout.activity_home);
    Account account = new Account();

    binding.setAccount(account);

    if (!checkLocationPermission()) {
        permissionFragment.show(fragmentManager, "Permission Dialog");
    }
}

然后我在我的片段中请求权限,如下所示:

    @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    binding = DataBindingUtil.inflate(inflater, R.layout.fragment_permission, container, false);
    binding.setPermissionType(PermissionType.LOCATION);
    binding.btnProceed.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if (binding.getPermissionType().equals(PermissionType.LOCATION)) {
                if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(getActivity(), new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, ACCESS_LOCATION);
                    return;
                }
                closePermissionDialog();
            } else {
                Intent callGPSSettingIntent = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                startActivity(callGPSSettingIntent);
            }
        }
    });

然后当我从权限请求返回时:

  public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    if (requestCode == ACCESS_LOCATION) {
        if (permissions[0].equals(Manifest.permission.ACCESS_FINE_LOCATION)
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            permissionFragment.dismiss();
        } else {
            permissionFragment.binding.setPermissionType(PermissionFragment.PermissionType.LOCATION_DENIED);
        }
    }
}

导致错误的代码在片段中,并且是这种方法:

    public void closePermissionDialog() {
    FragmentManager fm = getFragmentManager();
    FragmentTransaction ft = fm.beginTransaction();
    ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE);
    ft.detach(this);
    ft.commitAllowingStateLoss();
}

当尝试提交此事务时,它会在保存Activity的onSaveInstanceState之后发生,根据Android文档导致我的错误:

"事务只能在其包含活动保存其状态之前使用此方法提交。如果在该点之后尝试提交,则将引发异常。这是因为如果活动需要从其状态恢复,则提交后的状态可能会丢失。请参阅commitAllowingStateLoss()以了解可能丢失提交的情况。" - 此页面上的Android Google文档:https://developer.android.com/reference/android/app/FragmentTransaction.html#commit()

根除防止这种活动周期流动的最佳策略是什么?我显然没有采取任何正确的方法来处理活动和片段之间的流程。

我收到以下错误:

  java.lang.RuntimeException: Failure delivering result ResultInfo{who=@android:requestPermissions:, request=1, result=-1, data=Intent { act=android.content.pm.action.REQUEST_PERMISSIONS (has extras) }} to activity {.android/.activities.HomeActivity}: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
                                                                           at android.app.ActivityThread.deliverResults(ActivityThread.java:3699)
                                                                           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)
                                                                        Caused by: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
                                                                           at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:2044)
                                                                           at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:2067)
                                                                           at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:680)
                                                                           at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:634)
                                                                           at android.support.v4.app.DialogFragment.dismissInternal(DialogFragment.java:205)
                                                                           at android.support.v4.app.DialogFragment.dismiss(DialogFragment.java:171)
                                                                           at com.activities.HomeActivity.onRequestPermissionsResult(HomeActivity.java:92)
                                                                           at android.app.Activity.dispatchRequestPermissionsResult(Activity.java:6582)
                                                                           at android.app.Activity.dispatchActivityResult(Activity.java:6460)
                                                                           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) 

1 个答案:

答案 0 :(得分:0)

所以我使用ActivityCompat.requestPermissions移动了检查权限,这总是导致onSaveInstanceState回调在被调用的事件被调用之前被调用的活动,使用Fragment的requestPermission保证在我的Activity:

上调用onSaveInstance状态之前,我不在片段事务中
        binding.btnProceed.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if (binding.getPermissionType().equals(PermissionType.LOCATION)) {
                if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                    requestPermissions(new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, ACCESS_LOCATION);
                    return;
                }
                closePermissionDialog();
            } else {
                Intent callGPSSettingIntent = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                startActivity(callGPSSettingIntent);
            }
        }
    });