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

效果图 请求权限

用户禁止了权限

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

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

二.封装一个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 getDeniedPermissions(String[] permissions) {        List 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 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代码

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 hyczlf on 2017-02-19. */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 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 getDeniedPermissions(String[] permissions) {        List 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"?>        

  • MainActivity中使用:继承MPermissionsActivity即可
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;        }    }}


更多相关文章

  1. Android(安卓)开发的常用工具类(一)——ScreenUtils 可用于获取屏
  2. Android(安卓)上下文菜单:给ListView注册ContextMenu后获取被长按
  3. Android获取屏幕分辨率及DisplayMetrics简介
  4. android以后台service的方式获取GPRS数据
  5. Android(安卓)各大网络请求库的比较及实战
  6. Android悬浮窗使用小结
  7. androidManifest.xml之uses-permission(权限-安全控制)
  8. Android(安卓)root原理
  9. Android多媒体学习一:Android中Image的简单实例。

随机推荐

  1. android打开联系人的代码
  2. android日期控件显示
  3. android java 检测文件夹(目录)是否存在,
  4. android获取控件宽高
  5. Android 自定义 LinearLayout
  6. Android 中颜色对应的值
  7. Android手机卫士(一)
  8. Android 使用AlarmManager设置闹钟
  9. Android基础之Android的Activity周期
  10. android 调用相机拍摄照片视频