一、权限动态申请 我们都知道,从 Android 6.0 开始,部分危险权限在 xml 注册的同时,还需要动态申请。 1、需要动态申请的权限 Manifest.permission.CONTACTS //联系人Manifes
我们都知道,从 Android 6.0 开始,部分危险权限在 xml 注册的同时,还需要动态申请。
Manifest.permission.CONTACTS //联系人Manifest.permission.PHONE //电话Manifest.permission.CALENDAR //日历Manifest.permission.CAMERA //相机Manifest.permission.SENSORS //传感器Manifest.permission.LOCATION //位置Manifest.permission.STORAGE //存储Manifest.permission.MICROPHONE //麦克风Manifest.permission.CONTACTS //短信
需要动态申请的权限主要分为这 9 类,当然每类中可能不止一个权限,但只要动态申请一个就默认获取整个类别的权限。
//常量,用于回调int MY_PERMISSION_APPLY = 1;//要使用的相机权限int permission = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA);//判断是否有相机权限if (permission == PackageManager.PERMISSION_GRANTED) { //有权限直接执行 } else { //没有权限,提示获取权限 String[] perms = {"android.permission.CAMERA"}; ActivityCompat.requestPermissions(this, perms, MY_PERMISSION_APPLY);}
在弹出权限申请后,需要对用户的选择结果进行处理,在回调方法中执行:
public void onRequestPermissionsResult(int permsRequestCode, String[] permissions, int[] grantResults){ switch(permsRequestCode){ case MY_PERMISSION_APPLY: boolean albuMaccepted = grantResults[0]==PackageManager.PERMISSION_GRANTED; if(!albumAccepted){ //用户拒绝了权限 }else{ //用户同意了权限 } break; }}
//常量,用于回调int MY_PERMISSION_APPLY = 1;//要使用的相机和存储权限String[] permissions = new String[]{ Manifest.permission.CAMERA, Manifest.permission.STORAGE };//用于存放未同意的权限List mPermissionList = new ArrayList<>(); //清空未同意权限mPermissionList.clear();//循环得到未同意权限for (int i = 0; i < permissions.length; i++) { if (ContextCompat.checkSelfPermission(mContext, permissions[i]) != PackageManager.PERMISSION_GRANTED) { mPermissionList.add(permissions[i]); }} //判断是否有未同意权限if (mPermissionList.isEmpty()) { //都有权限直接执行 } else { //将List转为数组 String[] permissions = mPermissionList.toArray(new String[mPermissionList.size()]); ActivityCompat.requestPermissions(this, permissions, MY_PERMISSION_APPLY);}
然后,同样添加上面的回调方法处理用户的选择结果。
需求:Android 11.0 版本,sdk 32,使用本地 Download 下文件,在申请动态权限后,仍然提示缺少权限问题。
我们都知道 Android 开发某些功能(文件读写)时需要在 Manifest.xml 中添加对应权限。才能对 Android 手机中的图片、文件等内容进行处理。Manifest.xml 中添加读写权限如下:
Android 6.0 时在 Manifest.xml 添加权限的同时,还需要在使用时动态申请权限,这个大家应该也很熟悉,这里仅展示权限申请代码,至于用户拒绝、不再提示等操作及回调不再展示。
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M && context.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED) {//请求权限 ((Activity)context).requestPermissions(new String[]{ Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE},1);}
Android 10.0 开启了作用域存储,即使完成了上面的 Manifest.xml 中添加权限和代码中动态申请权限,在访问包名以外的文件夹时,依旧提示权限不足。这时我们在 Manifest.xml 添加属性关闭作用域存储,这时谷歌官方提供的一个暂时解决方案。
Android 11.0 开始,作用域存储开始强制启用,上面的关闭方法不在起作用,这时如果还需要访问外部文件夹,就需要用户手动开启一个危险权限——外部存储权限。
Manifest.xml 新增外部存储权限
手动设置打开
该权限属于特殊权限需要用户手动去设置中打开,通过 Environment.isExternalStorageManager() 判断是否开启,未开启跳转设置开启界面。
public static boolean checkStorageManagerPermission(Context context) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && !Environment.isExternalStorageManager()) { Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION); context.startActivity(intent); return false; } return true;}
打开后就可以正常访问 Download 等共享目录了。
1)系统应用直接授予权限
2)使用指定签名第三方应用直接授予权限
3)使用普通签名第三方应用正常提示
系统 APP 可以直接修改 DefaultPermissionGrantPolicy.java 中的 grantDefaultSystemHandlerPermissions() 方法直接为系统应用配置默认权限。
限制条件:需要修改系统源码,所以第三方应用无法实现
文件位置:frameworks/base/services/core/java/com/android/server/pm/permission/
1)直接修改权限级别在 frameworks/base/core/res/AndroidManifest.xml 中将 dangerous(危险)权限修改为 nORMal(正常)权限,所有应用均直接获得权限,不适用上面需求。
2)将 dangerous(危险)权限修改为 Signature(签名)权限,这样指定签名APP可以获得权限,但第三方其他签名 APP 无法获取权限。
ps:是否可以设置同名权限:例如设置摄像头同名权限,级别 Signature,同签名自动拥有权限,其他第三方APP申请默认dangerous 摄像头权限弹出提示。
需要验证,感觉可行性不大。
PackageManagerService.java 的grantPermissionsLpw 中添加指定包名通过权限,网络上很多资料都可以找到该方法,但现在的源码中找到了该文件,未找到该方法。
ps:是否可以将上面的判断包名变成判断签名,待验证。
/frameworks/base/core/res/res/values/config.xml中增加包名白名单
/frameworks/base/core/res/res/values/symbols.xml中声明白名单变量
frameworks/base/services/core/java/com/android/server/pm/ permission/PermissionManagerService.java中的grantPermissions方法中判断权限白名单
参考:Android 9.0 设置白名单赋予应用权限 - 二的次方 - 博客园
该方法添加白名单也需要修改配置文件,所以第三方指定签名文件也无法直接得到权限。所有权限通过也不适用。
但通过源码逻辑发现,下面代码应该是APP系统签名判断方法:
if(bp.isSignature()){ allowedSig = grantSignaturePermission(perm, pkge, bp, origPermissions);}
所以上面的判断白名单可以改成判断签名通过权限,即:
if(bp.isRuntime()){ else{ allowedSig = grantSignaturePermission(perm, pkge, bp, origPermissions); if(allowedSig){ grant = GRANT_INSTALL; } }}
这样使用指定签名APP和系统APP都能跳过权限验证。
直接在 GrantPermissionsActivity 中弹框时判断处理,但是根据需求也需要进行签名验证。
在 AndroidManifest.xml 中自定义一个新权限,级别为Signature;
在DefaultPermissionGrantPolicy.java将新定义的权限加入权限组;
这样指定签名的应用直接获得了新权限,又因为同组权限只要有一个权限是通过状态,其他权限不在验证直接通过。
需要直接通过的APP需要使用指定签名,同时还需要申请我们自定义的新权限。
来源地址:https://blog.csdn.net/c19344881x/article/details/128920179
--结束END--
本文标题: Android 开发中的权限申请
本文链接: https://lsjlt.com/news/387679.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-01-21
2023-10-28
2023-10-28
2023-10-27
2023-10-27
2023-10-27
2023-10-27
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0