微信朋友圈被折疊?會自動化不存在的(下)
點擊上方“AirPython”,選擇“加為星標”
第一時間關注 Python 原創(chuàng)干貨!

1. 前言
上篇文章,我們使用無障礙自動化服務實現(xiàn)了微信朋友圈內容防折疊的效果
但使用一段時間后,發(fā)現(xiàn)這種方式并不靈活!
主要體現(xiàn)在:
不靈活,偶爾會誤處理
在手機系統(tǒng)及 UI 元素層面,適配性不強
本篇將介紹另外一種實現(xiàn)方式,即:開發(fā)一款簡易的輸入法,適配性強且方便快捷!
PS:如果想直接下載體驗,可以通過文末方式獲取
2. 步驟
2-1? 創(chuàng)建鍵盤服務
首先,使用 Android Studio 創(chuàng)建一個項目(這里以 JAVA 為例,Kotlin 類似)
然后,自定義一個系統(tǒng)鍵盤輸入服務類
繼承于?InputMethodService
實現(xiàn)?KeyboardView.OnKeyboardActionListener 接口,并重寫方法
/***
?*?自定義系統(tǒng)鍵盤輸入服務
?*/
package?com.xingag.inputx;
import?android.inputmethodservice.InputMethodService;
import?android.inputmethodservice.KeyboardView;
/***
?*?自定義系統(tǒng)鍵盤輸入服務
?*/
public?class?CustomService?extends?InputMethodService?implements?KeyboardView.OnKeyboardActionListener
{
????@Override
????public?void?onPress(int?primaryCode)
????{
????}
????@Override
????public?void?onRelease(int?primaryCode)
????{
????}
????@Override
????public?void?onKey(int?primaryCode,?int[]?keyCodes)
????{
????}
????@Override
????public?void?onText(CharSequence?text)
????{
????}
????@Override
????public?void?swipeLeft()
????{
????}
????@Override
????public?void?swipeRight()
????{
????}
????@Override
????public?void?swipeDown()
????{
????}
????@Override
????public?void?swipeUp()
????{
????}
}
2-2? Manifest 配置鍵盤服務
在 AndroidManifest.xml 文件中,配置鍵盤服務,并在?service 的 meta-data 中引用元數(shù)據(jù)
<service
????android:name=".CustomService"
????android:permission="android.permission.BIND_INPUT_METHOD">
????<intent-filter>
????????<action?android:name="android.view.InputMethod"?/>
????intent-filter>
????<meta-data
????????android:name="android.view.im"
????????android:resource="@xml/method"?/>
service>
元數(shù)據(jù)定義在 res/xml 目錄下,內容如下:
<input-method?xmlns:android="http://schemas.android.com/apk/res/android">
input-method>
需要注意的是,元數(shù)據(jù)文件可以通過 subtype 標簽指定語言類型、鍵盤模型;為了方便,這里使用默認配置即可
2-3? 鍵盤布局文件
在 res/layout 創(chuàng)建一個鍵盤布局文件
指定鍵區(qū)的背景色、按鍵文字大小、按鍵點擊前后顏色背景等屬性
<android.inputmethodservice.KeyboardView?xmlns:android="http://schemas.android.com/apk/res/android"
????android:id="@+id/keyboard_view"
????android:layout_width="match_parent"
????android:layout_height="wrap_content"
????android:layout_alignParentBottom="true"
????android:focusable="true"
????android:focusableInTouchMode="true"
????android:keyBackground="@drawable/selector_key_background"
????android:keyPreviewOffset="0dp"
????android:keyTextColor="#000000"
????android:background="#b0b0b0"
????android:keyTextSize="20sp"
????android:shadowColor="@android:color/transparent"
????android:shadowRadius="0"?/>
接著,在 res/xml 中創(chuàng)建鍵盤按鍵展示的內容、布局、按鍵 Code 值
keyWidth:寬度;keyHeight:高度
horizontalGap/verticalGap:按鍵水平方向/垂直方向的間距
codes:按鍵的 Code 值,方便事件處理
keyLabel:按鍵上的文字展示內容
keyIcon:按鍵的圖標展示
isRepeatable:代表按鍵是可重復的,如果為 True,則長按可以重復觸發(fā)按鍵事件,默認值為 False
按鍵區(qū)定義了 4 個常見按鍵,分別對應:防折疊輸入、回退、長按清空、切換輸入法
<Keyboard?xmlns:android="http://schemas.android.com/apk/res/android"
????android:horizontalGap="1px"
????android:keyWidth="25%p"
????android:keyHeight="60dp"
????android:verticalGap="1px">
????<Row>
????????<Key
????????????android:codes="1"
????????????android:keyLabel="開始輸入"?/>
????????<Key
????????????android:codes="2"
????????????android:keyIcon="@mipmap/ic_back"?/>
????????
????????<Key
????????????android:codes="4"
????????????android:isRepeatable="true"
????????????android:keyEdgeFlags="right"
????????????android:keyIcon="@mipmap/ic_clear"
????????????android:popupCharacters="xag"?/>
????????<Key
????????????android:codes="3"
????????????android:keyLabel="切換輸入法"?/>
????Row>
????<Row>
????????<Key
????????????android:codes="0"
????????????android:keyWidth="100%p"
????????????android:keyHeight="60dp"
????????????android:keyEdgeFlags="right"
????????????android:keyLabel="防折疊輸入法(公眾號:AirPython)"?/>
????Row>
Keyboard>
2-4? 創(chuàng)建鍵盤視圖并設置監(jiān)聽
在鍵盤服務類中?onCreateInputView()?方法內,創(chuàng)建鍵盤視圖并設置監(jiān)聽
@Override
public?View?onCreateInputView()
{
????@SuppressLint("InflateParams")?KeyboardView?keyboard_view?=?(KeyboardView)?getLayoutInflater().inflate(R.layout.keyboard_view,?null);
????Keyboard?keyboard?=?new?Keyboard(this,?R.xml.keyboard);
????keyboard_view.setKeyboard(keyboard);
????keyboard_view.setOnKeyboardActionListener(this);
????//設置按鍵沒有時,點擊放大鏡顯示的效果
????setCandidatesViewShown(false);
????keyboard_view.setPreviewEnabled(false);
????return?keyboard_view;
}
默認創(chuàng)建的鍵盤,點擊按鍵時的放大鏡效果會影響美觀,建議通過?setCandidatesViewShown(false) 關閉它
2-5? 處理按鍵點擊事件
重寫 onKey(int key,int ints) 函數(shù),其中 key 代表鍵盤 Code,通過它可以進行不同的事件處理
首先,我們拿到輸入法的連接對象 InputConnection
使用它內置的?deleteSurroundingText() 方法即可以實現(xiàn)回退和長按清空的功能
InputConnection?inputConnection?=?getCurrentInputConnection();
if?(key?==?1)
{
????//獲取剪切板中的內容
????String?clipContent?=?getClipContent();
????//模擬輸入
????inputText(inputConnection,?clipContent);
}?else?if?(key?==?2)
{
????//回退
????inputConnection.deleteSurroundingText(1,?0);
}?else?if?(key?==?3)
{
????//切換輸入法
????Intent?intent?=?new?Intent(Settings.ACTION_INPUT_METHOD_SETTINGS);
????intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
????startActivity(intent);
}?else?if?(key?==?4)
{
????//清空
????inputConnection.deleteSurroundingText(1,?0);
}
對于朋友圈防折疊功能,我們依舊是分 2 步實現(xiàn)
首先,從系統(tǒng)剪切板中獲取文本數(shù)據(jù)
/***
?*?獲取系統(tǒng)剪貼板服務
?*?@return
?*/
public?String?getClipContent()
{
????ClipboardManager?clipboardManager?=?(ClipboardManager)?getSystemService(Context.CLIPBOARD_SERVICE);
????String?clipContent?=?"";
????if?(null?!=?clipboardManager)
????{
????????//?獲取剪貼板的剪貼數(shù)據(jù)集
????????ClipData?clipData?=?clipboardManager.getPrimaryClip();
????????if?(null?!=?clipData?&&?clipData.getItemCount()?>?0)
????????{
????????????//?從數(shù)據(jù)集中獲?。ㄕ迟N)第一條文本數(shù)據(jù)
????????????ClipData.Item?item?=?clipData.getItemAt(0);
????????????if?(null?!=?item)
????????????{
????????????????clipContent?=?item.getText().toString();
????????????}
????????}
????}
????return?clipContent;
}
接著,將文本內容進行切割,一個字符一個字符地模擬輸入
需要注意的是,可以通過指定睡眠時間,以控制輸入的速度
public?void?inputText(InputConnection?inputConnection,?String?clipContent)
{
????if?(TextUtils.isEmpty(clipContent))
????{
????????Toast.makeText(getApplicationContext(),?"粘貼板為空!",?Toast.LENGTH_SHORT).show();
????????return;
????}
????Log.d("xag",?"字符個數(shù)為:"?+?clipContent.length());
????for?(int?i?=?0;?i?????{
????????String?temp?=?clipContent.substring(i,?i?+?1);
????????Log.e("xag",?"輸入一次,輸入內容是:"?+?temp);
????????inputConnection.commitText(temp,?0);
????????//下面可以控制輸入的速度,這里設置間隔為0.1s
????????try
????????{
????????????Thread.sleep(100);
????????}?catch?(InterruptedException?e)
????????{
????????????e.printStackTrace();
????????}
????}
}3. 運行
由于項目中只存在一個?Service,不存在 Activity,這里需要配置項目運行參數(shù)

然后運行項目,在手機設置中開啟輸入法

最后,發(fā)布朋友圈的時候,切換到自定義的輸入法,點擊開始輸入即可
需要注意的是,手機系統(tǒng)不一樣,切換輸入法的方式不一致
比如:魅族就需要在設置中先打開,然后輸入的時候下拉狀態(tài)欄,最后選擇對應的輸入法

4. 最后
通過上面的步驟,即可以實現(xiàn)一個簡易版本的朋友圈防折疊輸入法!
當然,輸入法的布局、按鍵功能都可以進行自定義,以實現(xiàn)更加復雜的功能;受限于篇幅,不展開說明!
我已經(jīng)將 APK 上傳到后臺,關注公眾號,后臺回復「?1222?」即可獲得
如果你想獲取文中完整源碼,可以掃描文末的二維碼,加個人微信,備注「?輸入法源碼?」來獲取
如果你覺得文章還不錯,請大家?點贊、分享、留言?下,因為這將是我持續(xù)輸出更多優(yōu)質文章的最強動力!
