Android5.1系統(tǒng)通過包名給應(yīng)用開放系統(tǒng)權(quán)限的方法
常用的給應(yīng)用開放系統(tǒng)權(quán)限的方法是直接將該應(yīng)用做成系統(tǒng)應(yīng)用(即在AndroidManifest.xml文件里加上:android:sharedUserId="android.uid.system"),但是這種做法限制了應(yīng)用本身的自由,也就是說經(jīng)過系統(tǒng)簽名后的系統(tǒng)應(yīng)用只能夠在對應(yīng)的Android平臺上安裝使用,無法向其他應(yīng)用一樣放到Android市場里兼容所有的Android設(shè)備。
現(xiàn)在此介紹一種通過修改Android平臺系統(tǒng)層代碼,根據(jù)指定的應(yīng)用包名給對應(yīng)的應(yīng)用在該平臺上開放系統(tǒng)權(quán)限,這樣既不應(yīng)用應(yīng)用的兼容性,又解決了應(yīng)用想調(diào)用一些系統(tǒng)層接口而沒有權(quán)限的矛盾。
該方法的核心是:在ActivityManagerService的startProcessLocked接口中把uid和gid都改為0.
需要開放系統(tǒng)權(quán)限的包名:
1、net.forclass.fcstudent
2、com.ckl.launcher
3、com.creative.fcstudent
修改步驟:
1、應(yīng)用安裝在設(shè)備上之后,點擊啟動必定會調(diào)用ActivityManagerService的startProcessLocked接口來開啟一個新的進程,而給應(yīng)用開放系統(tǒng)權(quán)限目的其實就是使應(yīng)用能夠成為超級應(yīng)用,運行在系統(tǒng)進程中,這樣我們只需要在startProcessLocked接口里面將應(yīng)用的uid修改為0即可。
ActivityManagerService.java (frameworks\base\services\core\java\com\android\server\am)
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
// modified by haming patch begin, configure system permission for some special application.
if ("net.forclass.fcstudent".equals(info.packageName)
|| "com.ckl.launcher".equals(info.packageName)
|| "com.creative.fcstudent".equals(info.packageName)
|| "com.hampoo.hampoointerfacetestdemo".equals(info.packageName)){
info.uid = 0;
}
// modified by haming patch end.
long startTime = SystemClock.elapsedRealtime();
ProcessRecord app;
...... // 此處省略好多行
checkTime(startTime, "startProcess: stepping in to startProcess");
startProcessLocked( // 再次調(diào)用startProcessLocked重載方法
app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
checkTime(startTime, "startProcess: done starting proc!");
return (app.pid != 0) ? app : null;
}在重載方法startProcessLocked(ProcessRecord app, String hostingType,String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs)里面將應(yīng)用的gid也改為0:
private final void startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
long startTime = SystemClock.elapsedRealtime();
...... // 此處省略好多行
try {
int uid = app.uid;
int[] gids = null;
int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
if (!app.isolated) {
...... // 此處省略好多行
// modified by haming patch begin, configure system permission for some special application.
if ("net.forclass.fcstudent".equals(app.info.packageName)
|| "com.ckl.launcher".equals(app.info.packageName)
|| "com.creative.fcstudent".equals(app.info.packageName)
|| "com.hampoo.hampoointerfacetestdemo".equals(app.info.packageName)){
SystemProperties.set("sys.permission.enable", "true"); // 設(shè)置一個系統(tǒng)屬性,在Zygote進行判斷是否拋出異常
gids[0] = 0;
gids[1] = 0;
} else {
gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
}
// modified by haming patch end.
}
...... // 此處省略好多行
} catch (RuntimeException e) {
// XXX do better error recovery.
app.setPid(0);
mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
if (app.isolated) {
mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
}
Slog.e(TAG, "Failure starting process " + app.processName, e);
}
}
2、ZygoteConnection.java里的applyUidSecurityPolicy(Arguments args, Credentials peer, String peerSecurityContext)接口會對進程id進行判斷,如果小于Process.SYSTEM_UID(1000)則認為是非法,而zygote是具有root權(quán)限的唯一server,所有在判斷之后就可以通過讀取前面設(shè)定的系統(tǒng)屬性“sys.permission.enable”的值來決定是否拋出異常。
ZygoteConnection.java (frameworks\base\core\java\com\android\internal\os)
private static void applyUidSecurityPolicy(Arguments args, Credentials peer,
String peerSecurityContext)
throws ZygoteSecurityException {
int peerUid = peer.getUid();
if (peerUid == 0) {
// Root can do what it wants
} else if (peerUid == Process.SYSTEM_UID ) {
// System UID is restricted, except in factory test mode
String factoryTest = SystemProperties.get("ro.factorytest");
boolean uidRestricted;
/* In normal operation, SYSTEM_UID can only specify a restricted
* set of UIDs. In factory test mode, SYSTEM_UID may specify any uid.
*/
uidRestricted
= !(factoryTest.equals("1") || factoryTest.equals("2"));
// modified by haming patch begin, configure system permission for some special application.
if (uidRestricted
&& args.uidSpecified && (args.uid < Process.SYSTEM_UID)) {
if (!SystemProperties.getBoolean("sys.permission.enable", false)){
throw new ZygoteSecurityException(
"System UID may not launch process with UID < "
+ Process.SYSTEM_UID);
} else {
SystemProperties.set("sys.permission.enable", "false");
}
}
// modified by haming patch end.
} else {
// Everything else
if (args.uidSpecified || args.gidSpecified
|| args.gids != null) {
throw new ZygoteSecurityException(
"App UIDs may not specify uid's or gid's");
}
}
...... // 此處省略好多行
}
總結(jié)
以上所述是小編給大家介紹的Android5.1系統(tǒng)通過包名給應(yīng)用開放系統(tǒng)權(quán)限的方法,希望對大家有所幫助,如果大家有任何疑問歡迎給我留言!
- Android Studio 修改應(yīng)用包名實例詳解
- java批量采集豌豆莢網(wǎng)站Android應(yīng)用圖標和包名
- Android編程獲取APP應(yīng)用程序基本信息輔助類【APP名稱、包名、圖標,版本號等】
- Android獲取應(yīng)用版本號與版本名稱
- Android獲取手機型號/系統(tǒng)版本號/App版本號等信息實例講解
- Android獲取當前手機網(wǎng)絡(luò)類型(2g、3g、4g、wifi)以及手機型號、版本號代碼
- Android通過aapt命令獲取apk詳細信息(包括:文件包名,版本號,SDK等信息)
- 使用Java代碼來比較Android客戶端版本號
- Android 獲取未安裝的APK圖標、版本號、包名等信息方法
- Android編程實現(xiàn)應(yīng)用獲取包名、版本號、權(quán)限等信息的方法
相關(guān)文章
Android getSystemService用法實例總結(jié)
這篇文章主要介紹了Android getSystemService用法,結(jié)合實例形式總結(jié)分析了getSystemService獲取系統(tǒng)Service的相關(guān)使用方法與注意事項,需要的朋友可以參考下2016-01-01
Android學(xué)習教程之下拉刷新實現(xiàn)代碼(11)
這篇文章主要為大家詳細介紹了Android學(xué)習教程之下拉刷新實現(xiàn)代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-11-11

