美文网首页
Android 6.0(M) 最佳适配方案

Android 6.0(M) 最佳适配方案

作者: 抬头仰望放肆的微笑v | 来源:发表于2019-10-11 11:25 被阅读0次

    Android 6.0的新特性之一就是动态权限管理.在6.0之前,在应用安装的时候,提示用户所需要用到的权限列表,同意之后安装,该app就被赋予所有的权限,我们暂且称它为安装时权限,安装后,被赋予的权限也无法取消;在6.0之后,google对权限进行了运行时的管理,而不是在安装时候,危险权限需要在运行时申请,我们暂且称它为运行时权限,非危险权限,在安装时由用户授予,这样简化了应用安装过程,因为用户在安装或更新应用时不需要授予权限,也给予了用户对app功能更多的控制.

    系统权限主要分为两类,正常权限和危险权限

    正常权限不会直接危及用户的隐私,如果你的应用在它的Manifest中列出了正常权限,系统会自动授予权限

    危险权限可以让app访问用户的机密数据,如果你的应用在它的Manifest列出了危险权限,用户必须明确批准你的app使用该权限

    危险权限分组说明

    权限组 权限名称
    CALENDAR android.permission.READ_CALENDAR
    android.permission.WRITE_CALENDAR
    CAMERA android.permission.CAMERA
    CONTACTS android.permission.READ_CONTACTS
    android.permission.WRITE_CONTACTS
    android.permission.GET_ACCOUNTS
    LOCATION android.permission.ACCESS_FINE_LOCATION
    android.permission.ACCESS_COARSE_LOCATION
    MICROPHONE android.permission.RECORD_AUDIO
    PHONE android.permission.READ_PHONE_STATE
    android.permission.CALL_PHONE
    android.permission.READ_CALL_LOG
    android.permission.ADD_VOICEMAIL
    android.permission.WRITE_CALL_LOG
    android.permission.USE_SIP
    android.permission.PROCESS_OUTGOING_CALLS
    SENSORS android.permission.BODY_SENSORS
    SMS android.permission.SEND_SMS
    android.permission.RECEIVE_SMS
    android.permission.READ_SMS
    android.permission.RECEIVE_WAP_PUSH
    android.permission.RECEIVE_MMS
    STORAGE android.permission.READ_EXTERNAL_STORAGE
    android.permission.WRITE_EXTERNAL_STORAGE

    对应在清单文件中的展示如下:
    ...

     <!--CALENDAR-->
    <uses-permission android:name="android.permission.READ_CALENDAR"/>
    <uses-permission android:name="android.permission.WRITE_CALENDAR"/>
    <!--CAMERA-->
    <uses-permission android:name="android.permission.CAMERA"/>
    <!--CONTACTS-->
    <uses-permission android:name="android.permission.READ_CONTACTS"/>
    <uses-permission android:name="android.permission.WRITE_CONTACTS"/>
    <uses-permission android:name="android.permission.GET_ACCOUNTS"/>
    <!--LOCATION-->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <!--MICROPHONE-->
    <uses-permission android:name="android.permission.RECORD_AUDIO"/>
    <!--PHONE-->
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <uses-permission android:name="android.permission.CALL_PHONE"/>
    <uses-permission android:name="android.permission.READ_CALL_LOG"/>
    <uses-permission android:name="android.permission.ADD_VOICEMAIL"/>
    <uses-permission android:name="android.permission.WRITE_CALL_LOG"/>
    <uses-permission android:name="android.permission.USE_SIP"/>
    <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
    <!--SENSORS-->
    <uses-permission android:name="android.permission.BODY_SENSORS"/>
    <!--SMS-->
    <uses-permission android:name="android.permission.SEND_SMS"/>
    <uses-permission android:name="android.permission.RECEIVE_SMS"/>
    <uses-permission android:name="android.permission.READ_SMS"/>
    <uses-permission android:name="android.permission.RECEIVE_WAP_PUSH"/>
    <uses-permission android:name="android.permission.RECEIVE_MMS"/>
    <!--STORAGE-->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    

    ...

    实例:

    1.先从Activity的使用开始。
    ...

    public class MainActivity extends AppCompatActivity implements PermissionInterface {
      private PermissionHelper mPermissionHelper;
    
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
          //初始化并发起权限申请
          mPermissionHelper = new PermissionHelper(this, this);
          mPermissionHelper.requestPermissions();
      }
    
      @Override
      public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
          if(mPermissionHelper.requestPermissionsResult(requestCode, permissions, grantResults)){
          //权限请求结果,并已经处理了该回调
              return;
          }
          super.onRequestPermissionsResult(requestCode, permissions, grantResults);
      }
    
      @Override
      public int getPermissionsRequestCode() {
      //设置权限请求requestCode,只有不跟onRequestPermissionsResult方法中的其他请求码冲突即可。
          return 10000;
      }
    
      @Override
      public String[] getPermissions() {
      //设置该界面所需的全部权限
          return new String[]{
                  Manifest.permission.WRITE_EXTERNAL_STORAGE,
                  Manifest.permission.READ_PHONE_STATE
          };
      }
    
      @Override
      public void requestPermissionsSuccess() {
      //权限请求用户已经全部允许
          initViews();
      }
    
      @Override
      public void requestPermissionsFail() {
          //权限请求不被用户允许。可以提示或者弹框提示权限用途或者指引用户去重新授权
          Intent intent = new Intent("android.settings.APPLICATION_DETAILS_SETTINGS");
          intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
          intent.setData(Uri.fromParts("package", context.getPackageName(), null));
        if (intent.resolveActivity(context.getPackageManager()) != null) {
            context.startActivity(intent);
          }
      }
    
      private void initViews(){
          //已经拥有所需权限,可以放心操作任何东西了    
      }
    
    }
    

    ...

    其中使用到的两个类和一个接口实现:

    2.Activity需要实现的接口PermissionInterface.java
    ...

    /**
     * 权限请求接口
     * Created by dway on 2018/1/10.
     */
    public interface PermissionInterface {
        /**
         * 可设置请求权限请求码
         */
        int getPermissionsRequestCode();
        /**
         * 设置需要请求的权限
         */
        String[] getPermissions();
        /**
         * 请求权限成功回调
         */
        void requestPermissionsSuccess();
    
        /**
         * 请求权限失败回调
         */
        void requestPermissionsFail();
    
    }
    

    ...

    3.工具类PermissionUtil.java
    ...

    /**
     * 动态权限工具类
     * Created by dway on 2017/1/13.
     */
    public class PermissionUtil {
    
        /**
         * 判断是否有某个权限
         * @param context
         * @param permission
         * @return
         */
        public static boolean hasPermission(Context context, String permission){
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if(context.checkSelfPermission(permission)  != PackageManager.PERMISSION_GRANTED){
                    return false;
                }
            }
            return true;
        }
    
        /**
         * 弹出对话框请求权限
         * @param activity
         * @param permissions
         * @param requestCode
         */
        public static void requestPermissions(Activity activity, String[] permissions, int requestCode){
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                activity.requestPermissions(permissions, requestCode);
            }
        }
    
        /**
         * 返回缺失的权限
         * @param context
         * @param permissions
         * @return 返回缺少的权限,null 意味着没有缺少权限
         */
        public static String[] getDeniedPermissions(Context context, String[] permissions){
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                ArrayList<String> deniedPermissionList = new ArrayList<>();
                for(String permission : permissions){
                    if(context.checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED){
                        deniedPermissionList.add(permission);
                    }
                }
                int size = deniedPermissionList.size();
                if(size > 0){
                    return deniedPermissionList.toArray(new String[deniedPermissionList.size()]);
                }
            }
            return null;
        }
    
    }
    

    ...

    4.权限操作帮助类PermissionHelper.java
    ...

    package com.dway.permission;
    
    import android.app.Activity;
    import android.content.pm.PackageManager;
    import android.support.annotation.NonNull;
    
    /**
     * 动态权限帮助类
     * Created by dway on 2018/1/10.
     */
    public class PermissionHelper {
    
        private Activity mActivity;
        private PermissionInterface mPermissionInterface;
    
        public PermissionHelper(@NonNull Activity activity, @NonNull PermissionInterface permissionInterface) {
            mActivity = activity;
            mPermissionInterface = permissionInterface;
        }
    
        /**
         * 开始请求权限。
         * 方法内部已经对Android M 或以上版本进行了判断,外部使用不再需要重复判断。
         * 如果设备还不是M或以上版本,则也会回调到requestPermissionsSuccess方法。
         */
        public void requestPermissions(){
            String[] deniedPermissions = PermissionUtil.getDeniedPermissions(mActivity, mPermissionInterface.getPermissions());
            if(deniedPermissions != null && deniedPermissions.length > 0){
                PermissionUtil.requestPermissions(mActivity, deniedPermissions,     mPermissionInterface.getPermissionsRequestCode());
            }else{
                mPermissionInterface.requestPermissionsSuccess();
            }
        }
    
        /**
         * 在Activity中的onRequestPermissionsResult中调用
         * @param requestCode
         * @param permissions
         * @param grantResults
         * @return true 代表对该requestCode感兴趣,并已经处理掉了。false 对该requestCode不感兴趣,不处理。
         */
        public boolean requestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults){
            if(requestCode == mPermissionInterface.getPermissionsRequestCode()){
                boolean isAllGranted = true;//是否全部权限已授权
                for(int result : grantResults){
                    if(result == PackageManager.PERMISSION_DENIED){
                        isAllGranted = false;
                        break;
                    }
                }
                if(isAllGranted){
                    //已全部授权
                    mPermissionInterface.requestPermissionsSuccess();
                }else{
                    //权限有缺失
                    mPermissionInterface.requestPermissionsFail();
                }
                return true;
            }
            return false;
        }
    }
    

    ...

    OK,完成。建议在主activity就把需要的权限一次性都申请了。

    补充:
    在进行适配方案筛选过程中,发现一个开源库相比较下,更加简单易用.推荐一下
    Android权限适配的更优解决方案

    参考:
    Android 6.0 动态权限申请简单简洁优雅的处理方式

    相关文章

      网友评论

          本文标题:Android 6.0(M) 最佳适配方案

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