Android Marshmallow:在运行时更改权限会导致应用崩溃

时间:2016-05-11 10:52:23

标签: android android-6.0-marshmallow android-permissions

Marshmallow重新设计了获取权限。所以在调用需要权限的方法之前处理权限并且它工作正常,但它在以下场景中崩溃:

第1步:打开应用并提供所有必要的权限

第2步:点击主页按钮(所以应用程序在后台)

步骤3:手动更改设置

中的权限

第4步:从多任务启动应用程序,现在因应用程序上下文无效而崩溃

观察到应用再次创建,不明白为什么会发生这种情况。任何纠正这个问题的建议都会受到欢迎!

3 个答案:

答案 0 :(得分:1)

这是因为Marshmallow添加了额外的功能。您需要在运行时向用户请求。为此我使用了这个课程。然后在需要的时候使用它

public class AppPermission {

    public static boolean isMarshmallowPlusDevice() {
        return Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1;
    }

    @TargetApi(Build.VERSION_CODES.M)
    public static boolean isPermissionRequestRequired(Activity activity, @NonNull String[] permissions, int requestCode) {
        if (isMarshmallowPlusDevice() && permissions.length > 0) {
            List<String> newPermissionList = new ArrayList<>();
            for (String permission : permissions) {
                if (PackageManager.PERMISSION_GRANTED != activity.checkSelfPermission(permission)) {
                    newPermissionList.add(permission);
                }
            }
            if (newPermissionList.size() > 0) {
                activity.requestPermissions(newPermissionList.toArray(new String[newPermissionList.size()]), requestCode);
                return true;
            }
        }
        return false;
    }
}

然后将此代码放在需要用户许可的地方。

if (!AppPermission.isPermissionRequestRequired(SignInActivity.this, new String[]{"android.permission.GET_ACCOUNTS"},
        REQUEST_APP_PERMISSION)) {
    // Your code if permission available
}

在此之后,在FragmentActivity中输入此代码 -

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode) {
        case REQUEST_APP_PERMISSION:
            for (int i = 0; i < permissions.length; i++) {
                String permission = permissions[i];
                int grantResult = grantResults[i];
                switch (permission) {
                    case "android.permission.GET_ACCOUNTS":
                        if (PackageManager.PERMISSION_GRANTED == grantResult) {
                            // Your code
                        }
                        break;
                }
            }
            break;
    }
}

以上代码适用于GET_ACCOUNTS的请求权限,您可以将其更改为所需的任何内容。

答案 1 :(得分:0)

  

观察到应用再次创建,不明白为什么会这样   发生。任何纠正这个问题的建议都会受到欢迎!

因为权限更改时,应用程序“状态”应该无效。正确的方法是破坏根上下文,即应用程序本身。

每次查询需要这些权限的API方法时,都必须检查授予权限的权限。你不能依赖一些SharedPreferences标志,表明“用户在入职时授予了权限,好吧,让我们玩得开心”。在这方面让你的应用程序无国籍。

例如,您可以创建一些BaseActivity / BaseFragment或Utility,并在其中移动所有检查逻辑。

答案 2 :(得分:0)

首先定义一个布尔值

 private boolean isPermissionGranted = false;

然后检查是否授予了权限:

if (!isPermissionGranted) {
        checkPermission();
    }

运行时权限检查的实际代码如下:

private void checkPermission() {
    int hasPermission = ContextCompat.checkSelfPermission(UserProfile.this, Manifest.permission.CAMERA);
    int hasWritePermission = ContextCompat.checkSelfPermission(UserProfile.this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
    if (hasPermission != PackageManager.PERMISSION_GRANTED && hasWritePermission != PackageManager.PERMISSION_GRANTED) {
        if (!ActivityCompat.shouldShowRequestPermissionRationale(UserProfile.this, Manifest.permission.CAMERA) && !ActivityCompat.shouldShowRequestPermissionRationale(UserProfile.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
            showMessage(getString(R.string.allow_access_to_camera_external_storage),
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            ActivityCompat.requestPermissions(UserProfile.this, new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE},
                                    REQUEST_CODE_ASK_PERMISSIONS);
                        }
                    });
            return;
        }
        ActivityCompat.requestPermissions(UserProfile.this, new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE},
                REQUEST_CODE_ASK_PERMISSIONS);
        return;
    } else {
        isPermissionGranted = true;
    }
}

private void showMessage(String message, DialogInterface.OnClickListener       listener) {
    new AlertDialog.Builder(UserProfile.this)
            .setMessage(message)
            .setPositiveButton(R.string.ok, listener)
            .setNegativeButton(R.string.cancel, null)
            .create()
            .show();
}

  @Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    switch (requestCode) {
        case REQUEST_CODE_ASK_PERMISSIONS:
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                isPermissionGranted = true;

            } else {
                isPermissionGranted = false;
                Toast.makeText(UserProfile.this, R.string.permission_denied, Toast.LENGTH_SHORT)
                        .show();
            }
            break;

        default:
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
}

您可以从上面的代码中参考并在您的应用程序中实现它。