Android 系统应用升级的坑

基于业务需要,Android平板用户应用要变成系统应用,而且是桌面应用的唯一入口(关机开机后的应用界面)。

平板root之后,基于应用的改变为系统都有现成的说明,主要核心是将系统签名后的应用 adb push *****.apk /system/app中,当提示

adb: error: failed to copy 'ShenYue.apk' to '/system/app/*****.apk': remote Read-only file system
******apk: 0 files pushed. 25.1 MB/s (131056 bytes in 0.005s)

主要是权限未开放,需要挂载处理  直接

adb shell

mount -o remount,rw /system

exit

重新输入adb push *****.apk /system/app 等到传输完,打开手机应用快的话,你会看到应用突然就冒出来了,不行你就重启。

下面重点来了,用户应用改变成系统应用之后,升级咋办?

一开始思路,就是想办法下载的应用直接覆盖/system/app下目标apk,  问题开始出来了,之前在用户应用里面实现的下载模块提示下载失败,打开目录查阅发现根本没有对应的文件,原来把下载目录改成/system/app下  没有权限无法读写。

又考虑下载到公有目录下,然后直接拷贝到/system/app, 如下:

String paramString= "$ adb shell" +"\n"+
                        "$ su" +"\n"+
                        "# mount -o remount,rw /system" +"\n"+
                        //"# rm /system/app/ShenYue.apk" +"\n"+

*//*                        "# exit" +"\n"+

                        "$ adb push " + Constants.FILE_UPDATE_CLIENT_SAVE_PATH + Constants.FILE_CLIENT_NAME*//**//*//**//*data/DeepRead/ShenYue.apk*//**//* +" /system/app/ShenYue.apk" +"\n"+

                        "$ adb shell" +"\n"+
                        "$ su" +"\n"+*//*
                        " cp " + Constants.FILE_UPDATE_CLIENT_SAVE_PATH + Constants.FILE_CLIENT_NAME + " /system/app" + "\n" ;
                      //  "# mount -o remount,ro /system" +"\n"+
                        //"# am start -n com.yuanzong.deepread/.activity.SplashActivity" +"\n"+
                      //  "# exit" +"\n"+
                      //  "$ exit";
                if(RootCmd.haveRoot()){
                    if(RootCmd.execRootCmdSilent(paramString)==-1){
                        Toast.makeText(SplashActivity.this, "安装不成功", Toast.LENGTH_LONG).show();
                    }else{
                        Toast.makeText(SplashActivity.this, "安装成功", Toast.LENGTH_LONG).show();
                       // System.exit(0);
                    }
                }

走不通,因为发现无论是rm  cp  还是adb push 都无法改变当前版本的信息。

各种资料查阅,测试验证之后,发现静默安装可以解决问题

/**
 * install slient
 *
 * @param filePath
 * @return 0 means normal, 1 means file not exist, 2 means other exception error
 */
public static int installSilent(String filePath) {
    File file = new File(filePath);
    if (filePath == null || filePath.length() == 0 || file == null || file.length() <= 0 || !file.exists() || !file.isFile()) {
        return 1;
    }

    String[] args = { "pm", "install", "-r", filePath };
    ProcessBuilder processBuilder = new ProcessBuilder(args);
    java.lang.Process process = null;
    BufferedReader successResult = null;
    BufferedReader errorResult = null;
    StringBuilder successMsg = new StringBuilder();
    StringBuilder errorMsg = new StringBuilder();
    int result;
    try {
        process = processBuilder.start();
        successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));
        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);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            if (successResult != null) {
                successResult.close();
            }
            if (errorResult != null) {
                errorResult.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (process != null) {
            process.destroy();
        }
    }

    // TODO should add memory is not enough here
    if (successMsg.toString().contains("Success") || successMsg.toString().contains("success")) {
        result = 0;
    } else {
        result = 2;
    }
    Logg.d(TAG, "successMsg:" + successMsg + ", ErrorMsg:" + errorMsg);
    return result;
}

可以参考:https://blog.csdn.net/u013341672/article/details/69320412

发现一开始自己的思路就出现了问题,所以后面死胡同走不通。

不是要覆盖整个system/app里面的应用,而是走自己的一套升级流程。例如当前版本1.0.1,你首次安装通过push推进到手机里,通过静默升级(升级下载系统签名安装包的路径也要是公有的)到1.0.2之后, 你使用的一直都是1.0.2,后面再次升级也只是覆盖1.0.2,而永远都不会覆盖1.0.1。但是1.0.1还是存在的,当你通过设置页面删除应用也只是删除1.0.2或更高版本的应用, 1.0.1还是存在的。类似于恢复出厂设置的应用原理

 

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值