Android 系统应用升级的坑
基于業(yè)務(wù)需要,Android平板用戶應(yīng)用要變成系統(tǒng)應(yīng)用,而且是桌面應(yīng)用的唯一入口(關(guān)機開機后的應(yīng)用界面)。
平板root之后,基于應(yīng)用的改變?yōu)橄到y(tǒng)都有現(xiàn)成的說明,主要核心是將系統(tǒng)簽名后的應(yīng)用 adb push *****.apk /system/app中,當(dāng)提示
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)
主要是權(quán)限未開放,需要掛載處理? 直接
adb shell
mount -o remount,rw /system
exit
重新輸入adb push *****.apk /system/app 等到傳輸完,打開手機應(yīng)用快的話,你會看到應(yīng)用突然就冒出來了,不行你就重啟。
下面重點來了,用戶應(yīng)用改變成系統(tǒng)應(yīng)用之后,升級咋辦?
一開始思路,就是想辦法下載的應(yīng)用直接覆蓋/system/app下目標(biāo)apk,? 問題開始出來了,之前在用戶應(yīng)用里面實現(xiàn)的下載模塊提示下載失敗,打開目錄查閱發(fā)現(xiàn)根本沒有對應(yīng)的文件,原來把下載目錄改成/system/app下? 沒有權(quán)限無法讀寫。
又考慮下載到公有目錄下,然后直接拷貝到/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);}}走不通,因為發(fā)現(xiàn)無論是rm? cp? 還是adb push 都無法改變當(dāng)前版本的信息。
各種資料查閱,測試驗證之后,發(fā)現(xiàn)靜默安裝可以解決問題
/*** 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
發(fā)現(xiàn)一開始自己的思路就出現(xiàn)了問題,所以后面死胡同走不通。
不是要覆蓋整個system/app里面的應(yīng)用,而是走自己的一套升級流程。例如當(dāng)前版本1.0.1,你首次安裝通過push推進到手機里,通過靜默升級(升級下載系統(tǒng)簽名安裝包的路徑也要是公有的)到1.0.2之后, 你使用的一直都是1.0.2,后面再次升級也只是覆蓋1.0.2,而永遠都不會覆蓋1.0.1。但是1.0.1還是存在的,當(dāng)你通過設(shè)置頁面刪除應(yīng)用也只是刪除1.0.2或更高版本的應(yīng)用, 1.0.1還是存在的。類似于恢復(fù)出廠設(shè)置的應(yīng)用原理
?
總結(jié)
以上是生活随笔為你收集整理的Android 系统应用升级的坑的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android系统应用之Settings
- 下一篇: Android系统应用