拒绝权限时出错,ShowRequestPermissionRationale抛出NullPointerException

时间:2017-02-24 17:46:16

标签: android android-permissions

这是我的Permissions.java文件

public class Permissions {
private Context mContext;
final int READ_COARSE_LOCATION = 20;

public Permissions(Context context) {
    mContext = context;
}

public void checkPermission() {
    ActivityCompat.requestPermissions((Activity) mContext, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, READ_COARSE_LOCATION);
}

public void showMaterialDialog() {
    MaterialDialog dialog;
    MaterialDialog.Builder builder = new MaterialDialog.Builder(this);
    builder.title("Permission needed")
            .content("This Action Requires the Location Setting to be enabled. Go to Settings and check the Location Permission inside the Permissions View")
            .positiveText("SETTINGS")
            .negativeText("CANCEL")
            .onPositive(new MaterialDialog.SingleButtonCallback() {
                @Override
                public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                    final Intent i = new Intent();
                    i.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                    i.addCategory(Intent.CATEGORY_DEFAULT);
                    i.setData(Uri.parse("package:" + getApplicationContext().getPackageName()));
                    i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
                    i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
                    startActivity(i);
                }
            })
            .onNegative(new MaterialDialog.SingleButtonCallback() {
                @Override
                public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                    dialog.dismiss();
                }
            });
    dialog = builder.build();
    dialog.show();
}

public void showDialogOK() {
    MaterialDialog dialog;
    MaterialDialog.Builder builder = new MaterialDialog.Builder(this);
    builder.title("Permission needed")
            .content("This permission is required to access the weather data of your location.")
            .positiveText("OK")
            .onPositive(new MaterialDialog.SingleButtonCallback() {
                @Override
                public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                    dialog.dismiss();
                }
            });
    dialog = builder.build();
    dialog.show();
}

public void permission_denied() {
    // permission was not granted
    // permission is denied (this is the first time, when "never ask again" is not checked) so ask again explaining the usage of permission
    // shouldShowRequestPermissionRationale will return true
    //show the dialog or snackbar saying its necessary and try again otherwise proceed with setup.
    if (ActivityCompat.shouldShowRequestPermissionRationale(this,
            Manifest.permission.ACCESS_COARSE_LOCATION)) {
        showDialogOK();
    } //permission is denied (and never ask again is  checked)
    //shouldShowRequestPermissionRationale will return false
    else {
        showMaterialDialog();
    }
}
}

我从活动中调用的地方(WeatherActivity.java)(案例R.id.location)

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.change_city : showInputDialog();
            break;
        case R.id.about_page : Intent intent = new Intent(WeatherActivity.this, AboutActivity.class);
            startActivity(intent);
            break;
        case R.id.refresh : changeCity(GlobalActivity.cp.getCity());
            break;
        case R.id.location :
            permission = new Permissions(this);
            permission.checkPermission();
            break;
    }
    return true;
}

在我的代码中处理onRequestPermission结果是在下面给出的代码中处理的(属于WeatherActivity.java)(RequestCode 20是我要求的位置权限)

@Override
public void onRequestPermissionsResult(int requestCode,@NonNull String permissions[],@NonNull int[] grantResults) {
    switch (requestCode) {
        case 20: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                showCity();
            } else {
                permission.permission_denied();
            }
            break;
        }
    }
}

问题是,当我点击Deny(没有Don再次询问时)会抛出NullPointer异常,如:

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.pm.PackageManager android.content.Context.getPackageManager()' on a null object reference
                                                                    at android.content.ContextWrapper.getPackageManager(ContextWrapper.java:91)
                                                                    at android.app.Activity.shouldShowRequestPermissionRationale(Activity.java:4167)
                                                                    at android.support.v4.app.ActivityCompatApi23.shouldShowRequestPermissionRationale(ActivityCompatApi23.java:54)
                                                                    at android.support.v4.app.ActivityCompat.shouldShowRequestPermissionRationale(ActivityCompat.java:419)
                                                                    at com.a5corp.weather.permissions.Permissions.permission_denied(Permissions.java:78)
                                                                    at com.a5corp.weather.activity.WeatherActivity.onRequestPermissionsResult(WeatherActivity.java:58)

Permissions.java第78行是if(ActivityCompat.shouldShowRequestPermissionRationale(this,             Manifest.permission.ACCESS_COARSE_LOCATION))

WeatherActivity.java第58行是permission.permission_denied()

但是,当应用程序请求权限时,单击“同意”时没有问题。我的代码运行正常。

1 个答案:

答案 0 :(得分:1)

尝试更改您的permission_denied方法,如下所示:

public void permission_denied() {
    // permission was not granted
    // permission is denied (this is the first time, when "never ask again" is not checked) so ask again explaining the usage of permission
    // shouldShowRequestPermissionRationale will return true
    //show the dialog or snackbar saying its necessary and try again        otherwise proceed with setup.
        if (ActivityCompat.shouldShowRequestPermissionRationale(mContext,
                Manifest.permission.ACCESS_COARSE_LOCATION)) {
            showDialogOK();
        } //permission is denied (and never ask again is  checked)
        //shouldShowRequestPermissionRationale will return false
        else {
            showMaterialDialog();
        }
    }
}

在这里,您将活动实例作为ActivityCompat.shouldShowRequestPermissionRationale中的第一个参数传递,而您需要传递活动的上下文。