2017-02-24 125 views
-1

这里是我的Permissions.java文件错误的ShowRequestPermissionRationale引发NullPointerException异常

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; 
     } 
    } 
} 

问题是,当我打拒绝(不再次选择不要问)抛出一个空指针异常,如:

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,如果(ActivityCompat.shouldShowRequestPermissionRationale(这一点, 清单.permission.ACCESS_COARSE_LOCATION))

WeatherActivity.java线58 permission.permission_denied()

但是有当我点击,当应用程序请求许可同意就没问题。然后我的一段代码正常运行。

+1

**从不**创建框架类的随机子类,如'Activity'。当你需要一个'Context'的东西时,使用一个框架交给你的东西。而且,特别是为了处理运行时权限,'shouldShowRequestPermissionRationale()'需要使用一个实际的'Activity'来调用,它在清单中注册,由Android启动,并且已经通过了'onCreate()'方法。 – CommonsWare

+0

@CommonsWare所以你的意思是说不要创建一个特定的Permissions类?如果是,如果我需要从另一个活动读取权限,该怎么办?我不需要重新编写所有这些东西吗? – Sparker0i

+0

为什么我甚至在我的问题上得到一个赞成票? – Sparker0i

回答

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第一参数,而不是你需要通过你的活动范围内。

+0

我会尽力,然后回复 – Sparker0i

+0

这工作。谢谢 – Sparker0i

相关问题