Android_TRY
Android_TRY
  • 发布:2019-04-20 17:46
  • 更新:2023-03-29 12:15
  • 阅读:26480

Android动态权限申请

分类:Native.js

更新:插件市场已经提供了封装更完善版本:https://ext.dcloud.net.cn/plugin?id=594

从HBuilderX1.9.4及以上版本开始,Android平台默认targetSdkVersion从21(Android5.0)调整为23(Android6.0)。

Android动态权限申请机制

Android6.0(API23)及以后,系统对权限的管理更加严格,放弃了以往manifest中注册所需权限,用户只要安装APP,便获取了所有注册权限的权限管理机制,而是改为除了需manifest中注册,部分危险权限另需在用户使用某项特殊功能时,向用户动态申请的机制。

当用户手机系统为Android6.0及以上,APP的targetSdkVersion>=23时,新的动态权限申请机制将会被触发,其它所有情况(1.系统版本>=6.0,targetSdkVersion<23;2.系统版本<6.0,targetSdkVersion>=23;3.系统版本<6.0,targetSdkVersion<23)都不会触发动态权限申请机制,因此,如果你不想在APP中动态申请权限,可以将targetSdkVersion设置为小于23。如不然,你就需要在使用某些涉及危险权限的功能(如读取通讯录)时通过系统弹窗的形式向用户动态申请该权限。动态申请权限下,如果用户在权限申请弹窗中拒绝了该申请,则用户将不能使用需要该权限的功能,再次申请该权限时依然会弹窗向用户申请;若用户在权限申请弹窗中勾选了“不再提示”并拒绝,那么再次申请该权限的时候将不会弹出系统弹窗向用户申请权限,此时需要APP引导用户打开设置,在设置中给与APP所需权限。
注意:云端打包targetSdkVersion默认值为26

5+APP中动态权限申请机制的实现

5+APP各独立模块中已经集成了功能所需权限的动态申请机制,开发者无需另做处理。但是如果需要使用某些尚未集成的特殊功能,如通过native.js调用原生方法获取手机扫描到的wifi列表,由于android可以通过访问wifi获取位置信息,因此需要在使用原生方法前先动态申请该功能所需的ACCESS_FINE_LOCATION权限。正因为有这样的需求,DCloud在native.js中为Android提供了动态申请权限的功能。

开发者通过调用plus.android.requestPermissions申请权限。参数permissions为所需权限数组;resultCallback为申请结果回调,将会返回已获取的权限、拒绝本次申请的权限、永久拒绝申请的权限3种结果的权限列表,开发者可以读取各权限申请结果并做相应处理;errorCallback为权限参数格式错误时调用,返回错误信息。

代码举例

依然以获取wifi列表为例,使用该功能前需要开发者先申请所需权限ACCESS_FINE_LOCATION:

function requestPermission() {  
    plus.android.requestPermissions(  
    ["android.permission.ACCESS_FINE_LOCATION"],  
    function(resultObj){  
        for (var i = 0; i < resultObj.granted.length; i++) {  
            var grantedPermission = resultObj.granted[i];  
            console.log('已获取的权限:'+ grantedPermission);  
        }  
        for (var i = 0; i < resultObj.deniedPresent.length; i++) {  
            var deniedPresentPermission = resultObj.deniedPresent[i];  
            console.log('拒绝本次申请的权限:'+ deniedPresentPermission );  
        }  
        for (var i = 0; i < resultObj.deniedAlways.length; i++) {  
            var deniedAlwaysPermission = resultObj.deniedAlways[i];  
            console.log('永久拒绝申请的权限:'+ deniedAlwaysPermission);  
        }  
        // 若所需权限被永久拒绝,则打开APP设置界面,可以在APP设置界面打开相应权限  
        if (resultObj.deniedAlways.length > 0) {  
            var Intent = plus.android.importClass("android.content.Intent");  
            var Settings = plus.android.importClass("android.provider.Settings");  
            var Uri = plus.android.importClass("android.net.Uri");  
            var mainActivity = plus.android.runtimeMainActivity();  
            var intent = new Intent();  
            intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);  
            var uri = Uri.fromParts("package", mainActivity.getPackageName(), null);  
            intent.setData(uri);  
            mainActivity.startActivity(intent);  
        }  
    },  
    function(error){  
        console.log('申请权限错误:'+ error.code+ " = "+ error.message);  
    });  
}

引导用户打开所需权限的方法分析

当需要引导用户打开特定权限时,最理想的情况是打开一个只有该权限开关的页面让用户开启权限,但是Android会将应用申请的所有权限集中在一个页面,因此从Android系统提供的功能的角度讲,最好是能引导用户进入应用的权限管理页面,在这个页面中让用户根据提示打开相应权限。然而,国内厂商早在Android未提供动态权限申请功能时就对Android应用的权限申请进行了改造和封装,这就使开发者无法通过统一的入口进入应用权限管理页面,而需要通过各个厂商自己的入口进入,如

// 华为  
Intent intent = new Intent(packageName);  
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
ComponentName comp = new ComponentName("com.huawei.systemmanager", "com.huawei.permissionmanager.ui.MainActivity");  
intent.setComponent(comp);  
mContext.startActivity(intent);  
// 魅族  
Intent intent = new Intent("com.meizu.safe.security.SHOW_APPSEC");  
intent.addCategory(Intent.CATEGORY_DEFAULT);  
intent.putExtra("packageName", packageName);  
mContext.startActivity(intent);

这无疑加大了开发难度。而且各厂商更可能随着版本的升级更改权限管理入口,这就加大了开发的不确定性。因此,我们推荐的最理想的引导用户打开权限的入口是应用设置页面,然后用户通过点击“权限管理”自主进入权限管理页面进行相关权限的设置。
5+APP中利用native.js打开应用设置页面的方法见上方代码举例。

附Android危险权限列表

  • 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

  • CONTACTS(联系人)
    android.permission.READ_CONTACTS
    android.permission.WRITE_CONTACTS
    android.permission.GET_ACCOUNTS

  • PHONE(手机)
    android.permission.READ_PHONE_STATE
    android.permission.CALL_PHONE
    android.permission.READ_CALL_LOG
    android.permission.WRITE_CALL_LOG
    android.permission.ADD_VOICEMAIL
    android.permission.USE_SIP
    android.permission.PROCESS_OUTGOING_CALLS

  • CALENDAR(日历)
    android.permission.READ_CALENDAR
    android.permission.WRITE_CALENDAR

  • CAMERA(相机)
    android.permission.CAMERA

  • LOCATION(位置)
    android.permission.ACCESS_FINE_LOCATION
    android.permission.ACCESS_COARSE_LOCATION

  • SENSORS(传感器)
    android.permission.BODY_SENSORS

  • MICROPHONE(麦克风)
    android.permission.RECORD_AUDIO

Android官方权限概述(需翻墙)
Android官方权限列表(需翻墙)

相关问题

【报Bug】新版本hbuilder不支持安卓WIFI的扫描

iOS权限检查见:https://ask.dcloud.net.cn/article/35915

10 关注 分享
菜鸡 BoredApe vvipLin 小王子888 靓崽 l***@foxmail.com y***@gaosuxing.cn o***@163.com 9157654 1***@qq.com

要回复文章请先登录注册

7***@qq.com

7***@qq.com

请问下plus.android.requestPermissions回调函数没有触发可能是什么问题,有没有遇过的?
2020-05-22 11:25
b***@qq.com

b***@qq.com

请教大神如何在新进程中打开app权限设置页面
2020-04-29 21:26
1***@qq.com

1***@qq.com

回复 2***@qq.com :
已经解决了!
2019-12-10 10:28
2***@qq.com

2***@qq.com

回复 1***@qq.com :
解决了吗 我也是切换网络app闪退
2019-12-05 22:04
1***@qq.com

1***@qq.com

设置里面拒绝了,plus.android.requestPermissions获取的权限还是允许,一直是允许
2019-11-29 15:56
1***@qq.com

1***@qq.com

回复 Android_TRY :
那如果拒绝了此权限有办法让app不闪退吗?谢谢!
2019-11-13 10:41
Android_TRY

Android_TRY (作者)

回复 1***@qq.com :
获取访问照片,媒体内容和文件权限其实就是获取存储权限,这个无法去除,是uni-app的内部存储逻辑需要的,不会访问用户照片媒体文件的。
2019-11-13 10:23
1***@qq.com

1***@qq.com

回复 Android_TRY :
你好,请问下怎么删除app项目启动获取访问照片,媒体内容和文件权限呢?删除AndroidManifest.xml可这个文件在哪里?
2019-11-13 09:48
4***@qq.com

4***@qq.com

申请了短信权限之后 uniapp的返回键失灵了 要怎么处理呢
2019-07-08 16:06
m***@163.com

m***@163.com

回复 BJ_Q :
https://ask.dcloud.net.cn/article/35036 这个链接里面有一句:“注意uni-app不需要像5+App那样等待plus ready,可以直接用。”所以你贴到这个链接里面那个监听函数不需要。
2019-06-28 10:53