Android 權限申請

1、Android權限介紹

應用權限有助於保護對如下數據的訪問和對如下操做的執行,從而爲保護用戶隱私提供支持:java

  • 受限數據,例如系統狀態和用戶的聯繫信息。
  • 受限操做,例如鏈接到已配對的設備並錄製音頻。

1.1 權限分類

  • 安裝時權限

系統會在應用安裝時自動授予應用相應權限,包括普通權限和簽名權限。android

  • 運行時權限

運行時權限也稱爲危險權限,Android 6.0 開始須要在應用中執行權限申請相關代碼,系統會彈出受權框提示框,須要用戶點擊才能夠受權。markdown

  • 特殊權限

Android 6.0 開始須要用戶在應用設置界面中才能開啓權限。ide

基本上每一個版本,權限都會有必定的修改,並且系統對這方面的限制是愈來愈嚴格,因此正確的作法是請求最少數量的權限。oop

官網地址ui

2、權限申請

Android 6.0 版本開始,權限部分有了重大改變,因此下面以Android 6.0 爲分界線,介紹如何申請權限。this

2.1 Android 6.0 如下

無論是普通權限仍是危險權限,只需在 AndroidManifest.xml 清單文件中進行申明便可:spa

<uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
複製代碼

3.2 android 6.0 以上

安裝時只會給普通權限受權,其餘權限須要特殊操做進行申請。code

  • 危險權限:

不只要在清單文件中申明權限,還須要代碼中動態申請權限,系統會彈出對應的權限提示框,用戶點擊贊成才能夠受權。orm

  • 特殊權限

不只要在清單文件中申明權限,還須要在用戶在應用設置界面進行受權。

權限等級能夠經過 官網 進行查詢。

動態申請權限

主要分爲如下幾個步驟:

  1. 判斷當前是否有權限
if (PackageManager.PERMISSION_GRANTED == ActivityCompat
          .checkSelfPermission(context, permission)) {
        //已受權
      } else {
      	//未受權
      }
複製代碼
  1. 進行權限申請
ActivityCompat.requestPermissions(activity, String[] permissions, REQUEST_CODE));
複製代碼
  1. 用戶受權後操做
@Override
  public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

    if (requestCode == REQUEST_CODE) {
      for (int i = 0; i < permissions.length; i++) {
          if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
          //已受權
          } else {
		  //未受權
          }
      }
    }
  }
複製代碼

完整參考代碼以下:

private void requestStoragePermission() {
    List<String> needRequestList = checkPermission(this, PERMISSION_LIST);
    if (needRequestList.isEmpty()) {
      //已受權
    } else {
      //申請權限
      requestPermission(needRequestList);
    }
  }
  private List<String> checkPermission(Context context, String[] checkList) {
    List<String> list = new ArrayList<>();
    for (String s : checkList) {
      if (PackageManager.PERMISSION_GRANTED != ActivityCompat
          .checkSelfPermission(context, s)) {
        list.add(s);
      }
    }
    return list;
  }
  private void requestPermission(List<String> needRequestList) {
    ActivityCompat
        .requestPermissions(activity, needRequestList.toArray(new String[0]),
            REQUEST_CODE));
  }
  @Override
  public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

    if (requestCode == REQUEST_CODE_STORAGE) {
      for (int i = 0; i < permissions.length; i++) {
          if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
          //已受權
          } else {
           //未受權
          }
      }
    }
  }

複製代碼

權限被禁止

若是用戶第一次拒絕權限後,第二次再申請權限時,系統提示框會出現一個再也不詢問的按鈕,以下圖:

權限申請1.png

若是用戶勾選「再也不詢問」,同時點擊拒絕後,至關於權限被禁止了。下次再申請權限,會直接回調權限被拒絕。即 requestPermissions 調用後不會再彈出系統提示框,只能引導用戶去應用設置界面進行受權。 這時候能夠經過 shouldShowRequestPermissionRationale 方法進行判斷。

該方法的本意是,當權限被拒絕後,你能夠提示用戶爲何須要獲取該權限。有下面幾種場景:

  1. 沒有申請權限時,返回false
  2. 申請權限,可是被拒絕了,返回true
  3. 申請權限,可是被用戶禁止了,或者勾選了再也不詢問,返回false
  4. 申請權限,用戶容許了,返回false

主要流程以下:

  1. onRequestPermissionsResult 權限申請回調後,判斷權限是否被用戶禁止。
  2. 引導用戶跳轉到應用設置界面受權。
  3. 因爲受權後返回應用並無任何提示,因此須要從新再判斷權限。
@Override
  public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

    if (requestCode == REQUEST_CODE) {
      for (int i = 0; i < permissions.length; i++) {
          if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
            //用戶已受權
          } else {
            //判斷用戶是否勾選了再也不詢問
            if (VERSION.SDK_INT >= VERSION_CODES.M && !shouldShowRequestPermissionRationale(
                permission.WRITE_EXTERNAL_STORAGE)) {
              //跳轉到應用設置界面受權
              goToSetting();
            }
          }
      }
    }
  }
  /** * 跳轉應用設置界面進行受權 */
  private void goToSetting() {
    Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);

    Uri uri = Uri.fromParts("package", getPackageName(), null);

    intent.setData(uri);
	
    startActivityForResult(intent, REQUEST_CODE_SETTING);
  }

  @Override
  protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_CODE_SETTING) {
      //從設置界面回來,是不知道用戶是否有受權的,因此須要從新再判斷
      List<String> needRequestList = checkPermission(this, PERMISSION_LIST);
      if (needRequestList.isEmpty()) {
        //已受權
      }
    }

  }
複製代碼
相關文章
相關標籤/搜索