Android 6.0以上のダイナミックな複数の権限の申請-最も美しいソリューション

7673 ワード

目次
  • バックグラウンド
  • 危険権限
  • 申請権限構想
  • 申請権限プロセス
  • 乾物
  • 後続
  • 一.背景
    Android 23 APIは新たに危険権限チェックを追加し、手動で取得する必要がある.
    二.危険権限:
        
    android.permission-group.CALENDAR   
    android.permission.READ_CALENDAR
    android.permission.WRITE_CALENDAR
      
    android.permission-group.CAMERA 
    android.permission.CAMERA
       
    android.permission-group.CONTACTS   
    android.permission.READ_CONTACTS
    android.permission.WRITE_CONTACTS
    android.permission.GET_ACCOUNTS
      
    android.permission-group.LOCATION   
    android.permission.ACCESS_FINE_LOCATION
    android.permission.ACCESS_COARSE_LOCATION
       
    android.permission-group.MICROPHONE 
    android.permission.RECORD_AUDIO
      
    android.permission-group.PHONE  
    android.permission.READ_PHONE_STATE
    android.permission.CALL_PHONE
    android.permission.READ_CALL_LOG
    android.permission.WRITE_CALL_LOG
    com.android.voicemail.permission.ADD_VOICEMAIL
    android.permission.USE_SIP
    android.permission.PROCESS_OUTGOING_CALLS
       
    android.permission-group.SENSORS    
    android.permission.BODY_SENSORS
      
    android.permission-group.SMS    
    android.permission.SEND_SMS
    android.permission.RECEIVE_SMS
    android.permission.READ_SMS
    android.permission.RECEIVE_WAP_PUSH
    android.permission.RECEIVE_MMS
    android.permission.READ_CELL_BROADCASTS
      
    android.permission-group.STORAGE    
    android.permission.READ_EXTERNAL_STORAGE
    android.permission.WRITE_EXTERNAL_STORAGE
    

    三.申請権限の考え方
    Android6.0ランタイム権限、関連する方法は主に4つあります:1、権限ContextCompat.が付与されているかどうかをチェックします.checkSelfPermission(mContext,permissions[i])が返す結果はPackageManagerである.PERMISSION_GRANTED(0)は権限付与を表します
    2、要求権限Activity Compat.requestPermissions(WelcomeActivity.this, permissions, 1); 注意:permissionsは配列、単一の権限、new String[]{permission}パラメータ、1はrequestCodeであり、権限コールバックで使用する必要があります.
    3、権限要求後のコールバックpublic void onRequestPermissionsResult(int requestCode,@NonNull String[]permissions,@NonNull int[]grantResults){
    4、ユーザーが権限を拒否するかどうかを判断するdon't ask againオプションをチェックするかどうかを判断し、チェックする場合、お客様が手動で権限を開く必要がある場合Activity Compat.shouldShowRequestPermissionRationale(WelcomeActivity.this, permissions[i])
    注意:Activity Compat.shouldShowRequestPermissionRationale(activity,permission)この方法は、ユーザーが権限を拒否した後にtrueを返すことです.すなわち,ユーザが権限を必要とする場所を初めてクリックし,false(ユーザが拒否していないため~)を返し,ユーザがその権限を拒否すると,次回この権限をクリックするとtrueを返す.trueの場合、ダイアログボックスにその権限の説明が表示され、ユーザーに権限を再申請するかどうかを選択させます.ユーザーが権限を拒否してdon't ask againオプションをチェックするとfalseに戻り、Activity Compat.requestPermissionsダイアログボックスはポップアップされず、システムは直接denyし、onRequestPermissionsResultメソッドを実行します.
    5、総括1、申請する権限の状態を検査し、授権されていないものを単独で集合に保存する.②、集合が空で、トップページ(すべて権限が付与されている)に入り、空ではなく、権限を要求する.③、ユーザーが拒否した場合、don't ask againをチェックしているかどうかを判断し、チェックしていないので、権限を再申請し、チェックして、歓迎インタフェースをスキップして、メインインタフェースに入る.
    四.購買依頼権限プロセス
    A、実际のプロジェクトでは、开発の便利さのために、ウェルカムインタフェースで、よく使う権限を一度に申请し、一般的にメモリカードの书き込み、位置付けなどの権限を申请します.申請権限には、①直接権限ボックスをポップアップし、操作を許可または禁止する②携帯電話の特定のページに設定する2種類があります.B、ある具体的な操作の時(例えば:浮遊窓の権限)に単独で権限判断を行う.C、具体的な操作権限申請プロセス:①、要求権限;②、要求コールバックで、ユーザーが拒否した場合、don't ask againをチェックしているかどうかを判断し、チェックしていないので、権限を再申請し、チェックして、設定インタフェースにジャンプします.
    五、乾物
            
    private  boolean mShowRequestPermission = true;
    
          --            
     private void init_permission() {
          if (getSdkVersionSix()) {
              String[] permissions = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_PHONE_STATE, Manifest.permission.RECORD_AUDIO};
              List mPermissionList = new ArrayList<>();
              for (int i = 0; i < permissions.length; i++) {
                  if (ContextCompat.checkSelfPermission(LogInAct.this, permissions[i]) != PackageManager.PERMISSION_GRANTED) {
                      mPermissionList.add(permissions[i]);
                  }
              }
    
              if (mPermissionList.isEmpty()) {//     
                  mShowRequestPermission = true;
              } else {//        
                  String[] permissionsArr = mPermissionList.toArray(new String[mPermissionList.size()]);
                  ActivityCompat.requestPermissions(LogInAct.this, permissionsArr, 101);
              }
          }
      }
    
          ,              ,          ,  ,      。
               。           ,            ,
    
     @Override
      public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
          super.onRequestPermissionsResult(requestCode, permissions, grantResults);
          switch (requestCode) {
              case 101:
                  for (int i = 0; i < grantResults.length; i++) {
                      if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
                          //             
                          boolean showRequestPermission = ActivityCompat.shouldShowRequestPermissionRationale(LogInAct.this, permissions[i]);
                          if (showRequestPermission) {
                              init_permission();
                              return;
                          } else { // false     ,    
                              mShowRequestPermission = false;//     
                          }
                      }
                  }
                  break;
          }
      }
    
              ,                   “   ”   
     1.     6.0     
     2.        ,    ,             ,    onActivityResult           
                     ,                       getRequestPermission()  ,          
                            
    
       if (getSdkVersionSix()) {
                  if (Settings.canDrawOverlays(LogInAct.this)) {
                      if (getRequestPermission().equals("1")) { //     1   
                          init_IntentLogIn(getAccount(), getPwd());
                      }
                  } else {
                      Toast.makeText(this, R.string.login_canDrawOverlays,   Toast.LENGTH_SHORT).show();
                      Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
                      startActivityForResult(intent, 2);
                  }
              } else {
                  init_IntentLogIn(getAccount(), getPwd()); // 6.0      
       }
    
        SDK   6.0  
      public boolean getSdkVersionSix() {
          return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
      }
      
                   
      @RequiresApi(api = Build.VERSION_CODES.M)
      @Override
      protected void onActivityResult(int requestCode, int resultCode, Intent data) {
          super.onActivityResult(requestCode, resultCode, data);
          if (requestCode == 2) {
              if (Settings.canDrawOverlays(LogInAct.this)) {
                  init_permission();
              } else {
                  Toast.makeText(this, R.string.login_canDrawOverlays, Toast.LENGTH_SHORT).show();
              }
          } else if (requestCode == 3) {
              init_permission();
          }
      }
    
              
       public String getRequestPermission() {
          if (mShowRequestPermission) {
              return "1";
          } else {//                 ,           
              Toast.makeText(this, R.string.login_permission, Toast.LENGTH_SHORT).show();
              Intent intent = new Intent(Settings.ACTION_APPLICATION_SETTINGS);
              startActivityForResult(intent, 3);
              return "-1";
          }
      }
    
    

    六、後続
    ツールクラスがすでに出ています.コード転送ゲート
    七、リモート依存
    1.gradle
    
    allprojects {
            repositories {
                ...
                maven { url 'https://jitpack.io' }
            }
        }
    
    dependencies {
                implementation 'com.github.stf-android:Permissions:-SNAPSHOT'
        }
    

    2.maven
        
            
                jitpack.io
                https://jitpack.io
            
        
    
         
            com.github.stf-android
            Permissions
            -SNAPSHOT