安卓使用Root許可權實現後台類比全域按鍵、觸屏事件方法(類似按鍵精靈),安卓root
安卓使用Root許可權實現後台類比全域按鍵、觸屏事件方法(類似按鍵精靈)
有時我們需要使用安卓實現在後台類比系統按鍵,比如對音量進行調節(類比音量鍵),關閉前台正在啟動並執行App(類比返回鍵),或者類比觸屏事件。但是對於原生安卓系統而言,後台進程關閉前台進程,甚至類比使用者事件,進而操控整個系統,是不符合系統安全原則的,如果有這樣的漏洞被病毒或惡意軟體所利用,會非常危險。
由於一些特殊原因,我恰巧需要實現這樣的功能,而又沒有條件自行編譯安卓系統(但是可以利用Root許可權,因為Root許可權的擷取相對簡單很多,並且很多使用者的安卓裝置都有Root過)。網上也看到很多人在提類似的問題,很多人討論了半天,結果都是無解。於是我花了很大精力,最後終於找到瞭解決方案。
在網上尋找了很多資料,主要找到兩種方法:Instrumentation和IWindowManager。
使用Instrumentation介面:對於非自行編譯的安卓系統,無法擷取系統簽名,只能在前台類比按鍵,不能後台類比。
一種是使用Instrumentation介面,這個介面原本是用來對軟體進行測試而留出來的。經過嘗試,發現這個介面可以類比按鍵,但是前提是在應用處於前台時。而應用處於前台時,類比按鍵基本上也沒有太大的作用(類比按鍵動作應用自身似乎沒有很大意義)。
當應用處於後台時,這個Instrumentation介面就失效了。網上找到的解釋是,在後台使用這個介面,需要有系統許可權,也就是在Manifest中添加android:sharedUserId="android.uid.system"。而這會導致什麼問題呢?聲明了系統許可權的APK,只有具有系統簽名的情況下,才能被安裝到安卓裝置上,比如系統內建的電話、簡訊,本質上也就是APK程式,但是這些應用具有系統許可權。
安卓系統有一套簽名機制,APK只有有了數位簽章,才能被安裝。通常調試時預設Eclipse自動對其進行簽名,使用的是Debug簽名。當發布應用時,開發人員則使用自己專屬的數位簽章檔案對APK進行簽名(這個檔案可以用Eclipse產生,簽名也可以讓Eclipse完成)。APK有新版本的安裝時,如果檢測到簽名不一致,系統會提示簽名不一致,只有卸載舊版本才能安裝。這一機制從一定程度上避免了第三方對官方發布的APK進行修改甚至非法植入病毒等行為(當然如果使用者主動卸載舊版本的官方應用、安裝新版本的非官方APK也是可以的)。而具有同一簽名的不同App,它們之間可以共用一些資料。
而系統簽名怎麼擷取呢?在編譯安卓系統的時候,會將一個系統簽名的數位簽章檔案放到一起編譯。對於一個已經編譯完成的系統,或者為了適配不同系統,必然無法擷取到這個數位簽章檔案,於是也無法對APK進行系統簽名。最後就導致具有uid.system屬性的APK無法被安裝,於是Instrumentation介面後台類比按鍵的方法,只能在自行編譯系統的情況下才可以使用。
使用反射方法調用系統IWindowManager隱藏API:相容性較差,穩定性不好,容易出錯。另外實際編譯時間發生錯誤,原因暫時不明。
網上還有一種方法。安卓系統中有一些隱藏API,通常是利用Java的許可權限制,使得這些API無法被調用。但通過反射的方式,可以突破Java的許可權限制。在IWindowManager中就隱藏了可以類比按鍵和觸屏事件的API。嘗試網上的方法,下載到一個由安卓源碼編譯好的jar檔案,添加到工程中,然後使用發射編寫了一些代碼,嘗試調用隱藏API。結果編譯的時候Eclipse直接不響應了,可能是因為電腦配置不夠,jar檔案太大。嘗試了幾次沒有成功,又考慮到這種方法有很多弊端,並且很可能最後還是需要系統許可權(網上不少文章說得不是很清楚),於是就放棄了這個方法。
android類比按鍵問題總結[使用IWindowManager.injectKeyEvent方法]
http://blog.csdn.net/xudongdong99/article/details/8857173
Android中使用隱藏API(大量圖解)
http://163liufuliang.blog.163.com/blog/static/331651862013119114431760/
JNI調用C程式類比按鍵:仍然是許可權問題。
參考了網上一些資料所提出的可能的思路,發現剩下能想到的方法就是用JNI實現,通過調用C/C++程式來類比按鍵。對Linux底層編程不熟悉,網上參考了一些代碼,在Ubuntu下編寫了一個按鍵類比程式,很順利的編譯運行通過。然後又開始學習JNI的編譯方法,先在C程式層寫了個簡單的加法運算,編譯運行測試通過,然後就把類比按鍵的代碼貼了進去。滿懷期待的寫好安卓Java層代碼,編譯、下載、執行程式,卻發現完全沒有效果。
想看一下到底是哪一步出錯了,就在C程式裡面改了改,用LogCat列印出C程式的返回值,發現在開啟按鍵裝置的時候出錯,看來肯定又是許可權的問題了。
儘管系統已經Root,APK也允許使用Root許可權,但是Root許可權沒法傳遞給C程式,許可權不夠,程式無法執行。在網上找了一通有關Linux、安卓許可權的資料,也沒找出來什麼思路。其實當時很疑惑,在Linux系統中,Root許可權是最高的許可權,安卓也不例外,有文章指出,Root許可權>系統許可權>使用者權限。儘管能擷取到Root許可權,卻不能完成系統許可權所能完成的任務,總感覺不應該。
安卓按鍵精靈:使用Root許可權而不需系統簽名,實現後台類比按鍵和觸屏等事件是可行的。
當時很絕望,感覺估計只有自行編譯系統才能解決問題了。就在那時候,突然想起了按鍵精靈軟體。以前用過電腦版,在安卓市場一找,果然也有安卓版。下載使用發現,按鍵精靈就可以實現在後台類比按鍵動作,需要Root許可權,但是是什麼原理卻不得而知。本想嘗試反編譯源碼查看,但是當時出了一些問題,反編譯沒有成功。在網上搜尋安卓按鍵精靈的原理,除了之前的那兩種依賴源碼環境才能使用的API,也沒有找到結果。不過至少說明了,使用Root許可權而不需要系統簽名,實現類比按鍵、並且相容大量安卓裝置是可行的。
最終解決問題:使用Shell調用ADB指令實現。
繼續在網上搜尋安卓按鍵類比(其實那時都不知道用什麼關鍵字好了,能想到的關鍵字都用遍了,但是搜尋出來的結果,都是之前提到的那幾個依賴源碼環境和系統許可權的方案)。發現有很多介紹ADB調試,向手機發送按鍵事件的文章。剛好之前做過在Root許可權下,用Java調用安卓底層的Linux Shell,然後執行pm指令進行APK的安裝卸載。這時我突發奇想,能否用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指令 * * @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");}}
寫這篇文章的主要目的,並不是要強調這件事的難度,也不只是為了提出問題的解決方案(那樣就沒必要寫前面那麼多過程了)。而是想把我解決問題的過程完整的寫出來,對我而言算是一個記錄,對讀者而言,沒準能從中找到一些東西。
解決這個問題之後,後來意外的發現,這個問題其實有人已經解決了,並且發了部落格。不幸的是,那篇部落格被大量使用前兩種思路的部落格掩埋了,當時我怎麼也沒找到。這篇部落格地址在此:
http://blog.csdn.net/aminfo/article/details/7785975
順便說明一點,這篇部落格中作者提到的缺點:反應速度較慢。前面提到我也越到了同樣的問題,也已經給出瞭解決方案。
本文由PurpleSword(jzj1993)原創,轉載請註明原文網址 http://blog.csdn.net/jzj1993
安卓平台,個動作記錄,定時播放的工具,類似按鍵精靈
你用的是手機按器吧?不是手機版的按鍵精靈吧?手機版的按鍵精靈也是用電腦編程的,要手機串連到電腦上,好像手機小幫手一樣。電腦上編寫指令碼再在手機上啟動並執行。名字是手機按鍵啊。並且現在正在內測期間,當然也因為比較新的軟體,不會被遊戲和諧。你要想用一下。可以到按鍵精靈官方找到手機按鍵的內測群,裡面有。
魅族MX類似按鍵精靈的不用ROOT的軟體
您好,
對於按鍵的控制軟體都是要ROOT的。魅族MX在flyme1.1.7韌體是不可以root的。您可以更新到MX的最新系統(內建ROOT選項)www.meizu.com/...ype=mx開啟設定-賬戶-更多-取得系統root許可權,建議您不要開啟root最高許可權,那樣可能會造成系統不穩定或個人資料丟失的風險。
魅族企業平台[官方認證]