Android彈出系統自帶安全鍵盤的奇淫技巧

最近在做遠程控制功能,手機APP端控制電腦桌面端。有個功能是APP端輸入文本,顯示在電腦端輸入框內。由于當前遠程控制功能還在初級階段,只需實現輸入數字、英文大小寫字母、特殊符號和部分控制鍵,故只需要彈出一個安全鍵盤。

安全鍵盤在很多銀行APP里使用廣泛,一般用來輸入密碼。密碼通常是由數字、英文大小寫字母和特殊符號構成,沒有中文,所以輸入法鍵盤也就不需要支持語言切換,純英文鍵盤就可以。

一般來說,安全鍵盤可自定義,繼承KeyboardView然后設置自定義的布局文件(需要在xml目錄下自定義)。

但是在深入反編譯研究了TeamViewer的APK后發現,TeamViewer彈出的安全鍵盤并不是自定義的而是系統自帶的。有以下證據:

  1. 資源文件里沒有安全鍵盤相關的icon和字符串;
  2. 這個所謂的“安全鍵盤”的彈出動畫明顯區別于自定義的鍵盤,因為他的布局文件里在自定義的鍵盤上方加了一個工具條,在“安全鍵盤”彈出時可以看到工具條明顯的跳動,而自定義的鍵盤彈出時并沒有;
  3. 彈出這個“安全鍵盤”時,無法截屏,彈出自定義鍵盤時可以截屏。當然禁止截屏可以在代碼里通過
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE)實現,但是在全局搜索了反編譯之后的代碼并沒有發現,可見無法截屏應該是因為這個“安全鍵盤”導致的。
    安全鍵盤(因為無法截圖,只能拍照了)
自定義鍵盤

TeamViewer彈出的這個“安全鍵盤”完全滿足我們的需求,而且不用自定義,省去了很多繁瑣的工作。既然這樣,那么我們也嘗試彈出這個“安全鍵盤”吧。

不好意思,這個小功能點我斷斷續續做了兩天,還是無果。彈出來的輸入法永遠都是系統默認的搜狗。是我太菜了么?

搜狗鍵盤

當時我甚至在懷疑,這個“安全鍵盤”的xml布局文件是不是運行時動態地從服務器上下載的,導致我無法在反編譯的資源文件里找到一些線索。但轉念一想,這也不是什么機密文件,而且這個鍵盤布局也不需要更新變化(不像銀行的安全鍵盤,按鍵位置隨機變化)。然后我又仔仔細細的搜索了setKeyboard這個自定義鍵盤必須使用的方法,想著是不是有遺漏之處,依然毫無線索。

再結合前面說到的三條這個“安全鍵盤”是系統自帶的而不是自定義的證據,我再次確定,這個“安全鍵盤”確實是系統自帶的,一定是還有什么鍵盤屬性設置,被我遺漏了。

于是我又開始仔細看著枯燥的反編譯后的代碼文件。功夫不負有心人,在TeamViewer接收文字輸入的控件里(繼承了AutoCompleteTextView),他們重寫了onCreateInputConnection方法,里面有兩句配置:

paramEditorInfo.inputType = 524433;
paramEditorInfo.imeOptions = 268435457;

看到的第一眼,直覺告訴我,就是你們了。先不管這兩個數字看起來有多么奇怪,立馬先給自己的app加上再說,運行起來,打開一看,搞定!

興奮了幾分鐘,冷靜下來,準備繼續深入分析下去。

刪掉了paramEditorInfo.imeOptions = 268435457;這句后,依然可以彈出安全鍵盤。那么這個524433到底是何方神圣呢?

524433的16進制是0x80091EditorInfoinputType可以設置的類型在android.text.InputType這個類里,并沒有0x80091這個值,那么應該是多個value位運算后的結果。在InputType里湊了一會,發現是以下幾個:
TYPE_CLASS_TEXT(0x00000001),TYPE_TEXT_VARIATION_VISIBLE_PASSWORD(0x00000090)TYPE_TEXT_FLAG_NO_SUGGESTIONS(0x00080000)和。
完整的代碼是:

editorInfo.inputType = InputType.TYPE_CLASS_TEXT
                | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS;

TYPE_CLASS_TEXT一般和TYPE_TEXT_FLAG_NO_SUGGESTIONS一起使用來禁止輸入法鍵盤的智能提示功能(這個功能對暫時只支持輸入單個字符的遠程控制來說,確實不需要)。TYPE_TEXT_VARIATION_VISIBLE_PASSWORD這個用來讓密碼可見。嘗試了下設置inputType為單獨的TYPE_TEXT_VARIATION_VISIBLE_PASSWORD并不能彈出安全鍵盤,當然其他兩個更不行了。必須將inputType設置成InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS才能有效彈出安全鍵盤。

以上測試結果基于OPPO Reno。

后面又測試了Pixel,結果大跌眼鏡。Pixel根本彈不出所謂的安全鍵盤,不過也跟安全鍵盤無異。只是這個鍵盤就是默認的輸入法鍵盤,隨便寫一個EditText設置屬性android:inputType="none"就可以調出來。只是彈出這個鍵盤后,依舊可以截屏(因為就是一個普通的鍵盤)。

Pixel默認鍵盤

猜測是OPPO對輸入法做了魔改,禁用了系統自帶的默認鍵盤,改為了搜狗鍵盤。

假如說一開始就用Pixel做嘗試,就不會遇到彈不出“安全鍵盤”的問題,也就不會耽擱那么多時間來想方設法尋求解決方案。不過也正因如此,才發現了這么一些有趣的現象和解決方案。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容