当前位置: 首页 > web >正文

Android 动态权限申请

ContextCompat.checkSelfPermission
检查应用是否具有某个危险权限。如果应用具有此权限,方法将返回PackageManager.PERMISSION_GRANTED,并且应用可以继续操作。如果应用不具有此权限,方法将返回PackageManager.PERMISSION_DENIED,且应用必须明确向用户要求权限。
ActivityCompat.requestPermissions
应用可以通过这个方法动态申请权限,调用后会弹出一个对话框提示用户授权所申请的权限
ActivityCompat.shouldShowRequestPermissionRationale
如果应用之前请求过此权限但是用户拒绝了此权限,此方法返回true。如果用户在过去拒绝了权限请求,并且在权限请求系统对话框中选择了不再提示这样的选项,此方法将返回false。如果设备规范禁止应用具有此权限,此方法也会返回false。
onRequestPermissionsResult
当应用请求权限时,系统将向用户显示一个对话框。当用户响应时,系统将调用应用的onRequestPermissionsResult()方法,向其传递用户响应,处理对应的场景。

下面以Android 12系统为例,分析系统对动态权限的处理流程


App申请动态权限代码

xml

<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

Java

private static final int REQUEST_CAMERA_PERMISSION = 100;if (ContextCompat.checkSelfPermission(mContext, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(mActivity, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);
} else {// 权限已经被授予,可以使用相机功能Log.w(TAG, "xww onCreate: is aleady ok");
}public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);if (requestCode == REQUEST_CAMERA_PERMISSION) {if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {// 权限被授予,可以使用相机功能for (int i = 0; i < grantResults.length; i++) {Log.w(TAG, "xww onRequestPermissionsResult is ok" + " grantResults.length=" + grantResults.length+ " i=" + i + " grantResults=" + grantResults[i]);}} else {// 权限被拒绝,显示提示信息Toast.makeText(this, "xww 相机权限被拒绝", Toast.LENGTH_SHORT).show();Log.w(TAG, "xww onRequestPermissionsResult xww 相机权限被拒绝" + " grantResults.length=" + grantResults.length + " grantResults[0]=" + grantResults[0]);}}
}

requestPermissions

申请权限时启动权限控制应用,弹出窗口

@frameworks/base/core/java/android/app/Activity.java
requestPermissions
@frameworks/base/core/java/android/content/pm/PackageManager.javafinal Intent intent = getPackageManager().buildRequestPermissionsIntent(permissions);Intent intent = new Intent(ACTION_REQUEST_PERMISSIONS);   //public static final String ACTION_REQUEST_PERMISSIONS = "android.content.pm.action.REQUEST_PERMISSIONS";intent.putExtra(EXTRA_REQUEST_PERMISSIONS_NAMES, permissions);intent.setPackage(getPermissionControllerPackageName());    startActivityForResult(REQUEST_PERMISSIONS_WHO_PREFIX, intent, requestCode, null);//packages/modules/Permission/PermissionController/AndroidManifest.xml               <action android:name="android.content.pm.action.REQUEST_PERMISSIONS" /> 

GrantPermissionsActivity

权限控制应用

@packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/GrantPermissionsActivity.java
onCreate
@packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/GrantPermissionsViewHandlerImpl.ktmViewHandler = new com.android.permissioncontroller.permission.ui.handheld.GrantPermissionsViewHandlerImpl(this, mCallingPackage, Process.myUserHandle()).setResultListener(this);
@packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/model/GrantPermissionsViewModel.kt    mViewModel = factory.create(GrantPermissionsViewModel.class);return GrantPermissionsViewModel(app, packageName, requestedPermissions.toList(), sessionId,init {GlobalScope.launch(Main.immediate) {mViewModel.getRequestInfosLiveData().observe(this, this::onRequestInfoLoad);onRequestInfoLoad
@packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/GrantPermissionsViewHandlerImpl.kt    mRootView = mViewHandler.createView();button!!.setOnClickListener(this)//弹出弹窗
GlobalScope.launch(Main.immediate) {val groups = packagePermissionsLiveData.getInitializedValue() for (gg in groups) {Log.w("xww", "xww init, gg=${gg}");//gg=android.permission-group.CAMERA=[android.permission.CAMERA]//gg=android.permission-group.LOCATION=[android.permission.ACCESS_FINE_LOCATION, android.permission.ACCESS_COARSE_LOCATION, android.permission.ACCESS_BACKGROUND_LOCATION]for (requestedPerm in requestedPermissions) {Log.w("xww", "xww init, requestedPerm=$requestedPerm");//requestedPerm=android.permission.CAMERAallAffectedPermissions.addAll(computeAffectedPermissions(requestedPerm, groups))val extendedBySplitPerms = mutableListOf(perm)return extendedBySplitPermsunfilteredAffectedPermissions = allAffectedPermissions.toList()for (unfilteredAffectedPerm in unfilteredAffectedPermissions) {Log.w("xww", "xww init, unfilteredAffectedPerm=${unfilteredAffectedPerm}"); //unfilteredAffectedPerm=android.permission.CAMERA       getAppPermGroups(groups.toMutableMap().apply {val requestedGroups = groups.filter { (_, perms) -> perms.any { it in unfilteredAffectedPermissions }  //过滤出requestedGroupsfor (requestedGroup in requestedGroups) {Log.w("xww", "xww getAppPermGroups, requestedGroup=${requestedGroup}");        //getAppPermGroups, requestedGroup=android.permission-group.CAMERA=[android.permission.CAMERA]setSourcesToDifference(requestedGroups.keys, appPermGroupLiveDatas, getLiveDataFun)//viewModel,数据更新时调用onUpdate
@packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/model/GrantPermissionsViewModel.kt
onUpdategetRequestInfosFromGroupStates()requestInfos.add(RequestInfo(groupInfo, buttonVisibilities, locationVisibilities, message, detailMessage))value = if (requestInfos.any { it.sendToSettingsImmediately }        
@packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/GrantPermissionsActivity.javaonRequestInfoLoadmRequestInfos = requests;for(int i=0; i< requests.size(); i++){Log.w(LOG_TAG, "xww onRequestInfoLoad 5, i=" + i + " requests.getGroupName=" + requests.get(i).getGroupName());//onRequestInfoLoad 5, i=0 requests.getGroupName=android.permission-group.CAMERAshowNextRequest();
@packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/GrantPermissionsViewHandlerImpl.kt                mViewHandler.updateUi(info.getGroupName(), mTotalRequests, mCurrentRequestIdx, icon, message, detailMessage, mButtonVisibilities, mLocationVisibilities);Log.v("xww", "xww updateUi groupName=$groupName")this.groupName = groupName  //1. 设置groupName, 2处用到//updateUi groupName=android.permission-group.CAMERA
@frameworks/base/core/java/android/view/Window.javagetWindow().setDimAmount(mOriginalDimAmount);  // mOriginalDimAmount=0.6mHaveDimAmount = true;

点击allow按键

@packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/GrantPermissionsViewHandlerImpl.kt
onClickALLOW_BUTTON -> if (resultListener != null) {
@packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/GrantPermissionsActivity.java        resultListener!!.onPermissionGrantResult(groupName, affectedForegroundPermissions,GRANTED_ALWAYS)  //2. 获取groupName, 1处设置Log.w(LOG_TAG, "xww onPermissionGrantResult 2, name=" + name + " result=" + result + " affectedForegroundPermissions=" + affectedForegroundPermissions);//onPermissionGrantResult 2, name=android.permission-group.CAMERA result=1 affectedForegroundPermissions=nulllogGrantPermissionActivityButtons(name, affectedForegroundPermissions, result);
@packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/model/GrantPermissionsViewModel.ktmViewModel.onPermissionGrantResult(name, affectedForegroundPermissions, result);GRANTED_ALWAYS -> {onPermissionGrantResultSingleState(foregroundGroupState, affectedForegroundPermissions, granted = true, isOneTime = false, doNotAskAgain = false)
@packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/utils/KotlinUtils.ktKotlinUtils.grantForegroundRuntimePermissions(app, groupState.group, groupState.affectedPermissions, isOneTime)return grantRuntimePermissions(app, group, true, false, filterPermissions)for (permName in filterPermissions) {val (newPerm, shouldKill) = grantRuntimePermission(app, perm, isOneTime, group)
@frameworks/base/core/java/android/permission/PermissionManager.java                                    app.packageManager.grantRuntimePermission(group.packageName, perm.name, user)
@frameworks/base/services/core/java/com/android/server/pm/permission/PermissionManagerService.java                                        mPermissionManager.grantRuntimePermission(packageName, permissionName, user.getIdentifier());grantRuntimePermissionInternal(packageName, permName, overridePolicy, callingUid, userId, mDefaultPermissionCallback);callback.onPermissionGranted(uid, userId);  //通过PermissionCallback将权限申请结果回调给PKMS,PermissionCallback是在PKMS实现的mOnPermissionChangeListeners.onPermissionsChanged(uid);mPackageManagerInt.writeSettings(true);reportRequestResult(groupState.affectedPermissions, result)  //打印logfor (perm in permissions) { reportRequestResult(perm, result)Log.v(LOG_TAG, "Permission grant result requestId=$sessionId " + "callingUid=${packageInfo.uid} callingPackage=$packageName permission=$permission " + "isImplicit=$isImplicit result=$result")//Permission grant result requestId=-7157070073027897334 callingUid=10058 callingPackage=com.example.androidimu permission=android.permission.WRITE_EXTERNAL_STORAGE isImplicit=false result=4//Permission grant result requestId=-7157070073027897334 callingUid=10058 callingPackage=com.example.androidimu permission=android.permission.READ_EXTERNAL_STORAGE isImplicit=true result=4requestInfosLiveData.update()onUpdategetRequestInfosFromGroupStates()value = if (requestInfos.any { it.sendToSettingsImmediately }
@packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/GrantPermissionsActivity.javaonRequestInfoLoad                                            else if (requests.isEmpty()) {  mRequestInfos = requests;setResultAndFinish();return;showNextRequest();  //显示下一个权限请求if (mRequestInfos == null || mRequestInfos.isEmpty()) {  return;            

@packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/GrantPermissionsActivity.java onCreate @packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/GrantPermissionsViewHandlerImpl.kt mViewHandler = new com.android.permissioncontroller.permission.ui.handheld.GrantPermissionsViewHandlerImpl(this, mCallingPackage, Process.myUserHandle()).setResultListener(this); @packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/model/GrantPermissionsViewModel.kt mViewModel = factory.create(GrantPermissionsViewModel.class); return GrantPermissionsViewModel(app, packageName, requestedPermissions.toList(), sessionId, init { GlobalScope.launch(Main.immediate) { mViewModel.getRequestInfosLiveData().observe(this, this::onRequestInfoLoad); onRequestInfoLoad @packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/GrantPermissionsViewHandlerImpl.kt mRootView = mViewHandler.createView(); button!!.setOnClickListener(this) //弹出弹窗 GlobalScope.launch(Main.immediate) { val groups = packagePermissionsLiveData.getInitializedValue() for (gg in groups) { Log.w("xww", "xww init, gg=${gg}"); //gg=android.permission-group.CAMERA=[android.permission.CAMERA] //gg=android.permission-group.LOCATION=[android.permission.ACCESS_FINE_LOCATION, android.permission.ACCESS_COARSE_LOCATION, android.permission.ACCESS_BACKGROUND_LOCATION] for (requestedPerm in requestedPermissions) { Log.w("xww", "xww init, requestedPerm=$requestedPerm"); //requestedPerm=android.permission.CAMERA allAffectedPermissions.addAll(computeAffectedPermissions(requestedPerm, groups)) val extendedBySplitPerms = mutableListOf(perm) return extendedBySplitPerms unfilteredAffectedPermissions = allAffectedPermissions.toList() for (unfilteredAffectedPerm in unfilteredAffectedPermissions) { Log.w("xww", "xww init, unfilteredAffectedPerm=${unfilteredAffectedPerm}"); //unfilteredAffectedPerm=android.permission.CAMERA getAppPermGroups(groups.toMutableMap().apply { val requestedGroups = groups.filter { (_, perms) -> perms.any { it in unfilteredAffectedPermissions } //过滤出requestedGroups for (requestedGroup in requestedGroups) { Log.w("xww", "xww getAppPermGroups, requestedGroup=${requestedGroup}"); //getAppPermGroups, requestedGroup=android.permission-group.CAMERA=[android.permission.CAMERA] setSourcesToDifference(requestedGroups.keys, appPermGroupLiveDatas, getLiveDataFun) //viewModel,数据更新时调用onUpdate @packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/model/GrantPermissionsViewModel.kt onUpdate getRequestInfosFromGroupStates() requestInfos.add(RequestInfo(groupInfo, buttonVisibilities, locationVisibilities, message, detailMessage)) value = if (requestInfos.any { it.sendToSettingsImmediately } @packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/GrantPermissionsActivity.java onRequestInfoLoad mRequestInfos = requests; for(int i=0; i< requests.size(); i++){ Log.w(LOG_TAG, "xww onRequestInfoLoad 5, i=" + i + " requests.getGroupName=" + requests.get(i).getGroupName()); //onRequestInfoLoad 5, i=0 requests.getGroupName=android.permission-group.CAMERA showNextRequest(); @packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/GrantPermissionsViewHandlerImpl.kt mViewHandler.updateUi(info.getGroupName(), mTotalRequests, mCurrentRequestIdx, icon, message, detailMessage, mButtonVisibilities, mLocationVisibilities); Log.v("xww", "xww updateUi groupName=$groupName") this.groupName = groupName //1. 设置groupName, 2处用到 //updateUi groupName=android.permission-group.CAMERA @frameworks/base/core/java/android/view/Window.java getWindow().setDimAmount(mOriginalDimAmount); // mOriginalDimAmount=0.6 mHaveDimAmount = true; //点击allow按键 @packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/GrantPermissionsViewHandlerImpl.kt onClick ALLOW_BUTTON -> if (resultListener != null) { @packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/GrantPermissionsActivity.java resultListener!!.onPermissionGrantResult(groupName, affectedForegroundPermissions,GRANTED_ALWAYS) //2. 获取groupName, 1处设置 Log.w(LOG_TAG, "xww onPermissionGrantResult 2, name=" + name + " result=" + result + " affectedForegroundPermissions=" + affectedForegroundPermissions); //onPermissionGrantResult 2, name=android.permission-group.CAMERA result=1 affectedForegroundPermissions=null logGrantPermissionActivityButtons(name, affectedForegroundPermissions, result); @packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/model/GrantPermissionsViewModel.kt mViewModel.onPermissionGrantResult(name, affectedForegroundPermissions, result); GRANTED_ALWAYS -> { onPermissionGrantResultSingleState(foregroundGroupState, affectedForegroundPermissions, granted = true, isOneTime = false, doNotAskAgain = false) @packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/utils/KotlinUtils.kt KotlinUtils.grantForegroundRuntimePermissions(app, groupState.group, groupState.affectedPermissions, isOneTime) return grantRuntimePermissions(app, group, true, false, filterPermissions) for (permName in filterPermissions) { val (newPerm, shouldKill) = grantRuntimePermission(app, perm, isOneTime, group) @frameworks/base/core/java/android/permission/PermissionManager.java app.packageManager.grantRuntimePermission(group.packageName, perm.name, user) @frameworks/base/services/core/java/com/android/server/pm/permission/PermissionManagerService.java mPermissionManager.grantRuntimePermission(packageName, permissionName, user.getIdentifier()); grantRuntimePermissionInternal(packageName, permName, overridePolicy, callingUid, userId, mDefaultPermissionCallback); callback.onPermissionGranted(uid, userId); //通过PermissionCallback将权限申请结果回调给PKMS,PermissionCallback是在PKMS实现的 mOnPermissionChangeListeners.onPermissionsChanged(uid); mPackageManagerInt.writeSettings(true); reportRequestResult(groupState.affectedPermissions, result) //打印log for (perm in permissions) { reportRequestResult(perm, result) Log.v(LOG_TAG, "Permission grant result requestId=$sessionId " + "callingUid=${packageInfo.uid} callingPackage=$packageName permission=$permission " + "isImplicit=$isImplicit result=$result") //Permission grant result requestId=-7157070073027897334 callingUid=10058 callingPackage=com.example.androidimu permission=android.permission.WRITE_EXTERNAL_STORAGE isImplicit=false result=4 //Permission grant result requestId=-7157070073027897334 callingUid=10058 callingPackage=com.example.androidimu permission=android.permission.READ_EXTERNAL_STORAGE isImplicit=true result=4 requestInfosLiveData.update() onUpdate getRequestInfosFromGroupStates() value = if (requestInfos.any { it.sendToSettingsImmediately } @packages/modules/Permission/PermissionController/src/com/android/permissioncontroller/permission/ui/GrantPermissionsActivity.java onRequestInfoLoad else if (requests.isEmpty()) { mRequestInfos = requests; setResultAndFinish(); return; showNextRequest(); //显示下一个权限请求 if (mRequestInfos == null || mRequestInfos.isEmpty()) { return;

http://www.xdnf.cn/news/3329.html

相关文章:

  • 多通道经颅电刺激器的主流厂家介绍
  • hadoop集群建立
  • 【keil使用】无法打开keil工程,只有空白界面的解决方法
  • rk3568安全启动功能实践
  • 介绍一下Files类的常用方法
  • 车辆检测新突破:VFM-Det 如何用大模型提升识别精度
  • LVGL -按键介绍 上
  • Nginx 重写与重定向配置
  • SpringBoot集成Druid启动报错testWhileIdle is true, validationQuery not set
  • 【功能】根据时区获取开服天数
  • 4:机器人目标识别无序抓取程序二次开发
  • 深度学习正则化:原理、方法与应用深度解析
  • 【Linux服务器安装杀毒软件】
  • 利用v0与Cursor优化开发流程和效率
  • Unity 粒子同步,FishNet
  • 高等数学-第七版-下册 选做记录 习题9-6
  • 2025年4月AI科技领域周报(4.21-4.27):大模型生态加速演进 通用AI开启产业融合新范式
  • Java批量数据处理唯一ID生成优化
  • 如何用AI生成假期旅行照?
  • CUDA编程 - 如何使用 CUDA 流在 GPU 设备上并发执行多个内核 - 如何应用到自己的项目中 - concurrentKernels
  • 希尔伯特第十问题:是一个伪命题
  • 【android bluetooth 案例分析 03】【PTS 测试 】【PBAP/PCE/SSM/BV-10-C】
  • 用.net动态创建类的实例指南方案
  • MoonBit支持国产芯片开发--性能媲美C
  • 从零开始学Python游戏编程47-二维数组1
  • 一种基于光源评估并加权平均的自动白平衡方法(一)
  • 系统分析师-第十五章
  • nacos和redis本地启动
  • 小米MiMo推理大模型开源:7B参数规模超越更大规模模型
  • flutter开发音乐APP(简单的音乐播放demo)