安卓使用Root權限實現後臺模擬全局按鍵、觸屏事件方法(相似按鍵精靈)

繼續在網上搜索安卓按鍵模擬(其實那時都不知道用什麼關鍵字好了,能想到的關鍵字都用遍了,可是搜索出來的結果,都是以前提到的那幾個依賴源碼環境和系統權限的方案)。發現有不少介紹ADB調試,向手機發送按鍵事件的文章。恰好以前作過在Root權限下,用Java調用安卓底層的Linux Shell,而後執行pm指令進行APK的安裝卸載。這時我突發奇想,可否用Shell調用ADB指令呢?shell

因而就進行了嘗試,使用Java執行Runtime.getRuntime().exec("su").getOutputStream(),獲取了一個具備Root權限的Process的輸出流對象,向其中寫入字符串便可以Root權限被Shell執行,ADB模擬按鍵的指令爲 "input keyevent keyCode",keyCode爲按鍵的鍵值,例如KeyEvent.KEYCODE_VOLUME_UP表示音量加。命令行

編譯完程序安裝執行,終於實現了預期的效果,當時很是高興。至於觸屏或鼠標事件,只要調用相應的ADB指令便可。可是有一點問題,就是反應速度很是慢,尤爲是連續模擬多個按鍵的時候,甚至會死機。而按鍵精靈運行的就至關流暢,我又開始好奇按鍵精靈是怎麼實現的。調試

後來終於仍是找到了緣由,模擬按鍵時,不該每次都調用Runtime.getRuntime().exec("su"),由於每次調用這個代碼的時候,都會獲取Runtime實例,而且執行"su"請求Root權限,反應就會很慢(個人理解是至關於每次都新開一個命令行窗口);而應該只是在一開始執行一次,並獲取一個OutputStream實例,後來每次執行一條Shell指令,只需向其中寫入相應字符串,這樣就快了不少。code

下面貼出可用的代碼。要求設備已經Root,不須要其餘任何特殊權限或簽名。因爲用的是ADB指令,兼容性也不會有太大問題。首次運行程序時(其實也就是執行Runtime.exec("su")的時候),會請求Root權限。對象

/** 
 * 用root權限執行Linux下的Shell指令 
 *  
 * @author jzj 
 * @since 2014-09-09 
 */  
public class RootShellCmd {  
  
    private OutputStream os;  
  
    /** 
     * 執行shell指令 
     *  
     * @param cmd 
     *            指令 
     */  
    public final void exec(String cmd) {  
        try {  
            if (os == null) {  
                os = Runtime.getRuntime().exec("su").getOutputStream();  
            }  
            os.write(cmd.getBytes());  
            os.flush();  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
  
    /** 
     * 後臺模擬全局按鍵 
     *  
     * @param keyCode 
     *            鍵值 
     */  
    public final void simulateKey(int keyCode) {  
        exec("input keyevent " + keyCode + "\n");  
    }  
}
相關文章
相關標籤/搜索