ADBKeyBoard:通过 ADB 实现 Android 虚拟键盘输入
项目描述
ADBKeyBoard 是一个创新的 Android 虚拟键盘输入法。它通过接收系统广播意图(Broadcast Intents)来执行输入命令,使得用户能够使用 ADB(Android Debug Bridge)直接向 Android 设备发送文本输入。该项目主要解决了标准 ADB input 命令无法输入 Unicode 字符(如中文、表情符号等)的问题,是自动化测试、设备批量操作和特殊字符输入场景的理想工具。
功能特性
ADB 驱动的文本输入:通过 ADB 命令直接发送任意文本到当前激活的输入框。
完整的 Unicode 字符支持:突破了原生adb shell input text命令的限制,可以输入包括中文、日文、韩文及 Emoji 在内的所有 Unicode 字符。
多种输入模式:
直接文本输入 (ADB_INPUT_TEXT)。
Base64 编码文本输入 (ADB_INPUT_B64),用于解决高版本 Android 系统的兼容性问题。
发送键位事件码 (ADB_INPUT_CODE),模拟物理按键(如删除、回车)。
发送编辑器动作 (ADB_EDITOR_CODE),如执行搜索、前往等动作。
发送 Unicode 字符码点 (ADB_INPUT_CHARS)。
发送组合键(Meta 键) (ADB_INPUT_MCODE),如 Ctrl+A。
清空文本 (ADB_CLEAR_TEXT)。
便捷的 ADB 控制:提供完整的 ADB 命令来启用、切换和重置输入法。
轻量级与易集成:APK 体积小,通过广播机制与系统交互,无需复杂的权限或后台服务。
安装指南
方法一:直接安装 APK(推荐)
从项目的 Release 页面下载最新的 ADBKeyboard.apk 文件。
连接 Android 设备并开启 USB 调试模式。
执行以下命令进行安装:
adb install ADBKeyboard.apk
复制代码
方法二:从源码构建
克隆仓库:
git clone https://github.com/senzhk/ADBKeyBoard.git cd ADBKeyBoard
复制代码
配置环境:
设置 ANDROID_HOME 环境变量指向你的 Android SDK 路径,例如:
export ANDROID_HOME=$HOME/Android/Sdk
复制代码
* 或者直接编辑项目根目录下的 `local.properties` 文件,添加 `sdk.dir=/path/to/your/Android/Sdk`。
复制代码
构建并安装:
启用键盘
安装后,需要通过 ADB 或系统设置启用并切换到此输入法。
通过 ADB 启用和切换:
# 启用ADBKeyBoard输入法adb shell ime enable com.android.adbkeyboard/.AdbIME# 将ADBKeyBoard设置为当前默认输入法adb shell ime set com.android.adbkeyboard/.AdbIME
复制代码
通过系统设置启用:进入设备的 设置 -> 系统 -> 语言和输入法 -> 虚拟键盘,找到并启用“ADBKeyBoard”。
使用说明
启用 ADBKeyBoard 后,即可通过发送广播意图(Broadcast Intents)来控制输入。
基础使用示例
发送普通文本 (可能在高版本 Android 上失效):
adb shell am broadcast -a ADB_INPUT_TEXT --es msg '你好嗎? Hello?'
复制代码
发送 Base64 编码的文本 (推荐,兼容性更好):
# Mac/Linux adb shell am broadcast -a ADB_INPUT_B64 --es msg `echo -n '你好嗎? Hello?' | base64` # Windows (需借助PowerShell或Python脚本处理Base64)
复制代码
发送按键事件 (如删除键,码值 67):
adb shell am broadcast -a ADB_INPUT_CODE --ei code 67
复制代码
发送编辑器动作 (如“前往”动作,码值 2):
adb shell am broadcast -a ADB_EDITOR_CODE --ei code 2
复制代码
发送 Unicode 字符码点 (发送“😸 Cat”):
adb shell am broadcast -a ADB_INPUT_CHARS --eia chars '128568,32,67,97,116'
复制代码
发送组合键 (如 Ctrl + A):
adb shell am broadcast -a ADB_INPUT_MCODE --es mcode '4096,29'
复制代码
清空当前输入框的所有文本:
adb shell am broadcast -a ADB_CLEAR_TEXT
复制代码
ADB 输入法管理命令
adb shell ime set com.nuance.swype.dtc/com.nuance.swype.input.IME
复制代码
核心代码
以下是项目核心类 AdbIME.java 的关键代码片段,展示了广播接收器的注册和消息处理逻辑。
package com.android.adbkeyboard;
import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.inputmethodservice.InputMethodService;import android.util.Base64;import android.util.Log;import android.view.InputDevice;import android.view.KeyEvent;import android.view.View;import android.view.inputmethod.ExtractedTextRequest;import android.view.inputmethod.InputConnection;
public class AdbIME extends InputMethodService { // 定义广播Action常量,用于识别不同类型的输入指令 private String IME_MESSAGE = "ADB_INPUT_TEXT"; private String IME_CHARS = "ADB_INPUT_CHARS"; private String IME_KEYCODE = "ADB_INPUT_CODE"; private String IME_META_KEYCODE = "ADB_INPUT_MCODE"; private String IME_EDITORCODE = "ADB_EDITOR_CODE"; private String IME_MESSAGE_B64 = "ADB_INPUT_B64"; private String IME_CLEAR_TEXT = "ADB_CLEAR_TEXT"; private BroadcastReceiver mReceiver = null;
@Override public View onCreateInputView() { // 加载一个简单的空视图作为输入法界面 View mInputView = getLayoutInflater().inflate(R.layout.view, null);
// 注册广播接收器,用于监听来自ADB的命令 if (mReceiver == null) { IntentFilter filter = new IntentFilter(IME_MESSAGE); filter.addAction(IME_CHARS); filter.addAction(IME_KEYCODE);
filter.addAction(IME_EDITORCODE); filter.addAction(IME_MESSAGE_B64); filter.addAction(IME_CLEAR_TEXT); mReceiver = new AdbReceiver(); registerReceiver(mReceiver, filter); } return mInputView; }
public void onDestroy() { // 服务销毁时,注销广播接收器以防止内存泄漏 if (mReceiver != null) unregisterReceiver(mReceiver); super.onDestroy(); }
// 内部广播接收器类,负责处理接收到的各种输入命令 class AdbReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // 处理普通文本输入命令 if (intent.getAction().equals(IME_MESSAGE)) { String msg = intent.getStringExtra("msg"); if (msg != null) { InputConnection ic = getCurrentInputConnection(); if (ic != null) ic.commitText(msg, 1); // 将文本提交到当前输入连接 } // 此处代码省略了处理元键(Meta Key)的部分逻辑 } // 其他Action(如IME_CHARS, IME_KEYCODE等)的处理逻辑在此类中继续实现... } }}
复制代码
代码关键点解析:
继承 InputMethodService:AdbIME 类是 Android 输入法服务的基础,使其成为一个合法的系统输入法。
onCreateInputView 方法:在创建输入法视图时,初始化并注册一个 BroadcastReceiver (AdbReceiver)。它监听所有预定义的广播动作。
AdbReceiver 内部类:核心逻辑所在。其 onReceive 方法根据 Intent 的 Action 类型,提取附加数据(如文本、键值码),并通过 getCurrentInputConnection() 获取当前焦点输入框的连接,最终将输入内容提交 (commitText) 或执行相应动作。
生命周期管理:在 onDestroy 中注销广播接收器,这是 Android 开发中防止上下文泄漏的良好实践。
这段代码清晰地展示了 ADBKeyBoard 的工作原理:作为一个“无界面”的输入法,它主要依靠后台接收广播指令来工作,从而实现高度的自动化控制能力。更多精彩内容 请关注我的个人公众号 公众号(办公 AI 智能小助手)对网络安全、黑客技术感兴趣的朋友可以关注我的安全公众号(网络安全技术点滴分享)
公众号二维码
办公AI智能小助手
公众号二维码
网络安全技术点滴分享
评论