安卓靜默安裝之shell命令實現(需要root許可權)
阿新 • • 發佈:2019-01-23
現在很多應用比如360衛士,很多應用市場都搞後臺的靜默安裝.對於靜默安裝,首先需要裝置已經root了, 不然只能依賴系統自帶的安裝了.(之前在網上論壇看到有評論說不root也能實現靜默安裝,但最近了解下還是沒研究出來,也許是我研究的不夠深入吧,後面繼續學習這方面的東西.) ,實現一般使用隱藏的PM介面, 或者shell命令.
關於隱藏api去實現 這篇文章已經寫得很仔細,所以這裡選擇了後者.當然在網上看了不少文章也很多人實現. 所以這裡算是總結學習的經驗並加入一些修改.儘量完整的記錄下來.讓我們一起來學習吧~
public class MainActivity extends Activity { //將某個包名為com.test.install的應用xxx.apk放在手機內建儲存的根目錄中 private String appPath = "/mnt/sdcard/xxx.apk"; private String appPackgeName = "com.test.install"; private Button btn_ins,btn_unins; private String cmd_install = "pm install -r "; //靜默安裝命令 private String cmd_uninstall = "pm uninstall "; //靜默解除安裝命令 String apkLocation = Environment.getExternalStorageDirectory().toString() + "/"; private Process process; private DataOutputStream dos; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn_ins = (Button)findViewById(R.id.btn_install); btn_unins = (Button)findViewById(R.id.btn_uninstall); //安裝 btn_ins.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { install(); } }); //解除安裝 btn_unins.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { uninstall(); } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } public void install() { String cmdStr = cmd_install + apkLocation + appPath; System.out.println("靜默安裝命令:" + cmdStr); excute(cmdStr); } public void uninstall() { String cmdStr = cmd_uninstall + appPackgeName; System.out.println("靜默解除安裝命令:" + cmdStr); excute(cmdStr); } /** * 檢測裝置是否已Root * @return */ private boolean ifDeviceRoot(){ boolean result = false; try { if ((!new File("/system/bin/su").exists()) && (!new File("/system/xbin/su").exists())) { result = false; return result; } else { result = true; return result; } } catch (Exception e) { e.printStackTrace(); } return result; } protected int excute(String cmdStr) { if(ifDeviceRoot()){ //已root Toast.makeText(MainActivity.this, "裝置已Root", 1000).show(); try { //得到Process物件,這裡執行su命令是為了獲取root許可權.如果沒有root許可權就無法進行靜默安裝了. process = Runtime.getRuntime().exec("su"); dos = new DataOutputStream( (OutputStream) process.getOutputStream()); // 部分手機Root之後Library path 丟失,匯入path可解決該問題 dos.writeBytes((String) "export LD_LIBRARY_PATH=/vendor/lib:/system/lib\n"); cmdStr = String.valueOf(cmdStr); dos.writeBytes((String) (cmdStr + "\n")); dos.flush(); dos.writeBytes("exit\n"); dos.flush(); //阻塞程序,等待安裝完成 process.waitFor(); //值為0表示程序正常終止,當返回0 表示靜默安裝已結束 //若返回其他值代表失敗,通常表示大於0的對應的未終止異常執行緒數,比如1就是有1個程序未終止 int result = process.exitValue(); return (Integer) result; } catch (Exception e) { e.printStackTrace(); return -1; }finally{ try { if (dos != null) { dos.close(); } process.destroy(); } catch (Exception e) { e.printStackTrace(); } } }else{ //裝置沒有root,則呼叫系統的應用安裝頁面(請參考上篇文章) return 0; } } }
整體就是檢測裝置是否已root,如果已root 則進行靜默安裝,沒root就彈出頁面呼叫系統的安裝方法.