在安卓系统的机制里面 ,只要是将app复制到系统的system文件/system/app 文件夹中的app,都是系统应用(不可删除同时获取了系统的最高权限).在做开发的时候,有的情况需要获取到系统权限但是拿不到系统的签名(厂商编译源码时输出的),就会想到搞一下这个系统应用.
当然,要做这个操作,就必须得先root,不然是不可能做到的.
root的具体教程还请自行查询,毕竟机型以及刷机包版本种类太多了
以下操作为root成功以后
准备工作
- adb环境 打开命令行终端
adb version 查看 配置好环境变量直接使用 - 连接电脑进入手机root模式
这个操作也可以使用adb来完成
adb push demo.apk /sdcard/
进入手机的shell 命令行:
adb shell
然后切换root 用户
su root
这个"#"就是获得root权限的标志 - 解锁system分区
mount -o rw,remount,rw /system - 复制apk到system分区
cat /sdcard/demo.apk > /system/app/demo.apk
这里要罗嗦一下,有的手机厂商会修改这个system分区位置,我们可以在su root 命令后使用ls命令逐级查看 - 还原分区属性,只读
mount -o remount,ro -t remount,rw /system
关机重启, 这样自己的app就设置为系统app了.
[注]以上操作并不能保证app可以正常运行,需要对libs里文件进行copy
操作如下:
1.将app解压到一个文件夹如图
打开这个文件夹,里面会有三个文件夹,分别对应不同的 系统架构生成的 so文件 ,需要找到合适系统架构的的so文件,复制到 系统分区的lib 目录中去(/system/lib/)
重复以上步骤–>copy到/sdcard/ -->system分区解锁–>copy到目标文件 -->锁system分区
参考命令如下:
cat /sdcard/libsqlcipher.so > /system/lib/libsqlcipher.so
以上操作也可以使用代码实现如下:
public void setSysApp() {
final Runnable runnable = new Runnable() {
@Override
public void run() {
// 解锁系统分区
String s = "mount -o remount,rw -t yaffs2 /dev/block/mtdblock3 /system";
CMDUtils.upgradeRootPermission(s);
//
s="cat /sdcard/demo.apk > /system/app/demo.apk";
CMDUtils.upgradeRootPermission(s);
s="cat /sdcard/libsqlcipher.so > /system/lib/libsqlcipher.so";
CMDUtils.upgradeRootPermission(s);
s="mount -o remount,ro -t yaffs2 /dev/block/mtdblock3 /system ";
CMDUtils.upgradeRootPermission(s);
}
};
new ExecutorUtil(runnable).execute();
}
public class ExecutorUtil extends Thread{
final static ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
private Runnable runnable;
public ExecutorUtil(Runnable runnable){
this.runnable=runnable;
}
@Override
public void run() {
try{
Looper.prepare();
new Handler().post(runnable);//在子线程中直接去new 一个handler
Looper.loop();//这种情况下,Runnable对象是运行在子线程中的,可以进行联网操作,但是不能更新UI
}catch (Exception e){
e.printStackTrace();
}
}
public void execute() {
cachedThreadPool.execute(this);
}
}
// 获取系统权限的方式执行
public static String upgradeRootPermission(String cmd) {
Log.i(TAG, "执行开始");
//String pkgCodePath = "/sdcard";
Process process = null;
DataOutputStream os = null;
try {
process = Runtime.getRuntime().exec("su"); //切换到root帐号
os = new DataOutputStream(process.getOutputStream());
os.writeBytes(cmd + "\n");
os.writeBytes("exit\n");
os.flush();
process.waitFor();
StringBuilder successMsg = new StringBuilder();
StringBuilder errorMsg = new StringBuilder();
BufferedReader successResult = new BufferedReader(
new InputStreamReader(process.getInputStream()));
BufferedReader errorResult = new BufferedReader(
new InputStreamReader(process.getErrorStream()));
String s;
while ((s = successResult.readLine()) != null) {
successMsg.append(s);
}
while ((s = errorResult.readLine()) != null) {
errorMsg.append(s);
}
// cmdRsult = new CMD_Result(result, errorMsg.toString(),
// successMsg.toString());
Log.i(TAG, successMsg.toString() + "执行完成" + errorMsg.toString());
return successMsg.toString();
} catch (Exception e) {
Log.e(TAG, "异常 upgradeRootPermission: ", e);
} finally {
Log.i(TAG, "执行完成finally");
try {
if (os != null) {
os.close();
}
process.destroy();
} catch (Exception e) {
}
}
return null;
}