点击上方“AirPython”,选择“加为星标”
第一时间关注 Python 原创干货!
1. 前言
上篇文章,我们使用无障碍自动化服务实现了微信朋友圈内容防折叠的效果
但使用一段时间后,发现这种方式并不灵活!
主要体现在:
不灵活,偶尔会误处理
在手机系统及 UI 元素层面,适配性不强
本篇将介绍另外一种实现方式,即:开发一款简易的输入法,适配性强且方便快捷!
PS:如果想直接下载体验,可以通过文末方式获取
2. 步骤
2-1 创建键盘服务
首先,使用 Android Studio 创建一个项目(这里以 JAVA 为例,Kotlin 类似)
然后,自定义一个系统键盘输入服务类
继承于 InputMethodService
实现 KeyboardView.OnKeyboardActionListener 接口,并重写方法
/***
* 自定义系统键盘输入服务
*/
package com.xingag.inputx;
import android.inputmethodservice.InputMethodService;
import android.inputmethodservice.KeyboardView;
/***
* 自定义系统键盘输入服务
*/
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 中引用元数据
<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>
元数据定义在 res/xml 目录下,内容如下:
<?xml version="1.0" encoding="utf-8"?>
<input-method xmlns:android="http://schemas.android.com/apk/res/android">
</input-method>
需要注意的是,元数据文件可以通过 subtype 标签指定语言类型、键盘模型;为了方便,这里使用默认配置即可
2-3 键盘布局文件
在 res/layout 创建一个键盘布局文件
指定键区的背景色、按键文字大小、按键点击前后颜色背景等属性
<?xml version="1.0" encoding="utf-8"?>
<!--系统键盘,键区样式都一致-->
<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 中创建键盘按键展示的内容、布局、按键 Code 值
keyWidth:宽度;keyHeight:高度
horizontalGap/verticalGap:按键水平方向/垂直方向的间距
codes:按键的 Code 值,方便事件处理
keyLabel:按键上的文字展示内容
keyIcon:按键的图标展示
isRepeatable:代表按键是可重复的,如果为 True,则长按可以重复触发按键事件,默认值为 False
按键区定义了 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 创建键盘视图并设置监听
在键盘服务类中 onCreateInputView() 方法内,创建键盘视图并设置监听
@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;
}
默认创建的键盘,点击按键时的放大镜效果会影响美观,建议通过 setCandidatesViewShown(false) 关闭它
2-5 处理按键点击事件
重写 onKey(int key,int ints) 函数,其中 key 代表键盘 Code,通过它可以进行不同的事件处理
首先,我们拿到输入法的连接对象 InputConnection
使用它内置的 deleteSurroundingText() 方法即可以实现回退和长按清空的功能
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 步实现
首先,从系统剪切板中获取文本数据
/***
* 获取系统剪贴板服务
* @return
*/
public String getClipContent()
{
ClipboardManager clipboardManager = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
String clipContent = "";
if (null != clipboardManager)
{
// 获取剪贴板的剪贴数据集
ClipData clipData = clipboardManager.getPrimaryClip();
if (null != clipData && clipData.getItemCount() > 0)
{
// 从数据集中获取(粘贴)第一条文本数据
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", "字符个数为:" + clipContent.length());
for (int i = 0; i < clipContent.length(); 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,这里需要配置项目运行参数
然后运行项目,在手机设置中开启输入法
最后,发布朋友圈的时候,切换到自定义的输入法,点击开始输入即可
需要注意的是,手机系统不一样,切换输入法的方式不一致
比如:魅族就需要在设置中先打开,然后输入的时候下拉状态栏,最后选择对应的输入法
4. 最后
通过上面的步骤,即可以实现一个简易版本的朋友圈防折叠输入法!
当然,输入法的布局、按键功能都可以进行自定义,以实现更加复杂的功能;受限于篇幅,不展开说明!
我已经将 APK 上传到后台,关注公众号,后台回复「 1222 」即可获得
如果你想获取文中完整源码,可以扫描文末的二维码,加个人微信,备注「 输入法源码 」来获取
如果你觉得文章还不错,请大家 点赞、分享、留言 下,因为这将是我持续输出更多优质文章的最强动力!
加个人微信,获取源码