在6.0中須要動態獲取權限,而在動態獲取權限的時候,默認提示框包含不在提示按鈕,一旦用戶勾選了不在提示,那麼默認的系統提示框就不會再出現,所以咱們須要自定義系統提示框。ide
在Api 23中, 權限須要動態獲取, 核心權限必須知足. 標準流程:
工具
下面咱們以讀取文件權限爲例,演示對動態權限獲取的解決方案.ui
1 、 權限檢測工具this
public class PermissionHelper { private Context mContext; public static final String PACKAGE = "package:"; public PermissionHelper(Context context) { this.mContext = context; } /** * 判斷權限集合 * * @param permissions 檢測權限的集合 * @return 權限已所有獲取返回true,未所有獲取返回false */ public boolean checkPermissions(String... permissions) { for (String permission : permissions) { if (!checkPermission(permission)) { return false; } } return true; } /** * 判斷權限是否獲取 * * @param permission 權限名稱 * @return 已受權返回true,未受權返回false */ public boolean checkPermission(String permission) { return ContextCompat.checkSelfPermission(mContext, permission) == PackageManager.PERMISSION_GRANTED; } /** * 獲取權限 * * @param resultCode * @return */ public void permissionsCheck(String permission, int resultCode) { // 注意這裏要使用shouldShowRequestPermissionRationale而不要使用requestPermission方法 // 由於requestPermissions方法會顯示不在詢問按鈕 if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) mContext, permission)) { //若是用戶之前拒絕過改權限申請,則給用戶提示 showMissingPermissionDialog(); } else { //進行權限請求 ActivityCompat.requestPermissions((Activity) mContext, new String[]{permission}, resultCode); } // ActivityCompat.requestPermissions((Activity) mContext, new String[]{permission},resultCode); } // 顯示缺失權限提示 private void showMissingPermissionDialog() { AlertDialog.Builder builder = new AlertDialog.Builder(mContext); final AlertDialog alertDialog = builder.create(); builder.setMessage("當前應用缺乏必要權限。\n\n請點擊\"設置\"-\"權限\"-打開所需權限。\n\n最後點擊兩次後退按鈕,便可返回。"); // 拒絕, 退出應用 builder.setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { alertDialog.dismiss(); } }); builder.setPositiveButton("設置", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { startAppSettings(); } }); builder.show(); } // 啓動應用的設置 public void startAppSettings() { Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); intent.setData(Uri.parse( PACKAGE + mContext.getPackageName())); mContext.startActivity(intent); } }
二、主界面
假設進入主界面的時候須要獲取到文件訪問權限,獲取成功的話,進入另外一個Activity,在onResume()方法中判斷獲取權限狀態。.net
public class MainActivity extends AppCompatActivity { //返回值 private static final int WRITE_RESULT_CODE = 12; //權限名稱 private static final String WRITE_PERMISSION = Manifest.permission.WRITE_EXTERNAL_STORAGE; //權限檢測類 private PermissionHelper mPermissionHelper; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mPermissionHelper = new PermissionHelper(this); } @Override protected void onResume() { super.onResume(); //判斷權限受權狀態 boolean b = mPermissionHelper.checkPermission(WRITE_PERMISSION); //若是沒有獲取到權限,則嘗試獲取權限 if (!b){ mPermissionHelper.permissionsCheck(WRITE_PERMISSION,WRITE_RESULT_CODE); }else{ //若是請求成功,則進行相應的操做,好比咱們這裏打開一個新的Activity Intent intent = new Intent(MainActivity.this,PermissionActivity.class); startActivity(intent); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); switch(requestCode){ case WRITE_RESULT_CODE: if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { //若是請求成功,則進行相應的操做,好比咱們這裏打開一個新的Activity Intent intent = new Intent(MainActivity.this,PermissionActivity.class); startActivity(intent); } else { //若是請求失敗 mPermissionHelper.startAppSettings(); } break; } } }