赞
踩
android本身有提供了一套输入文字的方法。
adb input text “hi yeshen”
但是缺点也是很直接,不能输入中文,看了下代码,是在sendText
那里直接发了键盘码,所以不能直接给中文
/**
* Convert the characters of string text into key event's and send to
* device.
*
* @param text is a string of characters you want to input to the device.
*/
private void sendText(int source, String text) {
StringBuffer buff = new StringBuffer(text);
boolean escapeFlag = false;
for (int i=0; i<buff.length(); i++) {
if (escapeFlag) {
escapeFlag = false;
if (buff.charAt(i) == 's') {
buff.setCharAt(i, ' ');
buff.deleteCharAt(--i);
}
}
if (buff.charAt(i) == '%') {
escapeFlag = true;
}
}
char[] chars = buff.toString().toCharArray();
KeyCharacterMap kcm = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
KeyEvent[] events = kcm.getEvents(chars);
for(int i = 0; i < events.length; i++) {
KeyEvent e = events[i];
if (source != e.getSource()) {
e.setSource(source);
}
injectKeyEvent(e);
}
}
强制输入中文会有报错
10-25 05:46:28.563 2827 2827 D AndroidRuntime: Calling main entry com.android.commands.input.Input
10-25 05:46:28.565 2827 2827 I Input : injectKeyEvent: KeyEvent { action=ACTION_DOWN, keyCode=KEYCODE_D, scanCode=0, metaState=0, flags=0x0, repeatCount=0, eventTime=235147, downTime=235147, deviceId=-1, source=0x101 }
10-25 05:46:28.566 2827 2827 I Input : injectKeyEvent: KeyEvent { action=ACTION_UP, keyCode=KEYCODE_D, scanCode=0, metaState=0, flags=0x0, repeatCount=0, eventTime=235147, downTime=235147, deviceId=-1, source=0x101 }
10-25 05:46:28.566 1722 1722 D EmojiAltPhysicalKeyDetector: onKeyUp() : KeyEvent { action=ACTION_UP, keyCode=KEYCODE_D, scanCode=0, metaState=0, flags=0x0, repeatCount=0, eventTime=235147, downTime=235147, deviceId=-1, source=0x101 }
10-25 05:46:28.566 1722 1722 D EmojiAltPhysicalKeyDetector: onKeyUp() : Not Mapped: 32
10-25 05:46:28.566 2827 2827 I Input : injectKeyEvent: KeyEvent { action=ACTION_DOWN, keyCode=KEYCODE_O, scanCode=0, metaState=0, flags=0x0, repeatCount=0, eventTime=235147, downTime=235147, deviceId=-1, source=0x101 }
10-25 05:46:28.566 2827 2827 I Input : injectKeyEvent: KeyEvent { action=ACTION_UP, keyCode=KEYCODE_O, scanCode=0, metaState=0, flags=0x0, repeatCount=0, eventTime=235147, downTime=235147, deviceId=-1, source=0x101 }
10-25 05:46:28.566 1722 1722 D EmojiAltPhysicalKeyDetector: onKeyUp() : KeyEvent { action=ACTION_UP, keyCode=KEYCODE_O, scanCode=0, metaState=0, flags=0x0, repeatCount=0, eventTime=235147, downTime=235147, deviceId=-1, source=0x101 }
10-25 05:46:28.566 1722 1722 D EmojiAltPhysicalKeyDetector: onKeyUp() : Not Mapped: 43
10-25 05:46:28.566 2827 2827 I Input : injectKeyEvent: KeyEvent { action=ACTION_DOWN, keyCode=KEYCODE_N, scanCode=0, metaState=0, flags=0x0, repeatCount=0, eventTime=235147, downTime=235147, deviceId=-1, source=0x101 }
10-25 05:46:28.567 2827 2827 I Input : injectKeyEvent: KeyEvent { action=ACTION_UP, keyCode=KEYCODE_N, scanCode=0, metaState=0, flags=0x0, repeatCount=0, eventTime=235147, downTime=235147, deviceId=-1, source=0x101 }
10-25 05:46:28.567 1722 1722 D EmojiAltPhysicalKeyDetector: onKeyUp() : KeyEvent { action=ACTION_UP, keyCode=KEYCODE_N, scanCode=0, metaState=0, flags=0x0, repeatCount=0, eventTime=235147, downTime=235147, deviceId=-1, source=0x101 }
10-25 05:46:28.567 1722 1722 D EmojiAltPhysicalKeyDetector: onKeyUp() : Not Mapped: 42
10-25 05:46:28.567 2827 2827 I Input : injectKeyEvent: KeyEvent { action=ACTION_DOWN, keyCode=KEYCODE_E, scanCode=0, metaState=0, flags=0x0, repeatCount=0, eventTime=235147, downTime=235147, deviceId=-1, source=0x101 }
10-25 05:46:28.567 2827 2827 I Input : injectKeyEvent: KeyEvent { action=ACTION_UP, keyCode=KEYCODE_E, scanCode=0, metaState=0, flags=0x0, repeatCount=0, eventTime=235147, downTime=235147, deviceId=-1, source=0x101 }
10-25 05:46:28.567 1722 1722 D EmojiAltPhysicalKeyDetector: onKeyUp() : KeyEvent { action=ACTION_UP, keyCode=KEYCODE_E, scanCode=0, metaState=0, flags=0x0, repeatCount=0, eventTime=235147, downTime=235147, deviceId=-1, source=0x101 }
10-25 05:46:28.567 1722 1722 D EmojiAltPhysicalKeyDetector: onKeyUp() : Not Mapped: 33
10-25 05:46:28.567 2827 2827 I Input : injectKeyEvent: KeyEvent { action=ACTION_DOWN, keyCode=KEYCODE_ENTER, scanCode=0, metaState=0, flags=0x0, repeatCount=0, eventTime=235147, downTime=235147, deviceId=-1, source=0x101 }
10-25 05:46:28.568 2827 2827 I Input : injectKeyEvent: KeyEvent { action=ACTION_UP, keyCode=KEYCODE_ENTER, scanCode=0, metaState=0, flags=0x0, repeatCount=0, eventTime=235147, downTime=235147, deviceId=-1, source=0x101 }
10-25 05:46:28.568 1722 1722 D EmojiAltPhysicalKeyDetector: onKeyUp() : KeyEvent { action=ACTION_UP, keyCode=KEYCODE_ENTER, scanCode=0, metaState=0, flags=0x0, repeatCount=0, eventTime=235147, downTime=235147, deviceId=-1, source=0x101 }
10-25 05:46:28.568 1722 1722 D EmojiAltPhysicalKeyDetector: onKeyUp() : Not Mapped: 66
10-25 05:46:28.568 2827 2827 D AndroidRuntime: Shutting down VM
10-25 05:46:28.568 2827 2827 E AndroidRuntime: *** FATAL EXCEPTION IN SYSTEM PROCESS: main
10-25 05:46:28.568 2827 2827 E AndroidRuntime: java.lang.NullPointerException: Attempt to get length of null array
10-25 05:46:28.568 2827 2827 E AndroidRuntime: at com.android.commands.input.Input.sendText(Input.java:180)
10-25 05:46:28.568 2827 2827 E AndroidRuntime: at com.android.commands.input.Input.run(Input.java:89)
10-25 05:46:28.568 2827 2827 E AndroidRuntime: at com.android.commands.input.Input.main(Input.java:59)
10-25 05:46:28.568 2827 2827 E AndroidRuntime: at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)
10-25 05:46:28.568 2827 2827 E AndroidRuntime: at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:275)
10-25 05:46:28.568 2827 2827 E AndroidRuntime: Error reporting crash
10-25 05:46:28.568 2827 2827 E AndroidRuntime: java.lang.RuntimeException: Bad file descriptor
10-25 05:46:28.568 2827 2827 E AndroidRuntime: at android.os.BinderProxy.transactNative(Native Method)
10-25 05:46:28.568 2827 2827 E AndroidRuntime: at android.os.BinderProxy.transact(Binder.java:561)
10-25 05:46:28.568 2827 2827 E AndroidRuntime: at android.os.ServiceManagerProxy.getService(ServiceManagerNative.java:123)
10-25 05:46:28.568 2827 2827 E AndroidRuntime: at android.os.ServiceManager.getService(ServiceManager.java:55)
10-25 05:46:28.568 2827 2827 E AndroidRuntime: at android.app.ActivityManagerNative$1.create(ActivityManagerNative.java:2607)
10-25 05:46:28.568 2827 2827 E AndroidRuntime: at android.app.ActivityManagerNative$1.create(ActivityManagerNative.java:2606)
10-25 05:46:28.568 2827 2827 E AndroidRuntime: at android.util.Singleton.get(Singleton.java:34)
10-25 05:46:28.568 2827 2827 E AndroidRuntime: at android.app.ActivityManagerNative.getDefault(ActivityManagerNative.java:84)
10-25 05:46:28.568 2827 2827 E AndroidRuntime: at com.android.internal.os.RuntimeInit$UncaughtHandler.uncaughtException(RuntimeInit.java:114)
10-25 05:46:28.568 2827 2827 E AndroidRuntime: at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:693)
10-25 05:46:28.568 2827 2827 E AndroidRuntime: at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:690)
有绕过的方法,基本的原理就是在系统上装一个输入法app,然后通过adb 发广播,广播中文,然后输入法app,收到广播后输入。
这几天玩了一下,有延迟,会重复输入,会输入超时(稳定性不高)。
考虑自己自己修改下 input
的源码,支持一个输入中文的选项。最多就是把中文输出到粘贴板,通过粘贴板中转。
动手改了一下,可以这样实现
git diff frameworks/base/cmds/input/src/com/android/commands/input/Input.java
diff --git a/frameworks/base/cmds/input/src/com/android/commands/input/Input.java b/frameworks/base/cmds/input/src/c
om/android/commands/input/Input.java
index 2a7c79b..35c1378 100644
--- a/frameworks/base/cmds/input/src/com/android/commands/input/Input.java
+++ b/frameworks/base/cmds/input/src/com/android/commands/input/Input.java
@@ -24,6 +24,11 @@ import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.MotionEvent;
+import android.content.IClipboard;
+import android.content.Context;
+import android.os.ServiceManager;
+import android.os.IBinder;
+
import java.util.HashMap;
import java.util.Map;
@@ -82,6 +87,13 @@ public class Input {
sendText(inputSource, args[index+1]);
return;
}
+ } else if(command.equals("chinese")){
+ if (length == 2) {
+ inputSource = getSource(inputSource, InputDevice.SOURCE_KEYBOARD);
+ Log.e(TAG,args[index+1]);
+ sendChinese(inputSource, args[index+1]);
+ return;
+ }
} else if (command.equals("keyevent")) {
if (length >= 2) {
final boolean longpress = "--longpress".equals(args[index + 1]);
@@ -142,6 +154,17 @@ public class Input {
showUsage();
}
+ private void sendChinese(int source, String text){
+ try{
+ android.content.ClipData clip = android.content.ClipData.newPlainText("label",text);
+ IBinder b = ServiceManager.getService("clipboard");
+ IClipboard.Stub.asInterface(b).setPrimaryClip(clip, "org.yeshen.system.app");
+ }catch(Exception e){
+ e.printStackTrace();
+ Log.e(TAG,e.getMessage());
+ }
+ }
+
/**
* Convert the characters of string text into key event's and send to
* device.
@@ -278,6 +301,7 @@ public class Input {
System.err.println();
System.err.println("The commands and default sources are:");
System.err.println(" text <string> (Default: touchscreen)");
+ System.err.println(" chinese <string> (Default: touchscreen)");
System.err.println(" keyevent [--longpress] <key code number or name> ..."
+ " (Default: keyboard)");
System.err.println(" tap <x> <y> (Default: touchscreen)");
git diff packages/inputmethods/LatinIME/java/src/com/android/inputmethod/latin/LatinIME.java
diff --git a/packages/inputmethods/LatinIME/java/src/com/android/inputmethod/latin/LatinIME.java b/packages/inputmet
hods/LatinIME/java/src/com/android/inputmethod/latin/LatinIME.java
index 25a5de2..a5f3d81 100644
--- a/packages/inputmethods/LatinIME/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/packages/inputmethods/LatinIME/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -101,6 +101,9 @@ import java.util.Locale;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nonnull;
+import android.view.inputmethod.InputConnection;
+import android.content.ClipData;
+import android.content.ClipboardManager;
/**
* Input method implementation for Qwerty'ish keyboard.
@@ -148,6 +151,8 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
// {@link #onEvaluateInputViewShown()}.
private boolean mIsExecutingStartShowingInputView;
+ private ClipboardManager.OnPrimaryClipChangedListener mClipChangedListener = null;
+
// Object for reacting to adding/removing a dictionary pack.
private final BroadcastReceiver mDictionaryPackInstallReceiver =
new DictionaryPackInstallBroadcastReceiver(this);
@@ -689,6 +694,10 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
unregisterReceiver(mRingerModeChangeReceiver);
unregisterReceiver(mDictionaryPackInstallReceiver);
unregisterReceiver(mDictionaryDumpBroadcastReceiver);
+ if(mClipChangedListener != null) {
+ ((ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE)
+ ).removePrimaryClipChangedListener(mClipChangedListener);
+ }
mStatsUtilsManager.onDestroy(this /* context */);
super.onDestroy();
}
@@ -749,6 +758,18 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
if (hasSuggestionStripView()) {
mSuggestionStripView.setListener(this, view);
}
+
+ if(mClipChangedListener == null){
+ final ClipboardManager clipboard = (ClipboardManager) this.getSystemService(Context.CLIPBOARD_SERVICE);
+ mClipChangedListener = new ClipboardManager.OnPrimaryClipChangedListener() {
+ public void onPrimaryClipChanged() {
+ String str = clipboard.getText().toString();
+ InputConnection ic = getCurrentInputConnection();
+ if (ic != null) ic.commitText(str, 1);
+ }
+ };
+ clipboard.addPrimaryClipChangedListener(mClipChangedListener);
+ }
}
@Override
就是把中文复制到粘贴板,然后输入法监听粘贴板变化,有变化就输出
值得注意的是,有空格的话,记得加反斜杠,举个栗子
adb shell input chinese "Yeshen\ 不在"
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。