有时候使用某些api需要使用系统权限,如调用PackageInstaller的相关接口,需要android.permission.INSTALL_PACKAGES权限,该权限系统只会授权给系统应用,此时可以考虑将我们的应用升级为系统应用,升级为系统应用有两种方法:
1、将apk放到/system/app目录下,重启手机即可,此方法比较粗暴,而且需要修改/system目录的读写权限,因此需要root,而且随着Android系统版本对权限管理越来越严,root和修改读写权限更繁琐和复杂
2、添加sharedUserId="android.uid.system"配置,同时使用系统签名对apk进行重签名,安装后即有系统权限,此方法需要获取到系统签名,但通常厂商开发的rom都不会公开签名,因此如果针对某些自己集成系统的需求,可以使用此方案。
下面针对第2种方案进行讲解。
1、首先需要在menifest文件中添加sharedUserId="android.uid.system"配置,如下
1
2
3<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.google.example" android:sharedUserId="android.uid.system">
2、添加需要的使用的系统权限,如
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
3、使用系统签名对apk进行签名,首先需要打未签名的包,Android Studio环境下点击右侧Gradle按钮,弹出目录,打开Tasks->build->assemble...,其中assemble开头的几项即是打包任务,双击相应项即可获取相应的包
接着要获取系统签名,找到系统签名文件“platform.pk8”和“platform.x509.pem”,在系统源码路径下
签名文件路径:android/build/target/product/security/
准备好签名工具:“signapk.jar”
位置:android/prebuilts/sdk/tools/lib
将未签名的apk、签名文件和签名工具放在同一路径下,开启终端,cd到该目录,运行如下命令即可得到带系统签名的apk
java -jar signapk.jar platform.x509.pem platform.pk8 Demo.apk signedDemo.apk
以上的方法相对还是比较繁琐,而且不便于调试,可以将系统签名打入keystore,使用该keystore即可在Android Studio环境下生成带系统签名的apk
1、首先需要生成keystore文件,生成过程在此省略,可自行百度
2、下载keytool-importkeypair,https://github.com/getfatday/keytool-importkeypair/
3、该操作需要linux系统,并安装jdk,win10环境下可以开启“基于Lunix的Windows子系统”,不需要去折腾安装虚拟机或者系统。当如,如果兄dei你已经有Linux系统或者是mac,那么恭喜你,省了很多需要折腾的步骤
4、将keystore、platform.pk8、platform.x509.pem、keytool-importkeypair放在同一目录下,开启终端,cd到此目录,运行如下命令即可将系统签名打入keystore
/keytool-importkeypair -k ./demo.keystore -p password -pk8 platform.pk8 -cert platform.x509.pem -alias demoAlias
解释:-P后接keystore密码,-alias后接key alias
5、运行结束即会在当前目录下生成带有系统签名的keystore,使用此keystore安装Android Studio打包流程打包即可得到带系统权限的apk
补充知识:Android 系统级应用守护进程
我就废话不多说了,还是直接看代码吧!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180--- a/frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java +++ b/frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java @@ -16,24 +16,51 @@ package com.android.systemui; +import android.app.ActivityManager; +import android.app.ActivityManager.RunningAppProcessInfo; import android.app.Application; import android.app.Instrumentation; import android.content.BroadcastReceiver; import android.content.Context; +import android.content.ComponentName; import android.content.Intent; import android.content.IntentFilter; import android.content.res.Configuration; +import android.database.ContentObserver; +import android.net.Uri; +import android.os.Build; +import android.os.Handler; import android.os.Process; import android.os.PowerManager; import android.os.SystemClock; import android.os.SystemProperties; import android.os.UserHandle; import android.util.Log; - +import java.util.List; +import java.util.Calendar; import com.android.systemui.stackdivider.Divider; import java.util.HashMap; import java.util.Map; +import java.util.Objects; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.PrintWriter; +import java.math.BigInteger; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Random; /** * Application class for SystemUI. @@ -42,6 +69,8 @@ public class SystemUIApplication extends Application { private static final String TAG = "SystemUIService"; private static final boolean DEBUG = false; + + private Context mContext; /** * The classes of the stuff to start. @@ -86,6 +115,8 @@ public class SystemUIApplication extends Application { // application theme in the manifest does only work for activities. Keep this in sync with // the theme set there. setTheme(R.style.systemui_theme); + + mContext = getApplicationContext(); SystemUIFactory.createFromConfig(this); @@ -143,6 +174,7 @@ public class SystemUIApplication extends Application { private static final String SETTING_SYSTEM = "tchip.provider.setting.system"; private static final String SETTING_SECURE = "tchip.provider.setting.secure"; private static final String SETTING_GLOBAL = "tchip.provider.setting.global"; + private static final String BROADCAST_SCREENSHOT = "rk.android.screenshot.action"; private String valueContent = "0"; private MainReceiver mainReceiver; @@ -150,6 +182,10 @@ public class SystemUIApplication extends Application { android.util.Log.i("AZ", log); } + private void LDLog(String log) { + android.util.Log.i("LD", log); + } + public class MainReceiver extends BroadcastReceiver { @Override @@ -225,6 +261,18 @@ public class SystemUIApplication extends Application { intentDown.putExtra("android.intent.extra.KEY_CONFIRM", false); intentDown.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intentDown); + } else if (BROADCAST_SCREENSHOT.equals(action)) { + Intent intentScreenShot = new Intent("android.intent.action.SCREENSHOT"); + intentScreenShot.putExtra("path", intentScreenShot.getExtras().getString("path")); + intentScreenShot.putExtra("name", intentScreenShot.getExtras().getString("name")); + context.sendBroadcast(intentScreenShot); + } else if (BROADCAST_TIMETICK.equals(action)) { + //checkLaidianAppAlive(); + try{ + mHandler.removeCallbacks(laidianAppR); + }catch(Exception e){ + } + mHandler.postDelayed(laidianAppR, 1000); } } } @@ -326,4 +374,82 @@ public class SystemUIApplication extends Application { public SystemUI[] getServices() { return mServices; } + + + Handler mHandler = new Handler(); + private int laidianAppCheckTime = 3000; + Runnable laidianAppR = new Runnable(){ + + @Override + public void run() { + checkAppAlive(pkgName", "clsName"); + mHandler.postDelayed(laidianAppR, laidianAppCheckTime); + } + + }; + + private void checkAppAlive(String pkgName, String clsName){ + long startTime = System.currentTimeMillis(); + if(!isAppAlive(pkgName)){ + LDLog("checkAppAlive.start to start app... "); + try{ + ComponentName componentName = new ComponentName(pkgName, clsName); + Intent intent = new Intent(); + intent.setComponent(componentName); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + mContext.startActivity(intent); + }catch(Exception e){ + + } + }else{ + LDLog("checkAppAlive.app is running... "); + } + LDLog("checkAppAlive.used time : " + (System.currentTimeMillis() - startTime)); + } + + public boolean isAppAlive(String packageName){ + //boolean isAlive = false; + //String command = "ps | grep " + packageName/* + " | busybox awk '{print $2}'"*/; + //String[] result = ExecCmd.getPackagePID(command); + //for(String str :result){ + // if(!"-1".equals(str)){ + // isAlive = true; + // } + //} + //return isAlive; + + // 获取正在运行的进程 + /*ActivityManager activityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); + List<RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses(); + + for (RunningAppProcessInfo appProcess : appProcesses) { + String[] pkgList = appProcess.pkgList; + for (String pckName : pkgList) { + if(packageName.equals(pckName)){ + return true; + } + + } + }*/ + ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE); + List<ActivityManager.RecentTaskInfo> recentTasks = am.getRecentTasks(30, ActivityManager.RECENT_IGNORE_UNAVAILABLE + | ActivityManager.RECENT_INCLUDE_PROFILES); + + for (ActivityManager.RecentTaskInfo recentInfo : recentTasks){ + //if (recentInfo.origActivity != null) { + String pckName = recentInfo.baseIntent.getComponent().getPackageName(); + LDLog("isAppAlive.packageName=" + pckName); + if(packageName.equals(pckName)){ + return true; + } + //} + } + return false; + } + }
以上这篇Android普通应用升级为系统应用并获取系统权限的操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持靠谱客。
最后
以上就是坚定微笑最近收集整理的关于Android普通应用升级为系统应用并获取系统权限的操作的全部内容,更多相关Android普通应用升级为系统应用并获取系统权限内容请搜索靠谱客的其他文章。
发表评论 取消回复