Android6.0动态权限适配&XMPermissions

permission.jpg

Android6.0动态权限

简介

从 Android 6.0(API 级别 23)开始,用户开始在应用运行时向其授予权限,而不是在应用安装时授予。此方法可以简化应用安装过程,因为用户在安装或更新应用时不需要授予权限。它还让用户可以对应用的功能进行更多控制;例如,用户可以选择为相机应用提供相机访问权限,而不提供设备位置的访问权限。用户可以随时进入应用的“Settings”屏幕调用权限。摘自Android官网:在运行时请求权限

targetSdkVerion

我们在开发的时候需要指定minSdkVersiontargetSdkVerion

  • minSdkVersion为app最低适配的版本,低于该版本的手机无法安装;
  • targetSdkVerion简单来说就代表着你的App能够适配的系统版本,意味着你的App在这个版本的手机上做了充分的 前向 兼容性处理和实际测试。其实我们写代码时都是经常干这么一件事,就是 if(Build.VERSION.SDK_INT >= 23) { ... } ,这就是兼容性处理最典型的一个例子。如果你的target设置得越高,其实调用系统提供的API时,所得到的处理也是不一样的,甚至有些新的API是只有新的系统才有的;

Android6.0特殊权限Special Permissions

看权限名就知道特殊权限比危险权限更危险,特殊权限需要在manifest中申请并且通过发送Intent让用户在设置界面进行勾。

//SYSTEM_ALERT_WINDOW
private static final int REQUEST_CODE = 1;
private void requestAlertWindowPermission(){
    Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
    intent.setData(Uri.parse("package:"+ getPackageName()));
    startActivityForResult(intent, REQUEST_CODE);
}
@Override
protected void onActivityResult(intrequestCode, intresultCode, Intent data){
    super.onActivityResult(requestCode, resultCode, data);
    if(requestCode == REQUEST_CODE) {
        if(Settings.canDrawOverlays(this)) {
            Log.i(LOGTAG, "onActivityResult granted");
        }
    }
}
//WRITE_SETTINGS 修改系统设置
private static final int REQUEST_CODE_WRITE_SETTINGS = 2;
private void requestWriteSettings(){
    Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
    intent.setData(Uri.parse("package:"+ getPackageName()));
    startActivityForResult(intent, REQUEST_CODE_WRITE_SETTINGS );
}
@Override
protected void onActivityResult(intrequestCode, intresultCode, Intent data){
    super.onActivityResult(requestCode, resultCode, data);
    if(requestCode == REQUEST_CODE_WRITE_SETTINGS) {
        if(Settings.System.canWrite(this)) {
            Log.i(LOGTAG, "onActivityResult write settings granted");
        }
    }
}

Android6.0普通权限normal permission

普通权限不会对用户的隐私和安全产生太大的风险,所以只需要在AndroidManifest.xml中声明即可.

Android6.0危险权限dangerous permission

  • Normal Permission:写在xml文件里,那么App安装时就会默认获得这些权限,即使是在Android6.0系统的手机上,用户也无法在安装后动态取消这些normal权限,这和以前的权限系统是一样的,不变。

  • Dangerous Permission:还是得写在xml文件里,但是App安装时具体如果执行授权分以下几种情况:

    • 1、targetSDKVersion < 23 & API(手机系统) < 6.0 :安装时默认获得权限,且用户无法在安装App之后取消权限。

    • 3、targetSDKVersion < 23 & API(手机系统) >= 6.0 :安装时默认获得权限,但是用户可以在安装App完成后动态取消授权( 取消时手机会弹出提醒,告诉用户这个是为旧版手机打造的应用,让用户谨慎操作 )。

    • 2、targetSDKVersion >= 23 & API(手机系统) < 6.0 :安装时默认获得权限,且用户无法在安装App之后取消权限。

    • 4、targetSDKVersion >= 23 & API(手机系统) >= 6.0 :安装时不会获得权限,可以在运行时向用户申请权限。用户授权以后仍然可以在设置界面中取消授权,用户主动在设置界面取消后,在app运行过程中可能会出现crash。

Dangerous permissions and permission groups(危险权限和权限组)

同一组的任何一个权限被授权了,其他权限也自动被授权。例如,一旦WRITE_CONTENTS被授权了,APP也有READ_CONTACTS和GET_ACCOUNTS了。

permission-group dangerous 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(使用SIP协议 , PROCESS_OUTGOING_CALLS(程序拨出电话)
SENSORS(传感器) BODY_SENSORS
SMS SEND_SMS , RECEIVE_SMS , READ_SMS , RECEIVE_WAP_PUSH , RECEIVE_MMS
TORAGE(存储) READ_EXTERNAL_STORAGE ,WRITE_EXTERNAL_STORAGE

如何开始动态申请权限

判断权限是否具有某项权限

ContextCompat.checkSelfPermission(Context context,String permission);
ActivityCompat.checkSelfPermission(Context context, String permission);
activity.checkSelfPermission(String permission);

申请权限

ActivityCompat.requestPermissions(Activity activity,String[] permissions,int requestCode);
activity.requestPermissions(String[] permissions, int requestCode);
//申请权限回调方法,在Activity或Fragment重写
onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)

是否要提示用户申请该权限的缘由,sdk小于23恒为false

ActivityCompat.shouldShowRequestPermissionRationale(Activity activity, String permission)
0、之前没有拒绝过此权限的申请(第一次安装后请求权限前调用):false
1、曾经被拒绝过权限后再调用:true
2、曾经被拒绝过权限且不再询问后再调用:false
3、系统不允许任何程序获取该权限:false
4、查看源码得知安卓6.0以下返回:false
5、总是允许权限后再次调用:false

在APP使用过程中,从设置中更改权限

如果应用程序的某个业务逻辑需要使用权限,但用户没有选择开启。那么最好引导用户去设置界面修改应用程序的权限。

XMPermissions

导读

如果我们应用需要动态申请危险权限,按照Google官方问档我们需要在activity或者fragment中的onRequestPermissionsResult方法进行回调处理。一个执行任务代码需要分开写在两处地方,这我们的代码会变得很不优雅。

有没有链式、流式或者注解的方式去解决这个问题?有而且很多,以下是我在github 上找的start 最多的开源库。

RxPermissions RxJava流式用法;
XXPermissions 链式用法;
permissions4m 注解用法;

个人对注解使用不太感冒,而且项目有用到Rxjava的地方。
综上所述,我在RxPermissionsXXPermissions 基础上开发了 XMPermissions

依赖

implementation 'com.tzx.lib:xmpermission:1.0.0'

使用

public interface OnPermission {
    /**
     * 本次申请的权限全部通过
     */
    void hasPermission();

    /**
     * 本次申请的权限没有全部通过
     * @param granteds
     */
    void noPermission(List<PermissionState> granteds);
}

RxJava

XMPermissions.with(this)
    .request(Permission.Group.STORAGE, Permission.Group.PHONE)
    .subscribe(new SimpleSubscriber<List<PermissionState>>() {
        @Override
        public void onNext(List<PermissionState> permissionStates) {
            for (PermissionState s: permissionStates) {
                Log.d("tanzhenxing:", s.toString());
            }
        }
    });

链式调用

XMPermissions.with(this)
                //.constantRequest() //可设置被拒绝后继续申请,直到用户授权或者永久拒绝
                .permission(Permission.Group.STORAGE, Permission.Group.CALENDAR) 
                .request(new OnPermission() {

                    @Override
                    public void hasPermission() {
                        Toast.makeText(MainActivity.this, "获取权限成功", Toast.LENGTH_SHORT).show();
                    }

                    @Override
                    public void noPermission(List<PermissionState> granteds) {
                        for (PermissionState s: granteds) {
                            Log.d("tzx:", s.toString());
                        }
                    }

                });

跳转到应用权限设置页面

XMPermissions.gotoPermissionSettings(content);

6.0动态权限适配总结

有了XMPermissions 适配6.0动态权限就非常简单了。将targetVersion升级到23,然后每个使用储存、定位、电话、相机、录音等危险权限的地方做权限的check

当然这么做非常麻烦像储存、定位、电话这三个权限我们几乎每次接口访问都需要获取,所以我们可以将一些权限申请在应用启动前置。

  • 转转:储存、定位、电话前置
  • 58同城: 存储、电话前置
  • 京东: 定位、电话前置
  • 手机淘宝: 电话前置
  • 手机百度: 存储前置

在进行短信发送和打电话时,不需要权限也可以哦~!我自己测试了4个主流厂商的8款手机。

随着Android系统的不断更新,后续后问题会继续同步哒~!

文章到这里就全部讲述完啦,若有其他需要交流的可以留言哦

想阅读作者的更多文章,可以查看我 个人博客 和公共号:

振兴书城

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,451评论 25 707
  • 发热放入Android6.0带来了新的权限管理方式,根据提供的官方文档,再加上自己的理解,做了以下汇总仅供大家伙参...
    PapiAP阅读 1,658评论 0 6
  • Android6.0(M),代号棉花糖,尽管每年谷歌都会很早的推出Andorid新版本,但要让国内(普通用户)真正...
    李晨玮阅读 14,604评论 14 70
  • 用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金 Cover 有什么料? 从这篇文章中你...
    hw1212阅读 12,691评论 2 59
  • 乌云逐月隐隐行, 半是无晴半有晴。 敢问苍天有何事? 幻化莫测情难明!
    往事如烟胖婆婆阅读 397评论 5 6