需求场景
纯KeyCode 快捷操作
- 经常在代码中实现返回、Home 、音量加减、截屏 等功能实现,代码中硬编码 shell 脚本 模拟 KeyCode事件
- 物理按键调试,模拟物理按键测试用:按键功能,物理按键驱动层已经调试完成,但有没有完整的硬件方便调试,应用层模拟物理按键功能来调试。比如:Android方案中,电视产品、音箱产品、带屏的Android各种方案
都是有物理按键的,如果自己测试验证物理按键的功能呢,那就需要自己来模拟KeyEventCode 来模拟按键,先自测。 - 遥控器功能【投影产品】:一般根据蓝牙方案、红外方案实现遥控功能,传递给系统的都是Key的键值,系统自带标准的键值,这样就形成一套标准的流程了,系统根据键值做出反馈或者系统收到对应的键值反馈给上层,上层来处理业务逻辑。
- 游戏类产品,手柄的控制。手柄上面的功能按钮其实就是一些物理按键,点击物理按键,系统或者应用监听后给出反馈。那么在实际测试的时候,就需要模拟按键来测试验证
- 如果Android平板作为电脑使用,插上USB,那么Android平板作为电脑来时候,就必须响应键盘上面的所有按键,这些物理按键也是通过KeyCode
来传递给系统,准确来说是系统来响应这些KeyCode,进而再处理响应的逻辑。
总的来讲:系统响应KeyCode,这些KeyCode是外设作为输入源,KeyCode 键值就是Android一套标准的协议
KeyCode 按键响应操作、拦截
比如物理按键操作之后,系统是如何分发、响应、处理、拦截呢? 比如我们需要客制化一些物理按键功能,如何实现呢?
一、工作中常用KeyCode
枚举值 | 键值 | 功能说明 |
---|---|---|
KEYCODE_HOME | 3 | 主屏幕键 |
KEYCODE_BACK | 4 | 返回键 |
KEYCODE_DPAD_UP | 19 | 向上方向键 |
KEYCODE_DPAD_DOWN | 20 | 向下方向键 |
KEYCODE_DPAD_LEFT | 21 | 向左方向键 |
KEYCODE_DPAD_RIGHT | 22 | 向右方向键 |
KEYCODE_DPAD_CENTER | 23 | 中心键 |
KEYCODE_VOLUME_UP | 24 | 手机音量+ |
KEYCODE_VOLUME_DOWN | 25 | 手机音量- |
KEYCODE_POWER | 26 | 电源键 |
KEYCODE_EXPLORER | 64 | 启动浏览器程序 |
KEYCODE_MEDIA_PLAY_PAUSE | 85 | 多媒体播放、暂停键 |
KEYCODE_MEDIA_STOP | 86 | 停止键 |
KEYCODE_MEDIA_NEXT | 87 | 下一首键 |
KEYCODE_MEDIA_PREVIOUS | 88 | 上一首键 |
KEYCODE_MEDIA_REWIND | 89 | 快退键 |
KEYCODE_MEDIA_FAST_FORWARD | 90 | 快进键 |
KEYCODE_MEDIA_PLAY | 126 | 播放键 |
KEYCODE_MEDIA_PAUSE | 127 | 暂停键 |
KEYCODE_VOLUME_MUTE | 164 | 手机扬声器静音 |
KEYCODE_APP_SWITCH | 187 | 任务管理 最近历史任务 |
KEYCODE_MUSIC | 209 | 启动音乐 |
KEYCODE_BRIGHTNESS_DOWN | 220 | 亮度减少 |
KEYCODE_BRIGHTNESS_UP | 221 | 亮度增加 |
KEYCODE_DPAD_DOWN_LEFT | 269 | 向左下方向键 |
KEYCODE_DPAD_DOWN_RIGHT | 271 | 向右下方向键 |
KEYCODE_DPAD_UP_LEFT | 268 | 向左上方向键 |
KEYCODE_DPAD_UP_RIGHT | 270 | 向右上方向键 |
备注:如何用命令来模拟执行按键操作
枚举方式:adb shell input keyevent KEYCODE_HOME
code方式:adb shell input keyevent 3
二、KeyCode大全
这里给出谷歌官方KeyEvent 事件,里面总结了所有的KeyCode
官方KeyCode
三、KeyCode 响应事件
事件输入流程
从大的方向将,物理按键始于外部输入,在Kernel 响应,再传递到Service或者View层消费,对于Kernel层、系统层暂不研究。
输入设备键值从底层到应用层的映射流程
事件响应
源码分析
源码位置:
PhoneWindowManager
这里涉及到 源码中的PhoneWindowManager 来响应物理按键事件并进行分发:
// You can only start consuming the key gesture if ACTION_DOWN and repeat count
// is 0. If you start intercepting the key halfway, then key will not be consumed
// and will be sent to apps for processing too.
// e.g. If a certain combination is only handled on ACTION_UP (i.e.
// interceptShortcut() returns true only for ACTION_UP), then since we already
// sent the ACTION_DOWN events to the application, we MUST also send the
// ACTION_UP to the application.
// So, to ensure that your intercept logic works properly, and we don't send any
// conflicting events to application, make sure to consume the event on
// ACTION_DOWN even if you want to do something on ACTION_UP. This is essential
// to maintain event parity and to not have incomplete key gestures.
@SuppressLint("MissingPermission")
private boolean interceptSystemKeysAndShortcuts(IBinder focusedToken, KeyEvent event) {
final boolean keyguardOn = keyguardOn();
final int keyCode = event.getKeyCode();
final int repeatCount = event.getRepeatCount();
final int metaState = event.getMetaState();
final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
final boolean canceled = event.isCanceled();
final int displayId = event.getDisplayId();
final int deviceId = event.getDeviceId();
final boolean firstDown = down && repeatCount == 0;
// Cancel any pending meta actions if we see any other keys being pressed between the
// down of the meta key and its corresponding up.
if (mPendingMetaAction && !KeyEvent.isMetaKey(keyCode)) {
mPendingMetaAction = false;
}
// Any key that is not Alt or Meta cancels Caps Lock combo tracking.
if (mPendingCapsLockToggle && !KeyEvent.isMetaKey(keyCode) && !KeyEvent.isAltKey(keyCode)) {
mPendingCapsLockToggle = false;
}
if (isUserSetupComplete() && !keyguardOn) {
if (mModifierShortcutManager.interceptKey(event)) {
dismissKeyboardShortcutsMenu();
mPendingMetaAction = false;
mPendingCapsLockToggle = false;
return true;
}
}
switch (keyCode) {
case KeyEvent.KEYCODE_HOME:
return handleHomeShortcuts(focusedToken, event);
case KeyEvent.KEYCODE_MENU:
// Hijack modified menu keys for debugging features
final int chordBug = KeyEvent.META_SHIFT_ON;
if (mEnableShiftMenuBugReports && firstDown
&& (metaState & chordBug) == chordBug) {
Intent intent = new Intent(Intent.ACTION_BUG_REPORT);
mContext.sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT,
null, null, null, 0, null, null);
logKeyboardSystemsEvent(event, KeyboardLogEvent.TRIGGER_BUG_REPORT);
return true;
}
break;
case KeyEvent.KEYCODE_RECENT_APPS:
if (firstDown) {
showRecentApps(false /* triggeredFromAltTab */);
logKeyboardSystemsEvent(event, KeyboardLogEvent.RECENT_APPS);
}
return true;
case KeyEvent.KEYCODE_APP_SWITCH:
if (!keyguardOn) {
if (firstDown) {
preloadRecentApps();
} else if (!down) {
toggleRecentApps();
logKeyboardSystemsEvent(event, KeyboardLogEvent.APP_SWITCH);
}
}
return true;
case KeyEvent.KEYCODE_A:
if (firstDown && event.isMetaPressed()) {
launchAssistAction(Intent.EXTRA_ASSIST_INPUT_HINT_KEYBOARD,
deviceId, event.getEventTime(),
AssistUtils.INVOCATION_TYPE_UNKNOWN);
logKeyboardSystemsEvent(event, KeyboardLogEvent.LAUNCH_ASSISTANT);
return true;
}
break;
case KeyEvent.KEYCODE_H:
case KeyEvent.KEYCODE_ENTER:
if (event.isMetaPressed()) {
return handleHomeShortcuts(focusedToken, event);
}
break;
case KeyEvent.KEYCODE_I:
if (firstDown && event.isMetaPressed()) {
showSystemSettings();
logKeyboardSystemsEvent(event, KeyboardLogEvent.LAUNCH_SYSTEM_SETTINGS);
return true;
}
break;
case KeyEvent.KEYCODE_L:
if (firstDown && event.isMetaPressed()) {
lockNow(null /* options */);
logKeyboardSystemsEvent(event, KeyboardLogEvent.LOCK_SCREEN);
return true;
}
break;
case KeyEvent.KEYCODE_N:
if (firstDown && event.isMetaPressed()) {
if (event.isCtrlPressed()) {
sendSystemKeyToStatusBarAsync(event);
logKeyboardSystemsEvent(event, KeyboardLogEvent.OPEN_NOTES);
} else {
toggleNotificationPanel();
logKeyboardSystemsEvent(event, KeyboardLogEvent.TOGGLE_NOTIFICATION_PANEL);
}
return true;
}
break;
case KeyEvent.KEYCODE_S:
if (firstDown && event.isMetaPressed() && event.isCtrlPressed()) {
interceptScreenshotChord(SCREENSHOT_KEY_OTHER, 0 /*pressDelay*/);
logKeyboardSystemsEvent(event, KeyboardLogEvent.TAKE_SCREENSHOT);
return true;
}
break;
case KeyEvent.KEYCODE_DEL:
case KeyEvent.KEYCODE_ESCAPE:
if (firstDown && event.isMetaPressed()) {
logKeyboardSystemsEvent(event, KeyboardLogEvent.BACK);
injectBackGesture(event.getDownTime());
return true;
}
case KeyEvent.KEYCODE_DPAD_UP:
if (firstDown && event.isMetaPressed() && event.isCtrlPressed()) {
StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
if (statusbar != null) {
statusbar.moveFocusedTaskToFullscreen(getTargetDisplayIdForKeyEvent(event));
logKeyboardSystemsEvent(event, KeyboardLogEvent.MULTI_WINDOW_NAVIGATION);
return true;
}
}
break;
case KeyEvent.KEYCODE_DPAD_DOWN:
if (firstDown && event.isMetaPressed() && event.isCtrlPressed()) {
StatusBarManagerInternal statusbar = getStatusBarManagerInternal();
if (statusbar != null) {
statusbar.enterDesktop(getTargetDisplayIdForKeyEvent(event));
logKeyboardSystemsEvent(event, KeyboardLogEvent.DESKTOP_MODE);
return true;
}
}
break;
case KeyEvent.KEYCODE_DPAD_LEFT:
if (firstDown && event.isMetaPressed()) {
if (event.isCtrlPressed()) {
enterStageSplitFromRunningApp(true /* leftOrTop */);
logKeyboardSystemsEvent(event, KeyboardLogEvent.SPLIT_SCREEN_NAVIGATION);
} else {
logKeyboardSystemsEvent(event, KeyboardLogEvent.BACK);
injectBackGesture(event.getDownTime());
}
return true;
}
break;
case KeyEvent.KEYCODE_DPAD_RIGHT:
if (firstDown && event.isMetaPressed() && event.isCtrlPressed()) {
enterStageSplitFromRunningApp(false /* leftOrTop */);
logKeyboardSystemsEvent(event, KeyboardLogEvent.SPLIT_SCREEN_NAVIGATION);
return true;
}
break;
case KeyEvent.KEYCODE_SLASH:
if (firstDown && event.isMetaPressed() && !keyguardOn) {
toggleKeyboardShortcutsMenu(event.getDeviceId());
logKeyboardSystemsEvent(event, KeyboardLogEvent.OPEN_SHORTCUT_HELPER);
return true;
}
break;
case KeyEvent.KEYCODE_ASSIST:
Slog.wtf(TAG, "KEYCODE_ASSIST should be handled in interceptKeyBeforeQueueing");
return true;
case KeyEvent.KEYCODE_VOICE_ASSIST:
Slog.wtf(TAG, "KEYCODE_VOICE_ASSIST should be handled in"
+ " interceptKeyBeforeQueueing");
return true;
case KeyEvent.KEYCODE_VIDEO_APP_1:
case KeyEvent.KEYCODE_VIDEO_APP_2:
case KeyEvent.KEYCODE_VIDEO_APP_3:
case KeyEvent.KEYCODE_VIDEO_APP_4:
case KeyEvent.KEYCODE_VIDEO_APP_5:
case KeyEvent.KEYCODE_VIDEO_APP_6:
case KeyEvent.KEYCODE_VIDEO_APP_7:
case KeyEvent.KEYCODE_VIDEO_APP_8:
case KeyEvent.KEYCODE_FEATURED_APP_1:
case KeyEvent.KEYCODE_FEATURED_APP_2:
case KeyEvent.KEYCODE_FEATURED_APP_3:
case KeyEvent.KEYCODE_FEATURED_APP_4:
case KeyEvent.KEYCODE_DEMO_APP_1:
case KeyEvent.KEYCODE_DEMO_APP_2:
case KeyEvent.KEYCODE_DEMO_APP_3:
case KeyEvent.KEYCODE_DEMO_APP_4:
Slog.wtf(TAG, "KEYCODE_APP_X should be handled in interceptKeyBeforeQueueing");
return true;
case KeyEvent.KEYCODE_BRIGHTNESS_UP:
case KeyEvent.KEYCODE_BRIGHTNESS_DOWN:
if (down) {
int direction = keyCode == KeyEvent.KEYCODE_BRIGHTNESS_UP ? 1 : -1;
// Disable autobrightness if it's on
int auto = Settings.System.getIntForUser(
mContext.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS_MODE,
Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL,
UserHandle.USER_CURRENT_OR_SELF);
if (auto != 0) {
Settings.System.putIntForUser(mContext.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS_MODE,
Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL,
UserHandle.USER_CURRENT_OR_SELF);
}
int screenDisplayId = displayId < 0 ? DEFAULT_DISPLAY : displayId;
float minLinearBrightness = mPowerManager.getBrightnessConstraint(
PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MINIMUM);
float maxLinearBrightness = mPowerManager.getBrightnessConstraint(
PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MAXIMUM);
float linearBrightness = mDisplayManager.getBrightness(screenDisplayId);
float gammaBrightness = BrightnessUtils.convertLinearToGamma(linearBrightness);
float adjustedGammaBrightness =
gammaBrightness + 1f / BRIGHTNESS_STEPS * direction;
adjustedGammaBrightness = MathUtils.constrain(adjustedGammaBrightness, 0f,
1f);
float adjustedLinearBrightness = BrightnessUtils.convertGammaToLinear(
adjustedGammaBrightness);
adjustedLinearBrightness = MathUtils.constrain(adjustedLinearBrightness,
minLinearBrightness, maxLinearBrightness);
mDisplayManager.setBrightness(screenDisplayId, adjustedLinearBrightness);
Intent intent = new Intent(Intent.ACTION_SHOW_BRIGHTNESS_DIALOG);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION
| Intent.FLAG_ACTIVITY_NO_USER_ACTION);
intent.putExtra(EXTRA_FROM_BRIGHTNESS_KEY, true);
startActivityAsUser(intent, UserHandle.CURRENT_OR_SELF);
logKeyboardSystemsEvent(event, KeyboardLogEvent.getBrightnessEvent(keyCode));
}
return true;
case KeyEvent.KEYCODE_KEYBOARD_BACKLIGHT_DOWN:
if (down) {
mInputManagerInternal.decrementKeyboardBacklight(event.getDeviceId());
logKeyboardSystemsEvent(event, KeyboardLogEvent.KEYBOARD_BACKLIGHT_DOWN);
}
return true;
case KeyEvent.KEYCODE_KEYBOARD_BACKLIGHT_UP:
if (down) {
mInputManagerInternal.incrementKeyboardBacklight(event.getDeviceId());
logKeyboardSystemsEvent(event, KeyboardLogEvent.KEYBOARD_BACKLIGHT_UP);
}
return true;
case KeyEvent.KEYCODE_KEYBOARD_BACKLIGHT_TOGGLE:
// TODO: Add logic
if (!down) {
logKeyboardSystemsEvent(event, KeyboardLogEvent.KEYBOARD_BACKLIGHT_TOGGLE);
}
return true;
case KeyEvent.KEYCODE_VOLUME_UP:
case KeyEvent.KEYCODE_VOLUME_DOWN:
case KeyEvent.KEYCODE_VOLUME_MUTE:
if (mUseTvRouting || mHandleVolumeKeysInWM) {
// On TVs or when the configuration is enabled, volume keys never
// go to the foreground app.
dispatchDirectAudioEvent(event);
return true;
}
// If the device is in VR mode and keys are "internal" (e.g. on the side of the
// device), then drop the volume keys and don't forward it to the
// application/dispatch the audio event.
if (mDefaultDisplayPolicy.isPersistentVrModeEnabled()) {
final InputDevice d = event.getDevice();
if (d != null && !d.isExternal()) {
return true;
}
}
break;
case KeyEvent.KEYCODE_TAB:
if (firstDown && !keyguardOn && isUserSetupComplete()) {
if (event.isMetaPressed()) {
showRecentApps(false);
logKeyboardSystemsEvent(event, KeyboardLogEvent.RECENT_APPS);
return true;
} else if (mRecentAppsHeldModifiers == 0) {
final int shiftlessModifiers =
event.getModifiers() & ~KeyEvent.META_SHIFT_MASK;
if (KeyEvent.metaStateHasModifiers(
shiftlessModifiers, KeyEvent.META_ALT_ON)) {
mRecentAppsHeldModifiers = shiftlessModifiers;
showRecentApps(true);
logKeyboardSystemsEvent(event, KeyboardLogEvent.RECENT_APPS);
return true;
}
}
}
break;
case KeyEvent.KEYCODE_ALL_APPS:
if (!down) {
mHandler.removeMessages(MSG_HANDLE_ALL_APPS);
Message msg = mHandler.obtainMessage(MSG_HANDLE_ALL_APPS);
msg.setAsynchronous(true);
msg.sendToTarget();
logKeyboardSystemsEvent(event, KeyboardLogEvent.ALL_APPS);
}
return true;
case KeyEvent.KEYCODE_NOTIFICATION:
if (!down) {
toggleNotificationPanel();
logKeyboardSystemsEvent(event, KeyboardLogEvent.TOGGLE_NOTIFICATION_PANEL);
}
return true;
case KeyEvent.KEYCODE_SEARCH:
if (firstDown && !keyguardOn) {
switch (mSearchKeyBehavior) {
case SEARCH_BEHAVIOR_TARGET_ACTIVITY: {
launchTargetSearchActivity();
logKeyboardSystemsEvent(event, KeyboardLogEvent.LAUNCH_SEARCH);
return true;
}
case SEARCH_BEHAVIOR_DEFAULT_SEARCH:
default:
break;
}
}
break;
case KeyEvent.KEYCODE_LANGUAGE_SWITCH:
if (firstDown) {
int direction = (metaState & KeyEvent.META_SHIFT_MASK) != 0 ? -1 : 1;
sendSwitchKeyboardLayout(event, focusedToken, direction);
logKeyboardSystemsEvent(event, KeyboardLogEvent.LANGUAGE_SWITCH);
return true;
}
break;
case KeyEvent.KEYCODE_META_LEFT:
case KeyEvent.KEYCODE_META_RIGHT:
if (down) {
if (event.isAltPressed()) {
mPendingCapsLockToggle = true;
mPendingMetaAction = false;
} else {
mPendingCapsLockToggle = false;
mPendingMetaAction = true;
}
} else {
// Toggle Caps Lock on META-ALT.
if (mPendingCapsLockToggle) {
mInputManagerInternal.toggleCapsLock(event.getDeviceId());
mPendingCapsLockToggle = false;
logKeyboardSystemsEvent(event, KeyboardLogEvent.TOGGLE_CAPS_LOCK);
} else if (mPendingMetaAction) {
if (!canceled) {
launchAllAppsViaA11y();
logKeyboardSystemsEvent(event, KeyboardLogEvent.ACCESSIBILITY_ALL_APPS);
}
mPendingMetaAction = false;
}
}
return true;
case KeyEvent.KEYCODE_ALT_LEFT:
case KeyEvent.KEYCODE_ALT_RIGHT:
if (down) {
if (event.isMetaPressed()) {
mPendingCapsLockToggle = true;
mPendingMetaAction = false;
} else {
mPendingCapsLockToggle = false;
}
} else {
// hide recent if triggered by ALT-TAB.
if (mRecentAppsHeldModifiers != 0
&& (metaState & mRecentAppsHeldModifiers) == 0) {
mRecentAppsHeldModifiers = 0;
hideRecentApps(true, false);
return true;
}
// Toggle Caps Lock on META-ALT.
if (mPendingCapsLockToggle) {
mInputManagerInternal.toggleCapsLock(event.getDeviceId());
mPendingCapsLockToggle = false;
logKeyboardSystemsEvent(event, KeyboardLogEvent.TOGGLE_CAPS_LOCK);
return true;
}
}
break;
case KeyEvent.KEYCODE_CAPS_LOCK:
if (!down) {
logKeyboardSystemsEvent(event, KeyboardLogEvent.TOGGLE_CAPS_LOCK);
}
break;
case KeyEvent.KEYCODE_STYLUS_BUTTON_PRIMARY:
case KeyEvent.KEYCODE_STYLUS_BUTTON_SECONDARY:
case KeyEvent.KEYCODE_STYLUS_BUTTON_TERTIARY:
case KeyEvent.KEYCODE_STYLUS_BUTTON_TAIL:
Slog.wtf(TAG, "KEYCODE_STYLUS_BUTTON_* should be handled in"
+ " interceptKeyBeforeQueueing");
return true;
case KeyEvent.KEYCODE_SETTINGS:
if (mShortPressOnSettingsBehavior == SHORT_PRESS_SETTINGS_NOTIFICATION_PANEL) {
if (!down) {
toggleNotificationPanel();
logKeyboardSystemsEvent(event, KeyboardLogEvent.TOGGLE_NOTIFICATION_PANEL);
}
return true;
}
break;
case KeyEvent.KEYCODE_STEM_PRIMARY:
if (prepareToSendSystemKeyToApplication(focusedToken, event)) {
// Send to app.
return false;
} else {
// Intercepted.
sendSystemKeyToStatusBarAsync(event);
return true;
}
case KeyEvent.KEYCODE_SCREENSHOT:
if (emojiAndScreenshotKeycodesAvailable() && down && repeatCount == 0) {
interceptScreenshotChord(SCREENSHOT_KEY_OTHER, 0 /*pressDelay*/);
}
return true;
}
if (isValidGlobalKey(keyCode)
&& mGlobalKeyManager.handleGlobalKey(mContext, keyCode, event)) {
return true;
}
// Reserve all the META modifier combos for system behavior
return (metaState & KeyEvent.META_META_ON) != 0;
}
源码举例说明
控制中,如下:
case KeyEvent.KEYCODE_BRIGHTNESS_UP:
case KeyEvent.KEYCODE_BRIGHTNESS_DOWN:
if (down) {
int direction = keyCode == KeyEvent.KEYCODE_BRIGHTNESS_UP ? 1 : -1;
// Disable autobrightness if it's on
int auto = Settings.System.getIntForUser(
mContext.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS_MODE,
Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL,
UserHandle.USER_CURRENT_OR_SELF);
if (auto != 0) {
Settings.System.putIntForUser(mContext.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS_MODE,
Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL,
UserHandle.USER_CURRENT_OR_SELF);
}
int screenDisplayId = displayId < 0 ? DEFAULT_DISPLAY : displayId;
float minLinearBrightness = mPowerManager.getBrightnessConstraint(
PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MINIMUM);
float maxLinearBrightness = mPowerManager.getBrightnessConstraint(
PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MAXIMUM);
float linearBrightness = mDisplayManager.getBrightness(screenDisplayId);
float gammaBrightness = BrightnessUtils.convertLinearToGamma(linearBrightness);
float adjustedGammaBrightness =
gammaBrightness + 1f / BRIGHTNESS_STEPS * direction;
adjustedGammaBrightness = MathUtils.constrain(adjustedGammaBrightness, 0f,
1f);
float adjustedLinearBrightness = BrightnessUtils.convertGammaToLinear(
adjustedGammaBrightness);
adjustedLinearBrightness = MathUtils.constrain(adjustedLinearBrightness,
minLinearBrightness, maxLinearBrightness);
mDisplayManager.setBrightness(screenDisplayId, adjustedLinearBrightness);
Intent intent = new Intent(Intent.ACTION_SHOW_BRIGHTNESS_DIALOG);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION
| Intent.FLAG_ACTIVITY_NO_USER_ACTION);
intent.putExtra(EXTRA_FROM_BRIGHTNESS_KEY, true);
startActivityAsUser(intent, UserHandle.CURRENT_OR_SELF);
logKeyboardSystemsEvent(event, KeyboardLogEvent.getBrightnessEvent(keyCode));
}
return true;
这里消费亮度
业务逻辑如下:
- 获取当前亮度模式
- 获取当前亮度、最大亮度、最小亮度
- 调节亮度【用到了亮度曲线 从伽马曲线】
- 发送亮度控制的Intent
的接受者【实际为BrightnessDialog】
声音音量也是一样的,在这个方法中进行了处理一次,再响应给View来处理