使用Shell調用ADB指令方式來點擊屏幕


1. 背景

老大最近有個需求要捕獲一些東西(具體不能細說),然后在需求的最關鍵的一個點就歸結到要點擊一下別的APP的一個指定位置.
在網上搜索安卓按鍵模擬。用了很多方式都不太好,最后鎖定了使用ADB調試的方案,向手機發送按鍵事件。剛好之前做過在Root權限下,用Java調用安卓底層的Linux Shell,然后執行pm指令使用Shell調用ADB指令.
使用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指令,只需向其中寫入相應字符串,這樣就快了很多。 下面貼出可用的代碼。要求設備已經Root,不需要其他任何特殊權限或簽名。由於用的是ADB指令,兼容性也不會有太大問題。首次運行程序時(其實也就是執行Runtime.exec(“su”)的時候),會請求Root權限。

/** * 用root權限執行Linux下的Shell指令 * */
public class RootShell {

    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");
    }
}

其他參考博客
地址1
地址2


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM