下面列出了android.view.inputmethod.InputConnection#sendKeyEvent ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private void sendTab() {
InputConnection ic = getCurrentInputConnection();
boolean tabHack = isConnectbot() && mConnectbotTabHack;
// FIXME: tab and ^I don't work in connectbot, hackish workaround
if (tabHack) {
if (mModAlt) {
// send ESC prefix
ic.commitText(Character.toString((char) 27), 1);
}
ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN,
KeyEvent.KEYCODE_DPAD_CENTER));
ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP,
KeyEvent.KEYCODE_DPAD_CENTER));
ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN,
KeyEvent.KEYCODE_I));
ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP,
KeyEvent.KEYCODE_I));
} else {
sendModifiedKeyDownUp(KeyEvent.KEYCODE_TAB);
}
}
@Subscriber(value = @Param(value = IME_SEARCH_MESSAGE, sticky = false), thread = RunningThread.MAIN_THREAD)
public boolean inputSearchText(String text) {
if (text != null) {
InputConnection ic = getCurrentInputConnection();
if (ic != null) {
ic.commitText(text, 1);
// 需要额外点击发送
EditorInfo editorInfo = getCurrentInputEditorInfo();
if (editorInfo != null) {
int options = editorInfo.imeOptions;
final int actionId = options & EditorInfo.IME_MASK_ACTION;
switch (actionId) {
case EditorInfo.IME_ACTION_SEARCH:
sendDefaultEditorAction(true);
break;
case EditorInfo.IME_ACTION_GO:
sendDefaultEditorAction(true);
break;
case EditorInfo.IME_ACTION_SEND:
sendDefaultEditorAction(true);
break;
default:
ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER));
}
}
return true;
}
}
return false;
}
@Subscriber(value = @Param(value = IME_KEYCODE, sticky = false), thread = RunningThread.MAIN_THREAD)
public boolean inputKeyCode(int code) {
if (code != -1) {
InputConnection ic = getCurrentInputConnection();
if (ic != null) {
ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, code));
return true;
}
}
return false;
}
private void doBackspace() {
InputConnection ic = getInputConnection();
if (ic == null) return;
ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL));
ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DEL));
// We could also do this with inputConnection.deleteSurroundingText(1, 0)
// but then we would need to be careful of not deleting too much
// and not deleting half a surrogate pair.
// see https://developer.android.com/reference/android/view/inputmethod/InputConnection.html#deleteSurroundingText(int,%20int)
// see also https://stackoverflow.com/a/45182401
}
@Override
public void moveCursorLeft() {
InputConnection ic = getInputConnection();
if (ic == null) return;
ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_LEFT));
ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_LEFT));
}
@Override
public void moveCursorRight() {
InputConnection ic = getInputConnection();
if (ic == null) return;
ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_RIGHT));
ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_RIGHT));
}
@Override
public void moveCursorUp() {
InputConnection ic = getInputConnection();
if (ic == null) return;
ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_UP));
ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_UP));
}
@Override
public void moveCursorDown() {
InputConnection ic = getInputConnection();
if (ic == null) return;
ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_DOWN));
ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_DOWN));
}
private boolean sendAndroidKeyInternal(int keyCode) {
LogUtils.log(this, Log.VERBOSE, "sendAndroidKey: %d", keyCode);
InputConnection ic = getCurrentInputConnection();
if (ic == null) {
return false;
}
long eventTime = SystemClock.uptimeMillis();
if (!ic.sendKeyEvent(new KeyEvent(eventTime, eventTime,
KeyEvent.ACTION_DOWN, keyCode, 0 /*repeat*/))) {
return false;
}
return ic.sendKeyEvent(
new KeyEvent(eventTime, eventTime,
KeyEvent.ACTION_UP, keyCode, 0 /*repeat*/));
}
/**
* Mark text using SHIFT+DPAD
*
* @param con
* input connection
* @param keycode
* DPAD keycode
*/
private void markText(InputConnection con, int keycode) {
long now = SystemClock.uptimeMillis();
con.sendKeyEvent(new KeyEvent(now, now, KeyEvent.ACTION_DOWN,
KeyEvent.KEYCODE_SHIFT_LEFT, 0, 0));
con.sendKeyEvent(new KeyEvent(now, now, KeyEvent.ACTION_DOWN, keycode, 0,
KeyEvent.META_SHIFT_LEFT_ON));
con.sendKeyEvent(new KeyEvent(now, now, KeyEvent.ACTION_UP, keycode, 0,
KeyEvent.META_SHIFT_LEFT_ON));
con.sendKeyEvent(new KeyEvent(now, now, KeyEvent.ACTION_UP,
KeyEvent.KEYCODE_SHIFT_LEFT, 0, 0));
}
@Override
public boolean dispatchKeyEvent(final KeyEvent event) {
final int keyCode = event.getKeyCode();
final InputConnection connection = mInputConnection;
if (connection != null) {
if (isAttachToWindowWidget()) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
return false;
} else {
connection.sendKeyEvent(event);
hide(UIWidget.KEEP_WIDGET);
}
return true;
}
// Android Components do not support InputConnection.sendKeyEvent()
if (event.getAction() == KeyEvent.ACTION_DOWN) {
Log.e("reb", "key = " + KeyEvent.keyCodeToString(keyCode));
switch (keyCode) {
case KeyEvent.KEYCODE_DEL:
handleBackspace();
return true;
case KeyEvent.KEYCODE_ENTER:
case KeyEvent.KEYCODE_NUMPAD_ENTER:
handleDone();
return true;
case KeyEvent.KEYCODE_DPAD_LEFT:
moveCursor(-1);
return true;
case KeyEvent.KEYCODE_DPAD_RIGHT:
moveCursor(1);
return true;
default:
break;
}
if (event.getUnicodeChar() != 0) {
KeyCharacterMap map = event.getKeyCharacterMap();
String value = String.valueOf((char) map.get(keyCode, event.getMetaState()));
connection.commitText(value, 1);
return true;
}
}
}
return false;
}
@Override
public void onRelease(int primaryCode) {
InputConnection ic = getCurrentInputConnection();
KCommands commands = new KCommands(
this,
ic,
getCurrentInputEditorInfo(),
keys,
mAutoSpace,
mPassiveAggressive);
if(mSoundOnClick) {
playClick();
}
if(mVibrateOnClick) {
vibrate();
}
switch(primaryCode) {
case -5: //backspace
commands.d(1);
break;
case -6: //MAD
switchScreens();
break;
case 10: //enter
ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER));
ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_ENTER));
break;
case -201: //subtype switcher
switchIME();
break;
case -301: //settings
Intent i = new Intent(this, PrefsActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
break;
default:
String keyString = getKeyString(primaryCode);
if((keyString.startsWith("/") && keyString.contains("!"))) {
parseCommand(commands, keyString);
} else {
sendReply(commands, keyString);
}
break;
}
}
@Override
public void onKey(int primaryCode, int[] keyCodes) {
InputConnection ic = getCurrentInputConnection();
switch(primaryCode){
case PuffKeyboardView.KEYCODE_EDIT :
Intent intent = new Intent(this, DialogAcctList.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS | Intent.FLAG_ACTIVITY_CLEAR_TASK);
getApplicationContext().startActivity(intent);
stopSelf();
break;
case -11 :
ic.commitText(account, 1);
account = "";
break;
case -12:
ic.commitText(password, 1);
password = "";
break;
case -13:
ic.commitText(additional, 1);
additional = "";
break;
case Keyboard.KEYCODE_DONE:
ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER));
break;
case Keyboard.KEYCODE_DELETE:
ic.deleteSurroundingText(1, 0);
break;
case Keyboard.KEYCODE_MODE_CHANGE:
if(kv.getKeyboard() == symbolKeyboard || kv.getKeyboard() == symsftKeyboard) {
currentKeyboard = normalKeyboard;
} else {
currentKeyboard = symbolKeyboard;
}
kv.setKeyboard(currentKeyboard);
break;
case Keyboard.KEYCODE_SHIFT:
// if (kv.getKeyboard() == normalKeyboard) {
// caps = !caps;
// normalKeyboard.setShifted(caps);
// kv.invalidateAllKeys();
// }
if(currentKeyboard == shiftKeyboard) {
currentKeyboard = normalKeyboard;
} else {
currentKeyboard = shiftKeyboard;
}
kv.setKeyboard(currentKeyboard);
break;
case Keyboard.KEYCODE_ALT:
if (kv.getKeyboard() == symbolKeyboard) {
currentKeyboard = symsftKeyboard;
} else {
currentKeyboard = symbolKeyboard;
}
kv.setKeyboard(currentKeyboard);
break;
case -886 :
Toast.makeText(IMEService.this, "close", Toast.LENGTH_SHORT).show();
break ;
default:
char code = (char)primaryCode;
if (caps) {
code = Character.toUpperCase(code);
}
ic.commitText(String.valueOf(code),1);
break;
}
VibrateUtil.getStaticInstance(this).tick();
}
private void sendKeyDown(InputConnection ic, int key, int meta) {
long now = System.currentTimeMillis();
if (ic != null) ic.sendKeyEvent(new KeyEvent(
now, now, KeyEvent.ACTION_DOWN, key, 0, meta));
}
private void sendKeyUp(InputConnection ic, int key, int meta) {
long now = System.currentTimeMillis();
if (ic != null) ic.sendKeyEvent(new KeyEvent(
now, now, KeyEvent.ACTION_UP, key, 0, meta));
}
private void sendSpecialKey(int code) {
if (!isConnectbot()) {
commitTyped(getCurrentInputConnection(), true);
sendModifiedKeyDownUp(code);
return;
}
// TODO(klausw): properly support xterm sequences for Ctrl/Alt modifiers?
// See http://slackware.osuosl.org/slackware-12.0/source/l/ncurses/xterm.terminfo
// and the output of "$ infocmp -1L". Support multiple sets, and optional
// true numpad keys?
if (ESC_SEQUENCES == null) {
ESC_SEQUENCES = new HashMap<Integer, String>();
CTRL_SEQUENCES = new HashMap<Integer, Integer>();
// VT escape sequences without leading Escape
ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_HOME, "[1~");
ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_END, "[4~");
ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_PAGE_UP, "[5~");
ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_PAGE_DOWN, "[6~");
ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F1, "OP");
ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F2, "OQ");
ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F3, "OR");
ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F4, "OS");
ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F5, "[15~");
ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F6, "[17~");
ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F7, "[18~");
ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F8, "[19~");
ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F9, "[20~");
ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F10, "[21~");
ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F11, "[23~");
ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F12, "[24~");
ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FORWARD_DEL, "[3~");
ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_INSERT, "[2~");
// Special ConnectBot hack: Ctrl-1 to Ctrl-0 for F1-F10.
CTRL_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F1, KeyEvent.KEYCODE_1);
CTRL_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F2, KeyEvent.KEYCODE_2);
CTRL_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F3, KeyEvent.KEYCODE_3);
CTRL_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F4, KeyEvent.KEYCODE_4);
CTRL_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F5, KeyEvent.KEYCODE_5);
CTRL_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F6, KeyEvent.KEYCODE_6);
CTRL_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F7, KeyEvent.KEYCODE_7);
CTRL_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F8, KeyEvent.KEYCODE_8);
CTRL_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F9, KeyEvent.KEYCODE_9);
CTRL_SEQUENCES.put(-LatinKeyboardView.KEYCODE_FKEY_F10, KeyEvent.KEYCODE_0);
// Natively supported by ConnectBot
// ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_DPAD_UP, "OA");
// ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_DPAD_DOWN, "OB");
// ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_DPAD_LEFT, "OD");
// ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_DPAD_RIGHT, "OC");
// No VT equivalents?
// ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_DPAD_CENTER, "");
// ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_SYSRQ, "");
// ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_BREAK, "");
// ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_NUM_LOCK, "");
// ESC_SEQUENCES.put(-LatinKeyboardView.KEYCODE_SCROLL_LOCK, "");
}
InputConnection ic = getCurrentInputConnection();
Integer ctrlseq = null;
if (mConnectbotTabHack) {
ctrlseq = CTRL_SEQUENCES.get(code);
}
String seq = ESC_SEQUENCES.get(code);
if (ctrlseq != null) {
if (mModAlt) {
// send ESC prefix for "Alt"
ic.commitText(Character.toString((char) 27), 1);
}
ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN,
KeyEvent.KEYCODE_DPAD_CENTER));
ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP,
KeyEvent.KEYCODE_DPAD_CENTER));
ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN,
ctrlseq));
ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP,
ctrlseq));
} else if (seq != null) {
if (mModAlt) {
// send ESC prefix for "Alt"
ic.commitText(Character.toString((char) 27), 1);
}
// send ESC prefix of escape sequence
ic.commitText(Character.toString((char) 27), 1);
ic.commitText(seq, 1);
} else {
// send key code, let connectbot handle it
sendDownUpKeyEvents(code);
}
handleModifierKeysUp(false, false);
}
@Override
public void onRelease(int primaryCode) {
InputConnection ic = getCurrentInputConnection();
KCommands commands = new KCommands(
this,
ic,
getCurrentInputEditorInfo(),
keys,
mAutoSpace,
mPassiveAggressive);
if(mSoundOnClick) {
playClick();
}
if(mVibrateOnClick) {
vibrate();
}
switch(primaryCode) {
case -5: //backspace
commands.d(1);
break;
case -6: //MAD
switchScreens();
break;
case 10: //enter
ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER));
ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_ENTER));
break;
case -201: //subtype switcher
switchIME();
break;
case -301: //settings
Intent i = new Intent(this, PrefsActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
break;
default:
String keyString = getKeyString(primaryCode);
if((keyString.startsWith("/") && keyString.contains("!"))) {
parseCommand(commands, keyString);
} else {
sendReply(commands, keyString);
}
break;
}
}
/**
* Send the given key event code (as defined by {@link KeyEvent}) to the
* current input connection is a key down + key up event pair. The sent
* events have {@link KeyEvent#FLAG_SOFT_KEYBOARD KeyEvent.FLAG_SOFT_KEYBOARD}
* set, so that the recipient can identify them as coming from a software
* input method, and
* {@link KeyEvent#FLAG_KEEP_TOUCH_MODE KeyEvent.FLAG_KEEP_TOUCH_MODE}, so
* that they don't impact the current touch mode of the UI.
*
* <p>Note that it's discouraged to send such key events in normal operation;
* this is mainly for use with {@link android.text.InputType#TYPE_NULL} type
* text fields, or for non-rich input methods. A reasonably capable software
* input method should use the
* {@link android.view.inputmethod.InputConnection#commitText} family of methods
* to send text to an application, rather than sending key events.</p>
*
* @param keyEventCode The raw key code to send, as defined by
* {@link KeyEvent}.
*/
public void sendDownUpKeyEvents(int keyEventCode) {
InputConnection ic = getCurrentInputConnection();
if (ic == null) return;
long eventTime = SystemClock.uptimeMillis();
ic.sendKeyEvent(new KeyEvent(eventTime, eventTime,
KeyEvent.ACTION_DOWN, keyEventCode, 0, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
KeyEvent.FLAG_SOFT_KEYBOARD|KeyEvent.FLAG_KEEP_TOUCH_MODE));
ic.sendKeyEvent(new KeyEvent(eventTime, SystemClock.uptimeMillis(),
KeyEvent.ACTION_UP, keyEventCode, 0, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
KeyEvent.FLAG_SOFT_KEYBOARD|KeyEvent.FLAG_KEEP_TOUCH_MODE));
}
/**
* Send an down/up event
*
* @con connection to sent with
* @param key
* keycode
*/
private void typeKey(InputConnection con, int key) {
con.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, key));
con.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, key));
}