title: [Android7.1][RK3399] 系统默认给予App权限的各种情况及对应测试方法 Platform: RK3399 有这样几种场景: 系统 App(比如作为用来替代原生Launcher的系统应用)需要默认给予所有的权限。 系统需要内置的第三方App(比如腾讯视频,蓦然认知,喜马拉雅这种)需要默认给它 危险权限和特殊权限。 如上修改便给予了 特殊权限包括 悬浮窗、修改系统 设置等。 被 signature 标记标记的权限类型,当 app 被系统签名的时候,这种类型的权限会直接赋予给 app 网上方法有很多,但是大部分都没写自己的系统环境,很是头疼。 方法一:framework 中修改 PackageManagerService.java 方法二:修改 DatabaseHelper.java。//未测试,待验证。 write_settings_permission_custom_packagename 需要去 xml 里面定义一下。 方法三:RK 的补丁。修改的工程较大。 在这个方法里针对指定的 package,删掉所有权限,再增加指定权限(grantDefaultOtherAllPermissions)。 方法四:修改 framework 中各个权限的 protectionLevel。不推荐。 测试有效,但会引起很多Bug,比如点击 设置 里面的某些内容的时候会闪退。 我们以 PACKAGE_USAGE_STATS 为例。比如在 关注 protectionLevel: signature :Base permission type: a permission that the system is to grant only if the requesting application is signed with the same certificate as the application that declared the permission. If the certificates match, the system automatically grants the permission without notifying the user or asking for the user’s explicit approval. 所以将特殊权限修改为危险权限后,配合方法一使用即可。 方法五:使用 grantRuntimePermissionsLPw 授予特殊权限。 关注 protectionLevel:dangerous Base permission type: a higher-risk permission that would give a requesting application access to private user data or control over the device that can negatively impact the user. Because this type of permission introduces potential risk, the system may not automatically grant it to the requesting application. For example, any dangerous permissions requested by an application may be displayed to the user and require confirmation before proceeding, or some other approach may be taken to avoid the user automatically allowing the use of such facilities. 关注 protectionLevel:signature|preinstalled|appop|pre23|development 参考https://blog.csdn.net/zhangyong7112/article/details/55097257 可以看到,不会弹出悬浮窗了。权限被直接给予。 略,各种标志前面都写了 这个权限比较特殊,App 默认是会跳转到设置的系统界面中去,需要用户手动打开开关进行设置。
date: 2020-5-12 21:00:00
tags: Android
OS: Android 7.1
Kernel: v4.4.126文章目录
需求描述
App 是 系统 App 或者是 第三方需要内置的 App;
权限 是 危险权限 或者是 特殊权限。
所以排列组合有四种场景。这里分别讨论。
包括危险权限(身体传感器,日历,摄像头,通讯录,地理位置,麦克风,电话,短信,存储空间)和特殊权限(悬浮窗、系统修改权限、访问使用记录权限)。
危险权限可以通过修改 DefaultPermissionGrantPolicy.java 实现;
系统权限可以通过系统签名实现。给系统应用权限
framework 中的修改 DefaultPermissionGrantPolicy.java 给系统应用危险权限
services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java @@ -607,6 +607,25 @@ final class DefaultPermissionGrantPolicy { grantRuntimePermissionsLPw(musicPackage, STORAGE_PERMISSIONS, userId); } + PackageParser.Package YounixPackage = getPackageLPr("com.younix.packagename"); + Log.d(TAG, "YounixPackage >> "); + if (YounixPackage != null) { + Log.d(TAG, "YounixPackage >> not null"); + grantRuntimePermissionsLPw(YounixPackage, PHONE_PERMISSIONS, userId); + grantRuntimePermissionsLPw(YounixPackage, CONTACTS_PERMISSIONS, userId); + grantRuntimePermissionsLPw(YounixPackage, LOCATION_PERMISSIONS, userId); + grantRuntimePermissionsLPw(YounixPackage, CALENDAR_PERMISSIONS, userId); + grantRuntimePermissionsLPw(YounixPackage, SMS_PERMISSIONS, userId); + grantRuntimePermissionsLPw(YounixPackage, MICROPHONE_PERMISSIONS, userId); + grantRuntimePermissionsLPw(YounixPackage, CAMERA_PERMISSIONS, userId); + grantRuntimePermissionsLPw(YounixPackage, SENSORS_PERMISSIONS, userId); + grantRuntimePermissionsLPw(YounixPackage, STORAGE_PERMISSIONS, userId); + }else{ + Log.d(TAG, "YounixPackage >> null"); + } + // Watches if (mService.hasSystemFeature(PackageManager.FEATURE_WATCH, 0)) { // Home application on watches
com.younix.packagename
这个系统 App 所有的普通权限。给系统应用特殊权限
直接签名即可。
根据 google 的文档:https://developer.android.google.cn/reference/android/R.attr#protectionLevel
signature :Base permission type: a permission that the system is to grant only if the requesting application is signed with the same certificate as the application that declared the permission. If the certificates match, the system automatically grants the permission without notifying the user or asking for the user’s explicit approval.验证方法
$ adb shell dumpsys package [Package_Name]
给第三方应用权限
给第三方内置应用危险权限
我搜集并逐一尝试,有的有效有的无效,最终采用的方法五,赶时间的可以直接跳过去看。
grantPermisisons 返回 true //测试有效 ,但是对于特殊权限无效services/core/java/com/android/server/pm/PackageManagerService.java @@ -1447,8 +1447,13 @@ public class PackageManagerService extends IPackageManager.Stub { InstallArgs args = data.args; PackageInstalledInfo parentRes = data.res; + /* final boolean grantPermisisons = (args.installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0; + */ + final boolean grantPermissions = true; + //modified by Younix @2020.05.12,第三方应用默认给予权限 + final boolean killApp = (args.installFlags & PackageManager.INSTALL_DONT_KILL_APP) == 0; final String[] grantedPermissions = args.installGrantPermissions;
参考的 https://blog.csdn.net/wangjicong_215/article/details/71601494
记录如下。
frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java @@ -2351,6 +2351,65 @@ class DatabaseHelper extends SQLiteOpenHelper { if (mUserHandle == UserHandle.USER_SYSTEM) { loadGlobalSettings(db); } + + //added by Younix @2020.05.18 + loadAppOpsPermission(); + } + + private void loadAppOpsPermission(){ + AppOpsManager appOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE); + PackageManager pm = mContext.getPackageManager(); + + //String[] apkString = {"net.imoran.main.launcher"}; + + final String []itemString = mContext.getResources() + .getStringArray(com.android.internal.R.array.system_alert_window_permission_disable_custom_packagename);//net.imoran.main.launcher + for (int i = 0; i < itemString.length; i++) { + try { + PackageInfo packageInfo = pm.getPackageInfo(itemString[i], + PackageManager.GET_DISABLED_COMPONENTS | + PackageManager.GET_UNINSTALLED_PACKAGES | + PackageManager.GET_SIGNATURES); + + appOpsManager.setMode(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, + packageInfo.applicationInfo.uid, itemString[i], AppOpsManager.MODE_ERRORED); + } catch (Exception e) { + Log.e(TAG, "Exception when retrieving package:", e); + } + } + + final String []itemStringExt = mContext.getResources() + .getStringArray(com.android.internal.R.array.system_alert_window_permission_custom_packagename); + for (int i = 0; i < itemStringExt.length; i++) { + try { + PackageInfo packageInfo = pm.getPackageInfo(itemStringExt[i], + PackageManager.GET_DISABLED_COMPONENTS | + PackageManager.GET_UNINSTALLED_PACKAGES | + PackageManager.GET_SIGNATURES); + + appOpsManager.setMode(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, + packageInfo.applicationInfo.uid, itemStringExt[i], AppOpsManager.MODE_ALLOWED); + } catch (Exception e) { + Log.e(TAG, "Exception when retrieving package:", e); + } + } + + final String []itemStringExt1 = mContext.getResources() + .getStringArray(com.android.internal.R.array.write_settings_permission_custom_packagename); + + for (int i = 0; i < itemStringExt1.length; i++) { + try { + PackageInfo packageInfo = pm.getPackageInfo(itemStringExt1[i], + PackageManager.GET_DISABLED_COMPONENTS | + PackageManager.GET_UNINSTALLED_PACKAGES | + PackageManager.GET_SIGNATURES); + + appOpsManager.setMode(AppOpsManager.OP_WRITE_SETTINGS, + packageInfo.applicationInfo.uid, itemStringExt1[i], AppOpsManager.MODE_ALLOWED); + } catch (Exception e) { + Log.e(TAG, "Exception when retrieving package:", e); + } + } }
核心思想是,增加了一个方法method public abstract boolean deleteOtherPermissions(int, java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
其实本质还是grantRuntimePermissionsLPw
。
参考:
https://developer.android.google.cn/guide/topics/manifest/permission-element
https://developer.android.google.cn/reference/android/R.attr#protectionLevel
因为保护级别包含基本权限类型以及零个或者多个标记。
“dangerous”保护级别没有标记。core/res/AndroidManifest.xml
中看到如下信息:2667 <!-- @SystemApi Allows an application to collect component usage 2668 ¦statistics 2669 ¦<p>Declaring the permission implies intention to use the API and the user of the 2670 ¦device can grant permission through the Settings application. --> 2671 <permission android:name="android.permission.PACKAGE_USAGE_STATS" 2672 android:protectionLevel="signature|privileged|development|appop" /> 2673 <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
privileged:Additional flag from base permission type: this permission can also be granted to any applications installed as privileged apps on the system image. Please avoid using this option, as the signature protection level should be sufficient for most needs and works regardless of exactly where applications are installed. This permission flag is used for certain special situations where multiple vendors have applications built in to a system image which need to share specific features explicitly because they are being built together.
development:Additional flag from base permission type: this permission can also (optionally) be granted to development applications.
根据方法三中 RK 的补丁。grantRuntimePermissionsLPw 是可以给予特殊权限的。
所以进行如下操作--- a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java +++ b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java @@ -87,6 +87,13 @@ final class DefaultPermissionGrantPolicy { private static final String ATTR_NAME = "name"; private static final String ATTR_FIXED = "fixed"; + private static final Set<String> YOUNIX_PERMISSIONS = new ArraySet<>(); + static { + YOUNIX_PERMISSIONS.add(Manifest.permission.PACKAGE_USAGE_STATS); + YOUNIX_PERMISSIONS.add(Manifest.permission.SYSTEM_ALERT_WINDOW); + YOUNIX_PERMISSIONS.add(Manifest.permission.WRITE_SETTINGS); + } + private static final Set<String> PHONE_PERMISSIONS = new ArraySet<>(); static { PHONE_PERMISSIONS.add(Manifest.permission.READ_PHONE_STATE); @@ -663,6 +670,7 @@ final class DefaultPermissionGrantPolicy { grantRuntimePermissionsLPw(YounixPackage, CAMERA_PERMISSIONS, userId); grantRuntimePermissionsLPw(YounixPackage, SENSORS_PERMISSIONS, userId); grantRuntimePermissionsLPw(YounixPackage, STORAGE_PERMISSIONS, userId); + grantRuntimePermissionsLPw(YounixPackage, YOUNIX_PERMISSIONS, userId); }else{ Log.d(TAG, "YounixPackage >> null"); }
第三方应用危险权限申请 PERMISSIONS_STORAGE
原理
674 <permission android:name="android.permission.READ_EXTERNAL_STORAGE" 675 android:permissionGroup="android.permission-group.STORAGE" 676 android:label="@string/permlab_sdcardRead" 677 android:description="@string/permdesc_sdcardRead" 678 android:protectionLevel="dangerous" />
测试APKdemo
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
private static String[] PERMISSIONS_STORAGE = { Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); requestDangerousPermission(); //requestOverlayPermission(); //requestWriteSettings(); } private void requestDangerousPermission() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE, REQUEST_PERMISSION_CODE); } } } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == REQUEST_PERMISSION_CODE) { for (int i = 0; i < permissions.length; i++) { Log.i("MainActivity", "申请的权限为:" + permissions[i] + ",申请结果:" + grantResults[i]); } } }
第三方应用特殊权限(悬浮窗)申请 SYSTEM_ALERT_WINDOW
原理
1726 <!-- Allows an app to create windows using the type 1727 ¦{@link android.view.WindowManager.LayoutParams#TYPE_SYSTEM_ALERT}, 1728 ¦shown on top of all other apps. Very few apps 1729 ¦should use this permission; these windows are intended for 1730 ¦system-level interaction with the user. 1731 1732 ¦<p class="note"><strong>Note:</strong> If the app 1733 ¦targets API level 23 or higher, the app user must explicitly grant 1734 ¦this permission to the app through a permission management screen. The app requests 1735 ¦the user's approval by sending an intent with action 1736 ¦{@link android.provider.Settings#ACTION_MANAGE_OVERLAY_PERMISSION}. 1737 ¦The app can check whether it has this authorization by calling 1738 ¦{@link android.provider.Settings#canDrawOverlays 1739 ¦Settings.canDrawOverlays()}. 1740 ¦<p>Protection level: signature --> 1741 <permission android:name="android.permission.SYSTEM_ALERT_WINDOW" 1742 android:label="@string/permlab_systemAlertWindow" 1743 android:description="@string/permdesc_systemAlertWindow" 1744 android:protectionLevel="signature|preinstalled|appop|pre23|development" />
signature:签名后可以自动给于此权限
preinstalled:这个权限可以给系统中预安装的应用程序
appop:此权限与用于控制访问权限的应用操作紧密相关
pre23:如果是 Build.VERSION_CODES.M 以下的 SDK,可以自动授予
development:这个权限可以给予开发中的应用程序测试APKdemo
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //myRequetPermission(); requestOverlayPermission(); //requestWriteSettings(); } private void requestOverlayPermission() { //Settings.canDrawOverlays(this) 检查是否有悬浮窗权限 if(!Settings.canDrawOverlays(this)){ //没有悬浮窗权限,跳转申请 Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION); startActivity(intent); } }
第三方应用特殊权限(修改系统设置)申请 WRITE_SETTINGS
原理
测试 APK demo
代码参考 https://www.jianshu.com/p/c3908cb3554d /** * 申请权限 */ private void requestWriteSettings() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { //大于等于23 请求权限 if ( !Settings.System.canWrite(getApplicationContext())) {//没有权限,进行申请 Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS); intent.setData(Uri.parse("package:" + getPackageName())); startActivityForResult(intent, REQUEST_CODE_WRITE_SETTINGS ); } else {//有了权限,具体的动作(比如调整系统亮度) Settings.System.putInt(getContentResolver(),Settings.System.SCREEN_BRIGHTNESS, progress); } }else{ //小于23直接设置 } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_CODE_WRITE_SETTINGS) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { //Settings.System.canWrite方法检测授权结果 if (Settings.System.canWrite(getApplicationContext())) { T.show("获取了权限"); }else{ T.show("您拒绝了权限"); } } } }
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算