您好,欢迎来到源码搜藏!分享精神,快乐你我!提示:担心找不到本站?在百度搜索“源码搜藏”,网址永远不丢失!
  • 首 页
  • 在线工具
  • 当前位置:首页 > 安卓源码 > 技术博客 >

    Android6.0M权限管理实战,完美轻量级封装

    时间:2016-12-13 14:30 来源:互联网 作者:源码搜藏 浏览:收藏 挑错 推荐 打印

    随着Android版本的不断更新,Google的Android开发人员也想到了Android应用在权限管理方面的各种问题,让好多用户摸不着头脑就使用了用户的隐私数据。 为了在权限这方面加强管理,安卓平台权限一直有被流氓应用随便利用诟病,Android M的发布彻底解决了这一问

    随着Android版本的不断更新,Google的Android开发人员也想到了Android应用在权限管理方面的各种问题,让好多用户摸不着头脑就使用了用户的隐私数据。 为了在权限这方面加强管理,安卓平台权限一直有被流氓应用随便利用诟病,Android M的发布彻底解决了这一问题,取而代之的是, app不得不在运行时一个一个询问用户授予权限。Android 6.0(api23)M系统中,做了一些限制, 开发者在使用到每条权限时必须自己调用相关代码请求。 如果没有获得某项权限,直接使用相关功能,则会导致自己程序crash.。为了解决这方面的问题,我们每次请求某一个权限要写好多代码解决这个问题,非常的麻烦。 下面是我做的一个轻量级的封装,可以减少很多重复的工作。

    效果图 请求权限

    Android6.0M权限管理实战,完美轻量级封装

    用户禁止了权限

    Android6.0M权限管理实战,完美轻量级封装

    一.Android6.0M对权限的划分

    Android6.0M中对用户的权限分为了一般权限和危险权限,这些危险权限除了在AndroidManifest.xml中注册以外,还需要在使用的时候对用户进行请求权限弹窗提醒,才可以使用。 这些危险权限如下: Android6.0M权限管理实战,完美轻量级封装

    二.封装一个MPermissionsActivity的思路和步骤

    • 第一步:检测所有的权限是否都已授权
       /**
          * 检测所有的权限是否都已授权
          *
          * @param permissions
          * @return
          */
         private boolean checkPermissions(String[] permissions) {
             if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
                 return true;
             }
    
             for (String permission : permissions) {
                 if (ContextCompat.checkSelfPermission(this, permission) !=
                         PackageManager.PERMISSION_GRANTED) {
                     return false;
                 }
             }
             return true;
         }
    
    • 第二步:获取权限集中需要申请权限的列表
     /**
         * 获取权限集中需要申请权限的列表
         *
         * @param permissions
         * @return
         */
        private List<String> getDeniedPermissions(String[] permissions) {
            List<String> needRequestPermissionList = new ArrayList<>();
            for (String permission : permissions) {
                if (ContextCompat.checkSelfPermission(this, permission) !=
                        PackageManager.PERMISSION_GRANTED ||
                        ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) {
                    needRequestPermissionList.add(permission);
                }
            }
            return needRequestPermissionList;
        }
    
    • 第三步:请求权限
      /**
         * 请求权限
         *
         * @param permissions 请求的权限
         * @param requestCode 请求权限的请求码
         */
        public void requestPermission(String[] permissions, int requestCode) {
            this.REQUEST_CODE_PERMISSION = requestCode;
            if (checkPermissions(permissions)) {
                permissionSuccess(REQUEST_CODE_PERMISSION);
            } else {
                List<String> needPermissions = getDeniedPermissions(permissions);
                ActivityCompat.requestPermissions(this, needPermissions.toArray(new String[needPermissions.size()]), REQUEST_CODE_PERMISSION);
            }
        }
    
    
    • 第四步:处理权限请求回调
      /**
         * 系统请求权限回调
         *
         * @param requestCode
         * @param permissions
         * @param grantResults
         */
        @Override
        public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
            if (requestCode == REQUEST_CODE_PERMISSION) {
                if (verifyPermissions(grantResults)) {
                    permissionSuccess(REQUEST_CODE_PERMISSION);
                } else {
                    permissionFail(REQUEST_CODE_PERMISSION);
                    showTipsDialog();
                }
            }
        }
    
    
    • 第五步:查看处理权限请求回调用户是否已经授权
     /**
         * 确认所有的权限是否都已授权
         *
         * @param grantResults
         * @return
         */
        private boolean verifyPermissions(int[] grantResults) {
            for (int grantResult : grantResults) {
                if (grantResult != PackageManager.PERMISSION_GRANTED) {
                    return false;
                }
            }
            return true;
        }
    
    • 第六步:授权成功处理函数
      /**
         * 获取权限成功
         *
         * @param requestCode
         */
        public void permissionSuccess(int requestCode) {
            Log.d(TAG, "获取权限成功=" + requestCode);
    
        }
    
    
    • 第七步:授权失败处理函数与弹出用户提示
    
        /**
         * 权限获取失败
         * @param requestCode
         */
        public void permissionFail(int requestCode) {
            Log.d(TAG, "获取权限失败=" + requestCode);
        }
    
        /**
         * 显示提示对话框
         */
        private void showTipsDialog() {
            new AlertDialog.Builder(this)
                    .setTitle("提示信息")
                    .setMessage("当前应用缺少必要权限,该功能暂时无法使用。如若需要,请单击【确定】按钮前往设置中心进行权限授权。")
                    .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                        }
                    })
                    .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            startAppSettings();
                        }
                    }).show();
        }
    
    
    • 第八步:授权失败给用户提示后想再次开启跳到设置app权限界面
        /**
         * 启动当前应用设置页面
         */
        private void startAppSettings() {
            Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
            intent.setData(Uri.parse("package:" + getPackageName()));
            startActivity(intent);
        }
    

    三.完整的MPermissionsActivity代码

    package cn.bluemobi.dylan.mpermissions;
    
    import android.content.DialogInterface;
    import android.content.Intent;
    import android.content.pm.PackageManager;
    import android.net.Uri;
    import android.os.Build;
    import android.provider.Settings;
    import android.support.annotation.NonNull;
    import android.support.v4.app.ActivityCompat;
    import android.support.v4.content.ContextCompat;
    import android.support.v7.app.AlertDialog;
    import android.support.v7.app.AppCompatActivity;
    import android.util.Log;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * Created by yuandl on 2016-11-16.
     */
    
    public class MPermissionsActivity extends AppCompatActivity {
        private final String TAG = "MPermissions";
        private int REQUEST_CODE_PERMISSION = 0x00099;
    
        /**
         * 请求权限
         *
         * @param permissions 请求的权限
         * @param requestCode 请求权限的请求码
         */
        public void requestPermission(String[] permissions, int requestCode) {
            this.REQUEST_CODE_PERMISSION = requestCode;
            if (checkPermissions(permissions)) {
                permissionSuccess(REQUEST_CODE_PERMISSION);
            } else {
                List<String> needPermissions = getDeniedPermissions(permissions);
                ActivityCompat.requestPermissions(this, needPermissions.toArray(new String[needPermissions.size()]), REQUEST_CODE_PERMISSION);
            }
        }
    
        /**
         * 检测所有的权限是否都已授权
         *
         * @param permissions
         * @return
         */
        private boolean checkPermissions(String[] permissions) {
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
                return true;
            }
    
            for (String permission : permissions) {
                if (ContextCompat.checkSelfPermission(this, permission) !=
                        PackageManager.PERMISSION_GRANTED) {
                    return false;
                }
            }
            return true;
        }
    
        /**
         * 获取权限集中需要申请权限的列表
         *
         * @param permissions
         * @return
         */
        private List<String> getDeniedPermissions(String[] permissions) {
            List<String> needRequestPermissionList = new ArrayList<>();
            for (String permission : permissions) {
                if (ContextCompat.checkSelfPermission(this, permission) !=
                        PackageManager.PERMISSION_GRANTED ||
                        ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) {
                    needRequestPermissionList.add(permission);
                }
            }
            return needRequestPermissionList;
        }
    
    
        /**
         * 系统请求权限回调
         *
         * @param requestCode
         * @param permissions
         * @param grantResults
         */
        @Override
        public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
            if (requestCode == REQUEST_CODE_PERMISSION) {
                if (verifyPermissions(grantResults)) {
                    permissionSuccess(REQUEST_CODE_PERMISSION);
                } else {
                    permissionFail(REQUEST_CODE_PERMISSION);
                    showTipsDialog();
                }
            }
        }
    
        /**
         * 确认所有的权限是否都已授权
         *
         * @param grantResults
         * @return
         */
        private boolean verifyPermissions(int[] grantResults) {
            for (int grantResult : grantResults) {
                if (grantResult != PackageManager.PERMISSION_GRANTED) {
                    return false;
                }
            }
            return true;
        }
    
        /**
         * 显示提示对话框
         */
        private void showTipsDialog() {
            new AlertDialog.Builder(this)
                    .setTitle("提示信息")
                    .setMessage("当前应用缺少必要权限,该功能暂时无法使用。如若需要,请单击【确定】按钮前往设置中心进行权限授权。")
                    .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                        }
                    })
                    .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            startAppSettings();
                        }
                    }).show();
        }
    
        /**
         * 启动当前应用设置页面
         */
        private void startAppSettings() {
            Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
            intent.setData(Uri.parse("package:" + getPackageName()));
            startActivity(intent);
        }
    
        /**
         * 获取权限成功
         *
         * @param requestCode
         */
        public void permissionSuccess(int requestCode) {
            Log.d(TAG, "获取权限成功=" + requestCode);
    
        }
    
        /**
         * 权限获取失败
         * @param requestCode
         */
        public void permissionFail(int requestCode) {
            Log.d(TAG, "获取权限失败=" + requestCode);
        }
    }
    
    

    四.用法

    • 布局文件activity_main.xml
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/activity_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context="cn.bluemobi.dylan.mpermissions.MainActivity">
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello World!" />
    
        <Button
            android:id="@+id/button"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:onClick="onClick1"
            android:text="打电话" />
    
        <Button
            android:id="@+id/button2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:onClick="onClick2"
            android:text="写SD卡" />
    
        <Button
            android:id="@+id/button3"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:onClick="onClick3"
            android:text="拍照" />
    </LinearLayout>
    
    • MainActivity中使用:继承MPermissionsActivity即可
    package cn.bluemobi.dylan.mpermissions;
    
    import android.Manifest;
    import android.content.Intent;
    import android.net.Uri;
    import android.os.Bundle;
    import android.view.View;
    
    public class MainActivity extends MPermissionsActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
        }
    
        /**
         * 打电话
         *
         * @param view
         */
        public void onClick1(View view) {
            requestPermission(new String[]{Manifest.permission.CALL_PHONE}, 0x0001);
        }
    
        /**
         * 写SD卡
         *
         * @param view
         */
        public void onClick2(View view) {
            requestPermission(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0x0002);
        }
    
        /**
         * 拍照
         *
         * @param view
         */
        public void onClick3(View view) {
            requestPermission(new String[]{Manifest.permission.CAMERA}, 0x0003);
        }
    
        /**
         * 权限成功回调函数
         *
         * @param requestCode
         */
        @Override
        public void permissionSuccess(int requestCode) {
            super.permissionSuccess(requestCode);
            switch (requestCode) {
                case 0x0001:
                    Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:13468857714"));
                    startActivity(intent);
                    break;
            }
    
        }
    
    }
    
    

    五.GitHub

    Android6.0M权限管理实战,完美轻量级封装转载http://www.codesocang.com/anzhuoyuanma/boke/33988.html
    标签:网站源码