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 hereif (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還是存在的。類似于恢復出廠設置的應用原理
?
總結
以上是生活随笔為你收集整理的Android 系统应用升级的坑的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android系统应用之Settings
- 下一篇: Android系统应用