在安卓系统的机制里面 ,只要是将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;
    }