1. 程式人生 > >安卓靜默安裝之shell命令實現(需要root許可權)

安卓靜默安裝之shell命令實現(需要root許可權)

現在很多應用比如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就彈出頁面呼叫系統的安裝方法.