当前位置: 首页 > news >正文

KeyCode及KeyCode分发机制

文章目录

  • 需求场景
    • 纯KeyCode 快捷操作
    • KeyCode 按键响应操作、拦截
  • 一、工作中常用KeyCode
  • 二、KeyCode大全
  • 三、KeyCode 响应事件
    • 事件输入流程
    • 事件响应
      • 源码分析
      • 源码举例说明


需求场景

纯KeyCode 快捷操作

  • 经常在代码中实现返回、Home 、音量加减、截屏 等功能实现,代码中硬编码 shell 脚本 模拟 KeyCode事件
  • 物理按键调试,模拟物理按键测试用:按键功能,物理按键驱动层已经调试完成,但有没有完整的硬件方便调试,应用层模拟物理按键功能来调试。比如:Android方案中,电视产品、音箱产品、带屏的Android各种方案
    都是有物理按键的,如果自己测试验证物理按键的功能呢,那就需要自己来模拟KeyEventCode 来模拟按键,先自测。
  • 遥控器功能【投影产品】:一般根据蓝牙方案、红外方案实现遥控功能,传递给系统的都是Key的键值,系统自带标准的键值,这样就形成一套标准的流程了,系统根据键值做出反馈或者系统收到对应的键值反馈给上层,上层来处理业务逻辑。
  • 游戏类产品,手柄的控制。手柄上面的功能按钮其实就是一些物理按键,点击物理按键,系统或者应用监听后给出反馈。那么在实际测试的时候,就需要模拟按键来测试验证
  • 如果Android平板作为电脑使用,插上USB,那么Android平板作为电脑来时候,就必须响应键盘上面的所有按键,这些物理按键也是通过KeyCode
    来传递给系统,准确来说是系统来响应这些KeyCode,进而再处理响应的逻辑。

总的来讲:系统响应KeyCode,这些KeyCode是外设作为输入源,KeyCode 键值就是Android一套标准的协议

KeyCode 按键响应操作、拦截

比如物理按键操作之后,系统是如何分发、响应、处理、拦截呢? 比如我们需要客制化一些物理按键功能,如何实现呢?


一、工作中常用KeyCode

枚举值键值功能说明
KEYCODE_HOME3主屏幕键
KEYCODE_BACK4返回键
KEYCODE_DPAD_UP19向上方向键
KEYCODE_DPAD_DOWN20向下方向键
KEYCODE_DPAD_LEFT21向左方向键
KEYCODE_DPAD_RIGHT22向右方向键
KEYCODE_DPAD_CENTER23中心键
KEYCODE_VOLUME_UP24手机音量+
KEYCODE_VOLUME_DOWN25手机音量-
KEYCODE_POWER26电源键
KEYCODE_EXPLORER64启动浏览器程序
KEYCODE_MEDIA_PLAY_PAUSE85多媒体播放、暂停键
KEYCODE_MEDIA_STOP86停止键
KEYCODE_MEDIA_NEXT87下一首键
KEYCODE_MEDIA_PREVIOUS88上一首键
KEYCODE_MEDIA_REWIND89快退键
KEYCODE_MEDIA_FAST_FORWARD90快进键
KEYCODE_MEDIA_PLAY126播放键
KEYCODE_MEDIA_PAUSE127暂停键
KEYCODE_VOLUME_MUTE164手机扬声器静音
KEYCODE_APP_SWITCH187任务管理 最近历史任务
KEYCODE_MUSIC209启动音乐
KEYCODE_BRIGHTNESS_DOWN220亮度减少
KEYCODE_BRIGHTNESS_UP221亮度增加
KEYCODE_DPAD_DOWN_LEFT269向左下方向键
KEYCODE_DPAD_DOWN_RIGHT271向右下方向键
KEYCODE_DPAD_UP_LEFT268向左上方向键
KEYCODE_DPAD_UP_RIGHT270向右上方向键

备注:如何用命令来模拟执行按键操作
枚举方式: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 featuresfinal 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 onint 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 logicif (!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 behaviorreturn (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 onint 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来处理


http://www.mrgr.cn/news/29880.html

相关文章:

  • Chrome使用IE内核
  • 刘知远LLM——大模型微调:prompt-learningdelta tuning
  • TP6将HTML转换为PDF文件,非法UTF-8编码和中文乱码问题
  • Go语言中的`io.Copy`函数:高效的数据复制解决方案
  • 如何搭建自动化测试框架
  • Ecmascript(ES)标准
  • C++ 科目二 [reinterpret_cast]
  • Python VS Golng 谁更胜一筹?
  • 代码随想录Day 49|leetcode题目:42.接雨水、84.柱状图中最大矩形
  • 论文阅读 | 基于流模型和可逆噪声层的鲁棒水印框架(AAAI 2023)
  • Java零基础-抽象类详解
  • python:Django与Celery配合实现定时任务
  • Linux(ubuntu)(C语言开发-下载篇)
  • flutter Dio发送post请求
  • 八戒农场小程序V2最新源码
  • React-Hook原理
  • 数据库系统原理与应用【笔记总结】
  • Linux(Ubuntu)(终端实现helloworld输出)
  • 深入理解Spring中请求作用域的数据存储:ThreadLocal还是Spring容器?
  • javascript-数据类型
  • Cursor免费 GPT-4 IDE 工具的保姆级使用教程
  • Unity从2018.1版本开始,可以采用内置JSON进行存档和读档
  • Linux中权限和指令
  • 闯关leetcode——35. Search Insert Position
  • windows C++ 并行编程-异步消息块(一)
  • Linux驱动开发 ——架构体系