Android 6.0运行时权限管理

一、Android 6.0权限的简单介绍

在Android6.0以前的设备上,android的权限只在安装的时候被询问一次。一旦安装了,app可以在用户毫不知晓的情况下访问权限内的所有东西,而且用户通常不会去查看app的权限列表,更不会去深入了解这些权限的作用以及可能带来的相关危害。所以在android 6.0 Marshmallow版本之后,系统不会在软件安装的时候就赋予该app所有其申请的权限,对于一些危险级别的权限,app需要在运行时一个一个询问用户授予权限,先看看6.0的危险级别的权限有哪些。

Permission Group Permissions
CALENDAR(日历) READ_CALENDAR
WRITE_CALENDAR
CAMERA CAMERA
CONTACTS(通讯录) READ_CONTACTS
WRITE_CONTACTS
GET_ACCOUNTS
LOCATION(地理位置) ACCESS_FINE_LOCATION
ACCESS_COARSE_LOCATION
MICROPHONE(麦克风) RECORD_AUDIO
PHONE(电话) READ_PHONE_STATE
CALL_PHONE
READ_CALL_LOG
WRITE_CALL_LOG
ADD_VOICEMAIL
USE_SIP
PROCESS_OUTGOING_CALLS
SENSORS(传感器) BODY_SENSORS
SMS(短信) SEND_SMS
RECEIVE_SMS
READ_SMS
RECEIVE_WAP_PUSH
RECEIVE_MMS
STORAGE(存储空间) READ_EXTERNAL_STORAGE
WRITE_EXTERNAL_STORAGE

二、第三方库PermissionsDispatcher的使用

PermissionsDispatcher是通过提供简单的注释来处理运行在Android 6.0上的运行时权限。
  github地址:https://github.com/hotchemi/PermissionsDispatcher
1、使用PermissionsDispatcher首先搜索下载PermissionsDispatcher的插件,如图:

Android 6.0运行时权限管理_第1张图片
PNG

2、先在module gradle里面添加

buildscript {    
    repositories {        
        jcenter()    
    }    
    dependencies {        
        classpath 'com.android.tools.build:gradle:2.1.2'       
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'        
        // NOTE: Do not place your application dependencies here; they belong        
        // in the individual module build.gradle files   
    }
}

3、在app gradle里面添加依赖包,${latest.version}填写最新的版本号,目前为 2.2.0

apply plugin: 'android-apt'
dependencies { 
    compile 'com.github.hotchemi:permissionsdispatcher:${latest.version}' 
    apt 'com.github.hotchemi:permissionsdispatcher-processor:${latest.version}'
}

4、进行动态权限处理代码的生成,在Android Studio中选择CodeGenerateGenerate Runtime Permissions,如下图所示:

Android 6.0运行时权限管理_第2张图片
PNG

/** 
* @NeedsPermission 当申请的权限被用户允许后,调用此方法。 
* @OnShowRationale 当第一次申请权限时,用户选择拒绝,再次申请时调用此方法,在此方法中提示用户为什么需要这个权限。 
* @OnPermissionDenied 当申请的权限被用户拒绝后,调用此方法 
* @OnNeverAskAgain 当用户点击不再询问后,调用此方法。 
*/
@RuntimePermissions
public class PermissionsDispatcherActivity extends AppCompatActivity {    
    TextView mTxt;    
    @Override    
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_permissions_dispatcher);
        mTxt = (TextView) findViewById(R.id.pd_txt);
    }
    void onClick(View view) {
        PermissionsDispatcherActivityPermissionsDispatcher.needsPermissionWithCheck(this);
    }
    @NeedsPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
    void needsPermission() {
        mTxt.setTextColor(Color.GREEN);
        mTxt.setText("存储空间权限已申请成功");
    }
    @OnShowRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)
    void showRationale(final PermissionRequest request) {
        new AlertDialog.Builder(this)
                .setMessage("申请存储空间权限")
                .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        //再次执行请求
                        request.proceed();
                    }
                }).show();
    }
    @OnPermissionDenied(Manifest.permission.WRITE_EXTERNAL_STORAGE)
    void permissionDenied() {
        mTxt.setTextColor(Color.RED);
        mTxt.setText("权限被拒绝");
    }
    @OnNeverAskAgain(Manifest.permission.WRITE_EXTERNAL_STORAGE)
    void neverAskAgain() {
        mTxt.setTextColor(Color.YELLOW);
        mTxt.setText("不再询问");
    }
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        PermissionsDispatcherActivityPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults);
    }
}

看看效果:

Android 6.0运行时权限管理_第3张图片
12.gif

三、最后再来自己实现以下,就不多说了,直接上代码

public class RuntimePermisionActivity extends AppCompatActivity {
    TextView mTxt;
    private final int CAMERA_REQUEST_CODE = 0x001;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_runtime_permision);
        mTxt = (TextView) findViewById(R.id.rp_txt);
    }
    void onClick(View view) {
        requestPermissions();
    }
    private void requestPermissions() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)                != PackageManager.PERMISSION_GRANTED) {
            // 第一次请求权限时,向用户解释为什么需要这个权限,用户如果拒绝,下一次请求shouldShowRequestPermissionRationale()返回true
            if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                new AlertDialog.Builder(this)
                        .setMessage("申请存储空间权限")
                        .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                //申请存储空间权限
                                ActivityCompat.requestPermissions(RuntimePermisionActivity.this,                                        new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, CAMERA_REQUEST_CODE);
                            }
                        })                        .show();
            } else {
                //申请存储空间权限
                ActivityCompat.requestPermissions(this,                        new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, CAMERA_REQUEST_CODE);
            }
        } else {
            mTxt.setTextColor(Color.GREEN);
            mTxt.setText("存储空间权限已申请");
        }
    }
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == CAMERA_REQUEST_CODE) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                mTxt.setTextColor(Color.GREEN);
                mTxt.setText("存储空间权限已申请");
            } else {
                //用户勾选了不再询问
                //提示用户手动打开权限
                if (!ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                    mTxt.setTextColor(Color.RED);
                    mTxt.setText("存储空间权限已被禁止");
                }
            }
        }
    }
}

效果和使用PermissionsDispatcher是一样的

最后再来个最简单的权限判断请求方法

private final static int REQUEST_CODE_ASK_PERMISSIONS = 100;
public static boolean requestPermission(Activity activity, String... premission) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        for (int i = 0; i < premission.length; i++) {
            int hasPermission = activity.checkSelfPermission(premission[i]);
            if (hasPermission != PackageManager.PERMISSION_GRANTED) {
                activity.requestPermissions(premission,
                        REQUEST_CODE_ASK_PERMISSIONS);
                return false;
            }
        }
    }
    return true;
}
if (Utils.requestPermission(this,
 Manifest.permission.READ_EXTERNAL_STORAGE,
 Manifest.permission.WRITE_EXTERNAL_STORAGE,        
 Manifest.permission.CAMERA,        
 Manifest.permission.RECORD_AUDIO)) {
    //请求后的操作
}

github地址:https://github.com/JerryLong/Android/tree/master/app/src/main/java/com/dralong/demo/ui

你可能感兴趣的:(Android 6.0运行时权限管理)