下面列出了android.view.KeyEvent#getFlags ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private void handleVoiceKeyEventLocked(String packageName, int pid, int uid,
boolean asSystemService, KeyEvent keyEvent, boolean needWakeLock) {
int action = keyEvent.getAction();
boolean isLongPress = (keyEvent.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0;
if (action == KeyEvent.ACTION_DOWN) {
if (keyEvent.getRepeatCount() == 0) {
mVoiceButtonDown = true;
mVoiceButtonHandled = false;
} else if (mVoiceButtonDown && !mVoiceButtonHandled && isLongPress) {
mVoiceButtonHandled = true;
startVoiceInput(needWakeLock);
}
} else if (action == KeyEvent.ACTION_UP) {
if (mVoiceButtonDown) {
mVoiceButtonDown = false;
if (!mVoiceButtonHandled && !keyEvent.isCanceled()) {
// Resend the down then send this event through
KeyEvent downEvent = KeyEvent.changeAction(keyEvent, KeyEvent.ACTION_DOWN);
dispatchMediaKeyEventLocked(packageName, pid, uid, asSystemService,
downEvent, needWakeLock);
dispatchMediaKeyEventLocked(packageName, pid, uid, asSystemService,
keyEvent, needWakeLock);
}
}
}
}
@Override
public boolean dispatchKeyEvent(@NonNull KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
if (event.getAction() == KeyEvent.ACTION_UP) {
if (mIsMultiChoiceModeEnabled) {
setMultiChoiceModeEnabled(false);
setupOkButtonVisibility();
} else {
if (isTopDirectory(mCurrentDirectory)) {
finish();
} else {
readUpDirectory();
}
}
} else if (event.getAction() == KeyEvent.ACTION_DOWN && (event.getFlags() & KeyEvent.FLAG_LONG_PRESS) == KeyEvent.FLAG_LONG_PRESS) {
finish();
}
return true;
}
return super.dispatchKeyEvent(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);
}
@Override
public void onVolumeKeyLongPress(KeyEvent keyEvent) {
boolean screenOn = powerManager.isInteractive();
boolean musicPlaying = audioManager.isMusicActive();
int flags = keyEvent.getFlags();
//if(keyEvent.getFlags() != FLAG_FROM_SYSTEM) return;
if(!(flags == FLAG_FROM_SYSTEM || flags == FLAG_LONG_PRESS)) return;
if((musicPlaying || prefNoMedia) && (!screenOn || prefScreenOn)) {
if(keyEvent.getAction() == KeyEvent.ACTION_DOWN && keyEvent.getRepeatCount() <= 1) {
int keyCode = keyEvent.getKeyCode();
int event = (keyCode == KEYCODE_VOLUME_UP) ? KEYCODE_MEDIA_NEXT : KEYCODE_MEDIA_PREVIOUS;
int msgRes = (keyCode == KEYCODE_VOLUME_UP) ? R.string.msg_media_next : R.string.msg_media_pre;
KeyEvent skipEvent = new KeyEvent(keyEvent.getAction(), event);
audioManager.dispatchMediaKeyEvent(skipEvent);
if (debugEnabled) Toast.makeText(this, getString(msgRes), Toast.LENGTH_SHORT).show();
}
return;
}
// Let the MediaSessionManager deal with the event
mediaSessionManager.setOnVolumeKeyLongPressListener(null, null);
mediaSessionManager.dispatchVolumeKeyEvent(keyEvent, audioManager.getUiSoundsStreamType(), false);
mediaSessionManager.setOnVolumeKeyLongPressListener(this, mHandler);
}
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
if (!allowSkipTrack) return;
final KeyEvent event = (KeyEvent) param.args[0];
final int keyCode = event.getKeyCode();
initManagers((Context) XposedHelpers.getObjectField(param.thisObject, "mContext"));
if ((keyCode == KeyEvent.KEYCODE_VOLUME_DOWN ||
keyCode == KeyEvent.KEYCODE_VOLUME_UP) &&
(event.getFlags() & KeyEvent.FLAG_FROM_SYSTEM) != 0 &&
!mPowerManager.isInteractive() &&
mAudioManager != null && mAudioManager.isMusicActive()) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
mIsLongPress = false;
handleVolumeLongPress(param.thisObject, keyCode);
} else {
handleVolumeLongPressAbort(param.thisObject);
if (!mIsLongPress) {
if (mShoudTriggerWakeUp) {
wakeUp();
} else {
mAudioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC,
keyCode == KeyEvent.KEYCODE_VOLUME_UP ?
AudioManager.ADJUST_RAISE : AudioManager.ADJUST_LOWER, 0);
}
}
}
param.setResult(0);
return;
}
}
/**
* Calls from {@link Activity#onKeyUp(int, KeyEvent)} to delegate
* @param keyCode event key code
* @param event key event
* @return true if is intercepted as navigation, false otherwise
*/
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (!mEnabled) {
return false;
}
boolean notLongPress = (event.getFlags() & KeyEvent.FLAG_CANCELED_LONG_PRESS) == 0;
if (keyCode == KeyEvent.KEYCODE_VOLUME_UP && notLongPress) {
shortPress(DIRECTION_UP);
return true;
} else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN && notLongPress) {
shortPress(DIRECTION_DOWN);
return true;
}
return false;
}
/**
* Handle KeyEvents on this screen. Do not consume the KeyEvent.
*
* @param event KeyEvent to be consumed or ignored.
*/
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
/*
* Redirects captured key events to the EditText. This is necessary as the overridden
* dispatch key event in SetupWizardActivity was consuming the key events, so we must
* manually route the events to the EditText here.
*/
if ((event.getFlags() & KeyEvent.FLAG_SOFT_KEYBOARD) == KeyEvent.FLAG_SOFT_KEYBOARD) {
customSpeedEditText.dispatchKeyEvent(event);
return true;
}
return false;
}
/**
* 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);
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_SEARCH && (event.getFlags() & KeyEvent.FLAG_CANCELED) == 0) {
SearchView searchV = (SearchView) findViewById(R.id.searchApp);
if (searchV.isShown()) {
searchV.setIconified(false);
return true;
}
}
return super.onKeyUp(keyCode, event);
}
public static boolean hasFlagToIgnore(KeyEvent keyEvent) {
return (keyEvent.getFlags() & KeyEvent.FLAG_FALLBACK) == KeyEvent.FLAG_FALLBACK;
}
/**
* Accepts and handles key event from parent. KeyAssignmentUtils updates the keycombo list and
* view. Displays a message if the key is assigned elsewhere, and indicates if the press was
* consumed or not.
*
* @param dialog The Dialog on which the key press occurred
* @param keyCode The key code of the key that was pressed
* @param event The {@link KeyEvent} to process
* @return {@code true} if event was consumed, {@code false} otherwise
*/
@Override
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
// Process on ACTION_UP since ACTION_DOWN can be sent multiple times if the switch is
// pressed and held or not at all in other cases (e.g. the first time the switch is pressed
// when no keys are assigned).
if (event.getAction() == KeyEvent.ACTION_UP) {
// If the key press is from the back button when using a virtual hard key, close the dialog.
// Otherwise, allow the back button to be assigned as usual. This is because the back button
// is unable to be used as a switch when it's a virtual hard key, so it shouldn't be
// assignable.
if (keyCode == KeyEvent.KEYCODE_BACK
&& ((event.getFlags() & KeyEvent.FLAG_VIRTUAL_HARD_KEY)
== KeyEvent.FLAG_VIRTUAL_HARD_KEY)) {
dialog.dismiss();
return true;
}
long keyCombo = KeyAssignmentUtils.keyEventToExtendedKeyCode(event);
int keyPressResult =
KeyAssignmentUtils.processKeyAssignment(
getContext(), event, keyCombos, getKey(), keyListAdapter);
CharSequence titleOfOtherPrefForKey = getTitleOfOtherActionAssociatedWith(keyCombo);
if ((keyPressResult == KeyAssignmentUtils.KEYCOMBO_ALREADY_ASSIGNED)
&& (titleOfOtherPrefForKey != null)) {
CharSequence toastText =
getContext()
.getString(
R.string.toast_msg_key_already_assigned,
KeyAssignmentUtils.describeExtendedKeyCode(keyCombo, getContext()),
titleOfOtherPrefForKey);
Toast.makeText(getContext(), toastText, Toast.LENGTH_SHORT).show();
} else {
resetButton.setEnabled(hasSwitchesAdded());
if ((keyPressResult == KeyAssignmentUtils.CONSUME_EVENT) && (callback != null)) {
callback.onKeyEventConsumed();
}
/* If the event was ignored, return that the event was not consumed. */
return keyPressResult != KeyAssignmentUtils.IGNORE_EVENT;
}
}
resetButton.setEnabled(hasSwitchesAdded());
return true;
}
@Override
protected boolean onKeyEvent(KeyEvent event) {
if (null == event) return true; // WTF??
// Make sure we're not in the middle of a phone call.
if (null != mVolumePanel && mVolumePanel.getCallState() != TelephonyManager.CALL_STATE_IDLE)
return super.onKeyEvent(event);
final int flags = event.getFlags();
final int code = event.getKeyCode();
final boolean system = ((flags & KeyEvent.FLAG_FROM_SYSTEM) == KeyEvent.FLAG_FROM_SYSTEM);
// Specifically avoid software keys or "fake" hardware buttons.
if (((flags & KeyEvent.FLAG_SOFT_KEYBOARD) == KeyEvent.FLAG_SOFT_KEYBOARD) ||
((flags & KeyEvent.FLAG_VIRTUAL_HARD_KEY) == KeyEvent.FLAG_VIRTUAL_HARD_KEY)) {
return super.onKeyEvent(event);
} else {
// Specifically avoid handling certain keys. We never want to interfere
// with them or harm performance in any way.
switch (code) {
case KeyEvent.KEYCODE_BACK:
case KeyEvent.KEYCODE_HOME:
case KeyEvent.KEYCODE_MENU:
case KeyEvent.KEYCODE_POWER:
case KeyEvent.KEYCODE_SEARCH:
return super.onKeyEvent(event);
}
}
if (!system) return super.onKeyEvent(event);
LOGI(TAG, "--onKeyEvent(code=" + event.getKeyCode() + ", action=" + event.getAction() +
", topPackage=" + mCurrentActivityPackage + ", disabledButtons=" + disabledButtons + ')');
// Check if we're supposed to disable Noyze for a Blacklisted app.
if (blacklist.contains(mCurrentActivityPackage)) {
if (null != mVolumePanel) mVolumePanel.setEnabled(false);
return super.onKeyEvent(event);
} else {
// NOTE: we need a "safe" way to enable the volume panel that
// takes into consideration its previous state.
if (null != mVolumePanel) mVolumePanel.enable();
}
// If we're told to disable one or more of the volume buttons, do so (returning true consumes the event).
if (disabledButtons == code) return true;
// NOTE: KeyEvent#KEYCODE_VOLUME_DOWN + KeyEvent#KEYCODE_VOLUME_UP == KeyEvent_KEYCODE_U
final int upAndDown = (KeyEvent.KEYCODE_VOLUME_DOWN + KeyEvent.KEYCODE_VOLUME_UP); // 49
final int upSquared = KeyEvent.KEYCODE_VOLUME_UP * KeyEvent.KEYCODE_VOLUME_UP; // 576
if (disabledButtons == upAndDown && Utils.isVolumeKeyCode(upAndDown - code)) return true;
if (disabledButtons == upSquared && mVolumePanel != null && mVolumePanel.isLocked()) return true;
if (disabledButtons == upSquared && KEYGUARD.equals(mCurrentActivityPackage)) return true;
// Check if the volume panel has been disabled, or shouldn't handle this event (e.g. "safe volume").
if (null != mVolumePanel && mVolumePanel.isEnabled()) {
if (Utils.isVolumeKeyCode(code)) {
Message.obtain(mHandler, MESSAGE_KEY_EVENT, event).sendToTarget(); // Run asynchronously
return true;
}
}
return super.onKeyEvent(event);
}
@Override
protected boolean onKeyEvent(KeyEvent event) {
if (null == event) return true; // WTF??
// Make sure we're not in the middle of a phone call.
if (null != mVolumePanel && mVolumePanel.getCallState() != TelephonyManager.CALL_STATE_IDLE)
return super.onKeyEvent(event);
final int flags = event.getFlags();
final int code = event.getKeyCode();
final boolean system = ((flags & KeyEvent.FLAG_FROM_SYSTEM) == KeyEvent.FLAG_FROM_SYSTEM);
// Specifically avoid software keys or "fake" hardware buttons.
if (((flags & KeyEvent.FLAG_SOFT_KEYBOARD) == KeyEvent.FLAG_SOFT_KEYBOARD) ||
((flags & KeyEvent.FLAG_VIRTUAL_HARD_KEY) == KeyEvent.FLAG_VIRTUAL_HARD_KEY)) {
return super.onKeyEvent(event);
} else {
// Specifically avoid handling certain keys. We never want to interfere
// with them or harm performance in any way.
switch (code) {
case KeyEvent.KEYCODE_BACK:
case KeyEvent.KEYCODE_HOME:
case KeyEvent.KEYCODE_MENU:
case KeyEvent.KEYCODE_POWER:
case KeyEvent.KEYCODE_SEARCH:
return super.onKeyEvent(event);
}
}
if (!system) return super.onKeyEvent(event);
LOGI(TAG, "--onKeyEvent(code=" + event.getKeyCode() + ", action=" + event.getAction() +
", topPackage=" + mCurrentActivityPackage + ", disabledButtons=" + disabledButtons + ')');
// Check if we're supposed to disable Noyze for a Blacklisted app.
if (blacklist.contains(mCurrentActivityPackage)) {
if (null != mVolumePanel) mVolumePanel.setEnabled(false);
return super.onKeyEvent(event);
} else {
// NOTE: we need a "safe" way to enable the volume panel that
// takes into consideration its previous state.
if (null != mVolumePanel) mVolumePanel.enable();
}
// If we're told to disable one or more of the volume buttons, do so (returning true consumes the event).
if (disabledButtons == code) return true;
// NOTE: KeyEvent#KEYCODE_VOLUME_DOWN + KeyEvent#KEYCODE_VOLUME_UP == KeyEvent_KEYCODE_U
final int upAndDown = (KeyEvent.KEYCODE_VOLUME_DOWN + KeyEvent.KEYCODE_VOLUME_UP); // 49
final int upSquared = KeyEvent.KEYCODE_VOLUME_UP * KeyEvent.KEYCODE_VOLUME_UP; // 576
if (disabledButtons == upAndDown && Utils.isVolumeKeyCode(upAndDown - code)) return true;
if (disabledButtons == upSquared && mVolumePanel != null && mVolumePanel.isLocked()) return true;
if (disabledButtons == upSquared && KEYGUARD.equals(mCurrentActivityPackage)) return true;
// Check if the volume panel has been disabled, or shouldn't handle this event (e.g. "safe volume").
if (null != mVolumePanel && mVolumePanel.isEnabled()) {
if (Utils.isVolumeKeyCode(code)) {
Message.obtain(mHandler, MESSAGE_KEY_EVENT, event).sendToTarget(); // Run asynchronously
return true;
}
}
return super.onKeyEvent(event);
}