首页| 论坛| 搜索| 消息
主题:国内第三方Rom在Android6.0以下系统的权限适配
z3960发表于 2025-07-18 10:18
从6.0 MarshMallow开始,Android支持动态权限管理,即有些权限需要在使用到的时候动态申请,根据用户的选择需要有不同的处理,具体表现可以看下图:


权限申请
本文并不关心权限适配的原理,原理可以参考Android权限管理原理
,这里只是针对6.0中的表现做适配,先思考以下几个问题:为什么6.0权限需要适配什么权限需要动态适配怎样动态适配权限怎么样实现第三方库,简化代码及适配流程权限兼容库 PermissionCompat 对于国产ROM的影响

为什么6.0需要权限适配


6.0之前Android的权限都是在安装的时候授予的,6.0之后,为了简化安装流程,并且方便用户控制权限,Android允许在运行的时候动态控制权限。对于开发而言就是将targetSdkVersion设置为23,当运行在Android 6.0 +的手机上时,就会调用6.0相关的API,达到动态控制权限的目的。但是,如果仅仅是将targetSdkVersion设置为23,而在代码层面没有针对Android 6.0做适配,就可能在申请系统服务的时候,由于权限不足,引发崩溃。targetSDKVersion:该属性用于通知系统,您已针对目标版本进行测试,标识App能够适配的系统版本,有些新的API是只有新的系统才有的。

什么权限需要动态适配


并非所有的权限都需要动态申请,Android6.0将权限分为两种,普通权限跟敏感(危险)权限,普通权限是不需要动态申请的,但是敏感权限需要动态申请。1、普通权限(Normal permissions):不会泄露用户隐私,同时也不会导致手机安全问题。如网络请求权限、WIFI状态等,这类权限只需要在Manifest列出来,之后,系统会自动赋给APP权限:

代码语言:txt
AI代码解释
- ACCESS_NETWORK_STATE- ACCESS_NOTIFICATION_POLICY- ACCESS_WIFI_STATE- BLUETOOTH- BLUETOOTH_ADMIN2、

代码语言:txt
AI代码解释
- CALENDAR- CAMERA- CONTACTS- LOCATION- PHONE- SENSORS- SMS- STORAGE
敏感权限的请求是按照分组进行提醒的,并非仅仅针对一条,比如通讯录的读取权限与写权限,只要一个权限获到,下次请求权限的时候会自动提供,当然也要请求。否则还是有问题。3、特殊权限(Special Permissions) --不在本文分析范围There are a couple of permissions that don't behave like normal and dangerous permissions. SYSTEM_ALERT_WINDOW and WRITE_SETTINGS

怎样动态适配权限


对于敏感权限的适配有一个原则,那就是实时检查,因为权限随时可能被回收,比如用户可以在设置里面把权限给取消,但是APP并不一定知道,因此每次都需要检查,一旦没有,就需要请求,之后,根据返回结果处理后续逻辑。

实现步骤

1、在Manifest中列出来无论普通权限还是敏感权限,都需要在Manifest中列出来,同时也是对6.0之前的版本的一种兼容。 2、需要时,显示的请求
在权限没被授予前提下,系统会显示授权对话框,让用户操作,目前授权对话框不可定制,不过可以在申请之前添加一些解释,告诉用户为什么需要该权限,但是Google提醒,不要做过多的解释,可能会使用户感到厌烦,用法如下:

代码语言:javascript代码运行次数:0
运行
AI代码解释
ActivityCompat.requestPermissions(target.getActivity(), permissions,
·requestCode);

代码语言:javascript代码运行次数:0
运行
AI代码解释
public static void requestPermissions(final @NonNull Activity activity,final @NonNull String[] permissions, final int requestCode) {if (Build.VERSION.SDK_INT >= 23) {ActivityCompatApi23.requestPermissions(activity, permissions, requestCode);} else if (activity instanceof OnRequestPermissionsResultCallback) {Handler handler = new Handler(Looper.getMainLooper());handler.post(new Runnable() {@Overridepublic void run() {final int[] grantResults = new int;PackageManager packageManager = activity.getPackageManager();String packageName = activity.getPackageName();final int permissionCount = permissions.length;for (int i = 0; i 需要根据结果进行验证 if(PermissionUtils.verifyPermissions(grantResults)) { this.mOnGrantedListener.onGranted(this, permissions); } else if(!PermissionUtils.shouldShowRequestPermissionRationale(this, permissions)) { this.mOnGrantedListener.onNeverAsk(this, permissions); } else { this.mOnGrantedListener.onDenied(this, permissions); } } }

具体APP中不同的实现方案

1、简单的封装回调2、基于APT,采用注解方式简化编码逻辑,自动封封回调
先看一下直接回调的方式

采用最直接的回调


首先在基类Activity或者Fragment中统一设置授权回调监听,这里我们用一个

代码语言:javascript代码运行次数:0
运行
AI代码解释
public class BasePermissionCompatActivity extends AppCompatActivity {private SparseArray mOnGrantedListeners = new SparseArray();@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);OnGrantedListener listener = mOnGrantedListeners.get(requestCode);if (listener == null)return;if (PermissionUtils.verifyPermissions(grantResults)) {listener.onGranted(this, permissions);} else {if (PermissionUtils.shouldShowRequestPermissionRationale(this, permissions)) {listener.onDenied(this, permissions);} else {listener.onNeverAsk(this, permissions);}}}@Overrideprotected void onDestroy() {super.onDestroy();mOnGrantedListeners.clear();mOnGrantedListeners = null;}public void requestPermissions(final @NonNull String[] permissions, OnGrantedListener onGrantedListener) {int requestCode = getNextRequestCode();ActivityCompat.requestPermissions(this, permissions, requestCode);mOnGrantedListeners.put(requestCode, onGrantedListener);}private static int sNextCode;private static int getNextRequestCode() {return sNextCode++;}}
之后在需要时候的请求,并根据结果处理后续逻辑即可。

代码语言:javascript代码运行次数:0
运行
AI代码解释
requestPermissions(activity, P_CAMERA, new OnGrantedListener() {// 根据permissions自行处理,可合并,可分开@Overridepublic void onGranted(SecondActivity target, String[] permissions,int requestCode) {}@Overridepublic void onDenied(SecondActivity target, String[] permissions,int requestCode) {}@Overridepublic void onNeverAsk(SecondActivity target, String[] permissions,int requestCode) {}@Overridepublic void onShowRationale(SecondActivity target, String[] permissions,int requestCode) {});
上面的方法比较直接,灵活,不过每次都要自己实现回调监听Listener,接下来看第二种实现,基于APT,通过注解的方式,自动添加Listener,这种实现参考了But
下一页 (1/3)
回帖(5):
5 # huwg
07-19 00:31
谢谢分享
4 # huwg
07-19 00:31
来看看了
3 # srwam
07-18 22:30
了解一下
2 # srwam
07-18 22:30
来看看
1 # 爱我中华
07-18 12:41
多谢分享

全部回帖(5)»
最新回帖
收藏本帖
发新帖