美文网首页
Android 6.0 运行时权限处理解析

Android 6.0 运行时权限处理解析

作者: 如愿以偿丶 | 来源:发表于2019-09-29 21:02 被阅读0次

    1.概述

      大家有没有遇到过这种情况,开发app的时候发现自己手机选择照片是正常的,测试的时候他那边的一台手机怎么搞都不行,然后查看版本之后才发现是6.0的手机。

      在Google发出Android 6.0版本以后,对权限这边做了很大的变动,其中之一就是权限处理。那么在6.0及以上版本我们的危险权限都需要在运行的时候去申请,之前都是在清单文件中配置即可,现在就不行了需要用代码动态申请。不然程序在执行时没有相应的权限就会无响应甚至导致APP崩溃。


    2.权限分类及区别

    Google对于Android 6.0 系统权限分为两类:
      1.Normal Permission(普通权限):这类权限一般不涉及用户隐私,是不需要用户进行授权的,比如访问网络,访问WIFI,访问蓝牙等权限;
      看一些普通权限:

    android.permission.ACCESS LOCATIONEXTRA_COMMANDS 
    android.permission.ACCESS NETWORKSTATE 
    android.permission.ACCESS NOTIFICATIONPOLICY 
    android.permission.ACCESS WIFISTATE 
    android.permission.ACCESS WIMAXSTATE 
    android.permission.BLUETOOTH 
    android.permission.BLUETOOTH_ADMIN 
    android.permission.BROADCAST_STICKY 
    android.permission.CHANGE NETWORKSTATE 
    android.permission.CHANGE WIFIMULTICAST_STATE 
    android.permission.CHANGE WIFISTATE 
    android.permission.CHANGE WIMAXSTATE 
    android.permission.DISABLE_KEYGUARD 
    android.permission.EXPAND STATUSBAR 
    android.permission.FLASHLIGHT 
    android.permission.GET_ACCOUNTS 
    android.permission.GET PACKAGESIZE 
    android.permission.INTERNET 
    android.permission.KILL BACKGROUNDPROCESSES 
    android.permission.MODIFY AUDIOSETTINGS 
    android.permission.NFC 
    android.permission.READ SYNCSETTINGS 
    android.permission.READ SYNCSTATS 
    android.permission.RECEIVE BOOTCOMPLETED 
    android.permission.REORDER_TASKS 
    android.permission.REQUEST INSTALLPACKAGES 
    android.permission.SET TIMEZONE 
    android.permission.SET_WALLPAPER 
    android.permission.SET WALLPAPERHINTS 
    android.permission.SUBSCRIBED FEEDSREAD 
    android.permission.TRANSMIT_IR 
    android.permission.USE_FINGERPRINT 
    android.permission.VIBRATE 
    android.permission.WAKE_LOCK 
    android.permission.WRITE SYNCSETTINGS 
    

      2.Dangerous Permission(危险权限):这类权限一般是涉及到用户的安全和隐私问题,需要用户进行授权,比如读取SD卡,访问相册,拨打电话等权限。
      看几组危险权限:

      SMS(短信)
            SEND_SMS
            RECEIVE_SMS
            READ_SMS
            RECEIVE_WAP_PUSH
            RECEIVE_MMS
      STORAGE(存储卡)
            READ_EXTERNAL_STORAGE
            WRITE_EXTERNAL_STORAGE
      CONTACTS(联系人)
            READ_CONTACTS
            WRITE_CONTACTS
            GET_ACCOUNTS
      PHONE(手机)
            READ_PHONE_STATE
            READ_CALL_LOG
            WRITE_CALL_LOG
            CALL_PHONE
            ADD_VOICEMAIL
            USE_SIP
            PROCESS_OUTGOING_CALLS
      CALENDAR(日历)
            READ_CALENDAR
            WRITE_CALENDAR
      CAMERA(相机)
            CAMERA
      LOCATION(位置)
            ACCESS_FINE_LOCATION
            ACCESS_COARSE_LOCATION
      SENSORS(传感器)
            BODY_SENSORS
      MICROPHONE(麦克风)
            RECORD_AUDIO
    

    普通权限和危险权限的区别:

    • 普通权限:单条权限,可以直接在Manifests文件中进行注册从而获取权限,在程序初次安装启动时直接获取用户权限
    • 危险权限:成组授予,当授予一组中任何一个权限时,该组内其他的权限也会自动被授予。不仅需要在Manifests文件中进行注册还要在代码中进行动态申请。

    3.代码变化过程

    3.1.6.0之前是这样写(已电话拨打为例):

        Intent intent = new Intent(Intent.ACTION_CALL);
        Uri data = Uri.parse("tel:" + mPhone);
        intent.setData(data);
        startActivity(intent);
    

    3.2.6.0以后就不行啦,我们需要去检测该权限有没有被用户授予过,如果没有则需要申请打电话权限,如果有授予过可以直接拨打电话。
      ContextCompat.checkSelfPermission:检测权限
      ActivityCompat.requestPermissions:申请权限

       /**
         * 1.ContextCompat.checkSelfPermission 检查权限
         * 2.方法返回值有两种:
         *      PackageManager.PERMISSION_GRANTED   有该权限
         *      PackageManager.PERMISSION_DENIED    没有该权限
         */
        if(ContextCompat.checkSelfPermission(this,Manifest.permission.CALL_PHONE)
                != PackageManager.PERMISSION_GRANTED){
            /**
             * ActivityCompat.requestPermissions 申请权限
             *  参数1:Context , 
             *  参数2:用户需要申请的权限字符串数组,
             *  参数3:是请求码 主要用来处理用户选择后的返回结果 onRequestPermissionsResult返回会掉方法
             */
            ActivityCompat.requestPermissions(this,new String[]{"Manifest.permission.CALL_PHONE"},CALL_PHONE_REQUEST_CODE);
        }else {
            // 有该权限,直接打电话
            Intent intent = new Intent(Intent.ACTION_CALL);
            Uri data = Uri.parse("tel:" + mPhone);
            intent.setData(data);
            startActivity(intent);
        }
    

    3.3. 回调处理:如果用户同意或是拒绝那么会回调onRequestPermissionsResult(),注意:不是onActivityResult()

      @Override
      public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
          if(requestCode == CALL_PHONE_REQUEST_CODE){
            if (grantResults !=null&&grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // 用户授予了权限
                Intent intent = new Intent(Intent.ACTION_CALL);
                Uri data = Uri.parse("tel:" + mPhone);
                intent.setData(data);
                startActivity(intent);
            } else {
                //用户拒绝了权限
                  Toast.makeText(this,"权限被您拒绝了",Toast.LENGTH_SHORT).show();
              }
          }
      }
    

    4.简单事例:

    public class TextActivity extends AppCompatActivity {
          // 打电话权限申请的请求码
          private static final int CALL_PHONE_REQUEST_CODE = 0x0011;
    
          @Override
          protected void onCreate(Bundle savedInstanceState) {
               super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_text);
          }
         
         /**
          * 检察权限
          */    
          public void phoneClick(View view) {
               if (ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE)
                != PackageManager.PERMISSION_GRANTED) {
               Toast.makeText(this, "申请权限", Toast.LENGTH_SHORT).show();
               ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.CALL_PHONE}, CALL_PHONE_REQUEST_CODE);
              } else {
                callPhone();
              }
          }
    
          /**
           * 拨打电话
           **/
          private void callPhone() {
              Intent intent = new Intent(Intent.ACTION_CALL);
              Uri data = Uri.parse("tel:130****7927");
              intent.setData(data);
              startActivity(intent);
          }
    
          @Override
          public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
              super.onRequestPermissionsResult(requestCode, permissions, grantResults);
              if(requestCode == CALL_PHONE_REQUEST_CODE){
                  if (grantResults !=null&&grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                      // 授予权限
                      callPhone();
                  } else {
                      // 拒绝权限
                      Toast.makeText(this,"权限被您拒绝了",Toast.LENGTH_SHORT).show();
                  }
              }
          }
      }
    

    相关文章

      网友评论

          本文标题:Android 6.0 运行时权限处理解析

          本文链接:https://www.haomeiwen.com/subject/yqmzyctx.html