下面列出了android.view.KeyEvent#getDownTime ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Send a key event to the currently focused window/view and wait for it to
* be processed. Finished at some point after the recipient has returned
* from its event processing, though it may <em>not</em> have completely
* finished reacting from the event -- for example, if it needs to update
* its display as a result, it may still be in the process of doing that.
*
* @param event The event to send to the current focus.
*/
public void sendKeySync(KeyEvent event) {
validateNotAppThread();
long downTime = event.getDownTime();
long eventTime = event.getEventTime();
int source = event.getSource();
if (source == InputDevice.SOURCE_UNKNOWN) {
source = InputDevice.SOURCE_KEYBOARD;
}
if (eventTime == 0) {
eventTime = SystemClock.uptimeMillis();
}
if (downTime == 0) {
downTime = eventTime;
}
KeyEvent newEvent = new KeyEvent(event);
newEvent.setTime(downTime, eventTime);
newEvent.setSource(source);
newEvent.setFlags(event.getFlags() | KeyEvent.FLAG_FROM_SYSTEM);
InputManager.getInstance().injectInputEvent(newEvent,
InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event){
DrawerLayout drawer = findViewById(R.id.drawer_layout);
if(event.getKeyCode() == KeyEvent.KEYCODE_BACK){
if(drawer.isDrawerOpen(GravityCompat.START)){
switch(event.getAction()){
case KeyEvent.ACTION_DOWN:
if(event.getDownTime() - lastPressedTime < PERIOD){
finish();
}else{
Toast.makeText(context, R.string.press_again_to_exit, Toast.LENGTH_SHORT).show();
lastPressedTime = event.getEventTime();
}
return true;
}
}else if(!drawer.isDrawerOpen(GravityCompat.START)){
drawer.openDrawer(GravityCompat.START);
}
}
return false;
}
private KeyEvent convertKeyEventInArc(KeyEvent event) {
switch (event.getKeyCode()) {
case KeyEvent.KEYCODE_HOME:
case KeyEvent.KEYCODE_BACK:
// In Arc, Search + X is sent as KEYCODE_X with META_META_ON in Android. Android
// converts META_META_ON + KEYCODE_ENTER and META_META_ON + KEYCODE_DEL to
// KEYCODE_HOME and KEYCODE_BACK without META_META_ON. We add META_META_ON to this
// key event to satisfy trigger modifier condition. We don't need to do this in
// non-Arc since Search + X is usually sent as KEYCODE_X with META_META_ON and
// META_META_LEFT_ON or META_META_RIGHT_ON.
return new KeyEvent(
event.getDownTime(),
event.getEventTime(),
event.getAction(),
event.getKeyCode(),
event.getRepeatCount(),
event.getMetaState() | KeyEvent.META_META_ON);
default:
return event;
}
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
boolean handled = false;
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_CENTER:
case KeyEvent.KEYCODE_NUMPAD_ENTER:
case KeyEvent.KEYCODE_ENTER:
long duration = event.getEventTime() - event.getDownTime();
if (event.isTracking() && event.getDownTime() > mLastLongPress && duration < ViewConfiguration.getLongPressTimeout()) {
performItemClick(getSelectedView(), getSelectedItemPosition(), getSelectedItemId());
}
handled = true;
break;
}
return handled || super.onKeyUp(keyCode, event);
}
/**
* Send a key event to the currently focused window/view and wait for it to
* be processed. Finished at some point after the recipient has returned
* from its event processing, though it may <em>not</em> have completely
* finished reacting from the event -- for example, if it needs to update
* its display as a result, it may still be in the process of doing that.
*
* @param event The event to send to the current focus.
*/
public void sendKeySync(KeyEvent event) {
validateNotAppThread();
long downTime = event.getDownTime();
long eventTime = event.getEventTime();
int action = event.getAction();
int code = event.getKeyCode();
int repeatCount = event.getRepeatCount();
int metaState = event.getMetaState();
int deviceId = event.getDeviceId();
int scancode = event.getScanCode();
int source = event.getSource();
int flags = event.getFlags();
if (source == InputDevice.SOURCE_UNKNOWN) {
source = InputDevice.SOURCE_KEYBOARD;
}
if (eventTime == 0) {
eventTime = SystemClock.uptimeMillis();
}
if (downTime == 0) {
downTime = eventTime;
}
KeyEvent newEvent = new KeyEvent(downTime, eventTime, action, code, repeatCount, metaState,
deviceId, scancode, flags | KeyEvent.FLAG_FROM_SYSTEM, source);
InputManager.getInstance().injectInputEvent(newEvent,
InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
}
/**
* Send a key event to the currently focused window/view and wait for it to
* be processed. Finished at some point after the recipient has returned
* from its event processing, though it may <em>not</em> have completely
* finished reacting from the event -- for example, if it needs to update
* its display as a result, it may still be in the process of doing that.
*
* @param event The event to send to the current focus.
*/
public void sendKeySync(KeyEvent event) {
validateNotAppThread();
long downTime = event.getDownTime();
long eventTime = event.getEventTime();
int action = event.getAction();
int code = event.getKeyCode();
int repeatCount = event.getRepeatCount();
int metaState = event.getMetaState();
int deviceId = event.getDeviceId();
int scancode = event.getScanCode();
int source = event.getSource();
int flags = event.getFlags();
if (source == InputDevice.SOURCE_UNKNOWN) {
source = InputDevice.SOURCE_KEYBOARD;
}
if (eventTime == 0) {
eventTime = SystemClock.uptimeMillis();
}
if (downTime == 0) {
downTime = eventTime;
}
KeyEvent newEvent = new KeyEvent(downTime, eventTime, action, code, repeatCount, metaState,
deviceId, scancode, flags | KeyEvent.FLAG_FROM_SYSTEM, source);
InputManager.getInstance().injectInputEvent(newEvent,
InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
}
/**
* Send a key event to the currently focused window/view and wait for it to
* be processed. Finished at some point after the recipient has returned
* from its event processing, though it may <em>not</em> have completely
* finished reacting from the event -- for example, if it needs to update
* its display as a result, it may still be in the process of doing that.
*
* @param event The event to send to the current focus.
*/
public void sendKeySync(KeyEvent event) {
validateNotAppThread();
long downTime = event.getDownTime();
long eventTime = event.getEventTime();
int action = event.getAction();
int code = event.getKeyCode();
int repeatCount = event.getRepeatCount();
int metaState = event.getMetaState();
int deviceId = event.getDeviceId();
int scancode = event.getScanCode();
int source = event.getSource();
int flags = event.getFlags();
if (source == InputDevice.SOURCE_UNKNOWN) {
source = InputDevice.SOURCE_KEYBOARD;
}
if (eventTime == 0) {
eventTime = SystemClock.uptimeMillis();
}
if (downTime == 0) {
downTime = eventTime;
}
KeyEvent newEvent = new KeyEvent(downTime, eventTime, action, code, repeatCount, metaState,
deviceId, scancode, flags | KeyEvent.FLAG_FROM_SYSTEM, source);
InputManager.getInstance().injectInputEvent(newEvent,
InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
}
/**
* Send a key event to the currently focused window/view and wait for it to
* be processed. Finished at some point after the recipient has returned
* from its event processing, though it may <em>not</em> have completely
* finished reacting from the event -- for example, if it needs to update
* its display as a result, it may still be in the process of doing that.
*
* @param event The event to send to the current focus.
*/
public void sendKeySync(KeyEvent event) {
validateNotAppThread();
long downTime = event.getDownTime();
long eventTime = event.getEventTime();
int action = event.getAction();
int code = event.getKeyCode();
int repeatCount = event.getRepeatCount();
int metaState = event.getMetaState();
int deviceId = event.getDeviceId();
int scancode = event.getScanCode();
int source = event.getSource();
int flags = event.getFlags();
if (source == InputDevice.SOURCE_UNKNOWN) {
source = InputDevice.SOURCE_KEYBOARD;
}
if (eventTime == 0) {
eventTime = SystemClock.uptimeMillis();
}
if (downTime == 0) {
downTime = eventTime;
}
KeyEvent newEvent = new KeyEvent(downTime, eventTime, action, code, repeatCount, metaState,
deviceId, scancode, flags | KeyEvent.FLAG_FROM_SYSTEM, source);
InputManager.getInstance().injectInputEvent(newEvent,
InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
}
/**
* Handles the dispatching of the volume button events to one of the
* registered listeners. If there's a volume key long-press listener and
* there's no active global priority session, long-pressess will be sent to the
* long-press listener instead of adjusting volume.
*
* @param packageName The caller package.
* @param asSystemService {@code true} if the event sent to the session as if it was come
* from the system service instead of the app process. This helps sessions to
* distinguish between the key injection by the app and key events from the
* hardware devices. Should be used only when the volume key events aren't handled
* by foreground activity. {@code false} otherwise to tell session about the real
* caller.
* @param keyEvent a non-null KeyEvent whose key code is one of the
* {@link KeyEvent#KEYCODE_VOLUME_UP},
* {@link KeyEvent#KEYCODE_VOLUME_DOWN},
* or {@link KeyEvent#KEYCODE_VOLUME_MUTE}.
* @param stream stream type to adjust volume.
* @param musicOnly true if both UI nor haptic feedback aren't needed when adjust volume.
*/
@Override
public void dispatchVolumeKeyEvent(String packageName, boolean asSystemService,
KeyEvent keyEvent, int stream, boolean musicOnly) {
if (keyEvent == null ||
(keyEvent.getKeyCode() != KeyEvent.KEYCODE_VOLUME_UP
&& keyEvent.getKeyCode() != KeyEvent.KEYCODE_VOLUME_DOWN
&& keyEvent.getKeyCode() != KeyEvent.KEYCODE_VOLUME_MUTE)) {
Log.w(TAG, "Attempted to dispatch null or non-volume key event.");
return;
}
final int pid = Binder.getCallingPid();
final int uid = Binder.getCallingUid();
final long token = Binder.clearCallingIdentity();
if (DEBUG_KEY_EVENT) {
Log.d(TAG, "dispatchVolumeKeyEvent, pkg=" + packageName + ", pid=" + pid + ", uid="
+ uid + ", asSystem=" + asSystemService + ", event=" + keyEvent);
}
try {
synchronized (mLock) {
if (isGlobalPriorityActiveLocked()
|| mCurrentFullUserRecord.mOnVolumeKeyLongPressListener == null) {
dispatchVolumeKeyEventLocked(packageName, pid, uid, asSystemService,
keyEvent, stream, musicOnly);
} else {
// TODO: Consider the case when both volume up and down keys are pressed
// at the same time.
if (keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
if (keyEvent.getRepeatCount() == 0) {
// Keeps the copy of the KeyEvent because it can be reused.
mCurrentFullUserRecord.mInitialDownVolumeKeyEvent =
KeyEvent.obtain(keyEvent);
mCurrentFullUserRecord.mInitialDownVolumeStream = stream;
mCurrentFullUserRecord.mInitialDownMusicOnly = musicOnly;
mHandler.sendMessageDelayed(
mHandler.obtainMessage(
MessageHandler.MSG_VOLUME_INITIAL_DOWN,
mCurrentFullUserRecord.mFullUserId, 0),
mLongPressTimeout);
}
if (keyEvent.getRepeatCount() > 0 || keyEvent.isLongPress()) {
mHandler.removeMessages(MessageHandler.MSG_VOLUME_INITIAL_DOWN);
if (mCurrentFullUserRecord.mInitialDownVolumeKeyEvent != null) {
dispatchVolumeKeyLongPressLocked(
mCurrentFullUserRecord.mInitialDownVolumeKeyEvent);
// Mark that the key is already handled.
mCurrentFullUserRecord.mInitialDownVolumeKeyEvent = null;
}
dispatchVolumeKeyLongPressLocked(keyEvent);
}
} else { // if up
mHandler.removeMessages(MessageHandler.MSG_VOLUME_INITIAL_DOWN);
if (mCurrentFullUserRecord.mInitialDownVolumeKeyEvent != null
&& mCurrentFullUserRecord.mInitialDownVolumeKeyEvent
.getDownTime() == keyEvent.getDownTime()) {
// Short-press. Should change volume.
dispatchVolumeKeyEventLocked(packageName, pid, uid, asSystemService,
mCurrentFullUserRecord.mInitialDownVolumeKeyEvent,
mCurrentFullUserRecord.mInitialDownVolumeStream,
mCurrentFullUserRecord.mInitialDownMusicOnly);
dispatchVolumeKeyEventLocked(packageName, pid, uid, asSystemService,
keyEvent, stream, musicOnly);
} else {
dispatchVolumeKeyLongPressLocked(keyEvent);
}
}
}
}
} finally {
Binder.restoreCallingIdentity(token);
}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event){
DrawerLayout drawer = findViewById(R.id.drawer_layout);
Fragment fragment = this.getFragmentManager().findFragmentById(R.id.fragmentHolder);
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
if(event.getKeyCode() == KeyEvent.KEYCODE_BACK){
if(fragment instanceof DashBoard){
if(drawer.isDrawerOpen(GravityCompat.START)){
switch(event.getAction()){
case KeyEvent.ACTION_DOWN:
if(event.getDownTime() - lastPressedTime < PERIOD){
finish();
}else{
Toast.makeText(context, R.string.press_again_to_exit, Toast.LENGTH_SHORT).show();
lastPressedTime = event.getEventTime();
}
return true;
}
}else if(!drawer.isDrawerOpen(GravityCompat.START)){
drawer.openDrawer(GravityCompat.START);
}
}else if(fragment instanceof About){
fragment = new DashBoard();
fragmentTransaction.replace(R.id.fragmentHolder, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}else if(fragment instanceof DesktopEnvironment){
fragment = new DashBoard();
fragmentTransaction.replace(R.id.fragmentHolder, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}else if(fragment instanceof WindowManager){
fragment = new DashBoard();
fragmentTransaction.replace(R.id.fragmentHolder, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}else if(fragment instanceof SSH){
fragment = new DashBoard();
fragmentTransaction.replace(R.id.fragmentHolder, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}else if(fragment instanceof Uninstaller){
fragment = new DashBoard();
fragmentTransaction.replace(R.id.fragmentHolder, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}else if(fragment instanceof Patches){
fragment = new DashBoard();
fragmentTransaction.replace(R.id.fragmentHolder, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}else if(fragment instanceof SU){
fragment = new DashBoard();
fragmentTransaction.replace(R.id.fragmentHolder, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}else if(fragment instanceof RootfsDownload){
fragment = new DashBoard();
fragmentTransaction.replace(R.id.fragmentHolder, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
}
return false;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event){
DrawerLayout drawer = findViewById(R.id.drawer_layout);
Fragment fragment = this.getFragmentManager().findFragmentById(R.id.fragmentHolder);
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
if(event.getKeyCode() == KeyEvent.KEYCODE_BACK){
if(fragment instanceof DashBoard){
if(drawer.isDrawerOpen(GravityCompat.START)){
switch(event.getAction()){
case KeyEvent.ACTION_DOWN:
if(event.getDownTime() - lastPressedTime < PERIOD){
finish();
}else{
Toast.makeText(context, R.string.press_again_to_exit, Toast.LENGTH_SHORT).show();
lastPressedTime = event.getEventTime();
}
return true;
}
}else if(!drawer.isDrawerOpen(GravityCompat.START)){
drawer.openDrawer(GravityCompat.START);
}
}else if(fragment instanceof About){
fragment = new DashBoard();
fragmentTransaction.replace(R.id.fragmentHolder, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}else if(fragment instanceof DesktopEnvironment){
fragment = new DashBoard();
fragmentTransaction.replace(R.id.fragmentHolder, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}else if(fragment instanceof WindowManager){
fragment = new DashBoard();
fragmentTransaction.replace(R.id.fragmentHolder, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}else if(fragment instanceof SSH){
fragment = new DashBoard();
fragmentTransaction.replace(R.id.fragmentHolder, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}else if(fragment instanceof Uninstaller){
fragment = new DashBoard();
fragmentTransaction.replace(R.id.fragmentHolder, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}else if(fragment instanceof Patches){
fragment = new DashBoard();
fragmentTransaction.replace(R.id.fragmentHolder, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}else if(fragment instanceof SU){
fragment = new DashBoard();
fragmentTransaction.replace(R.id.fragmentHolder, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}else if(fragment instanceof RootfsDownload){
fragment = new DashBoard();
fragmentTransaction.replace(R.id.fragmentHolder, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
}
return false;
}
private boolean onKeyDown(KeyEvent event) {
if (mIsArc) {
event = convertKeyEventInArc(event);
}
mCurrentKeysDown.add(event.getKeyCode());
mCurrentKeyComboCode = getKeyComboCode(event);
mCurrentKeyComboTime = event.getDownTime();
// Check modifier.
int triggerModifier = mKeyComboModel.getTriggerModifier();
boolean hasModifier = triggerModifier != KeyComboModel.NO_MODIFIER;
if (hasModifier && (triggerModifier & event.getModifiers()) != triggerModifier) {
// Do nothing if condition of modifier is not met.
mPassedKeys.addAll(mCurrentKeysDown);
return false;
}
boolean isServiceActive = (mServiceState == SERVICE_STATE_ACTIVE);
// If the current set of keys is a partial combo, consume the event.
mHasPartialMatch = false;
for (Map.Entry<String, Long> entry : mKeyComboModel.getKeyComboCodeMap().entrySet()) {
if (!isServiceActive && !alwaysProcessCombo(entry.getKey())) {
continue;
}
final int match = matchKeyEventWith(event, triggerModifier, entry.getValue());
if (match == EXACT_MATCH) {
int comboId = getActionIdFromKey(entry.getKey());
EventId eventId = Performance.getInstance().onKeyComboEventReceived(comboId);
// Checks interrupt events if matches key combos. To prevent interrupting actions generated
// by key combos, we should send interrupt events
// before performing key combos.
interrupt(comboId);
for (KeyComboListener listener : mListeners) {
if (listener.onComboPerformed(comboId, eventId)) {
mPerformedCombo = true;
return true;
}
}
}
if (match == PARTIAL_MATCH) {
mHasPartialMatch = true;
}
}
// Do not handle key event if user has pressed search key (meta key) twice to open search
// app.
if (hasModifier && triggerModifier == KeyEvent.META_META_ON) {
if (mPreviousKeyComboCode == mCurrentKeyComboCode
&& mCurrentKeyComboTime - mPreviousKeyComboTime < TIME_TO_DETECT_DOUBLE_TAP
&& (mCurrentKeyComboCode
== KeyComboManager.getKeyComboCode(
KeyEvent.META_META_ON, KeyEvent.KEYCODE_META_RIGHT)
|| mCurrentKeyComboCode
== KeyComboManager.getKeyComboCode(
KeyEvent.META_META_ON, KeyEvent.KEYCODE_META_LEFT))) {
// Set KEY_COMBO_CODE_UNASSIGNED not to open search app again with following search
// key event.
mCurrentKeyComboCode = KeyComboModel.KEY_COMBO_CODE_UNASSIGNED;
mPassedKeys.addAll(mCurrentKeysDown);
return false;
}
}
if (!mHasPartialMatch) {
mPassedKeys.addAll(mCurrentKeysDown);
}
return mHasPartialMatch;
}