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

【SystemUI】新增实体键盘快捷键说明

一、问题描述

基于 Android 14平台,设备外接键盘,Android 原生中的设置 - 键盘 - 实体键盘 - 键盘快捷键中可以查看系统输入已开应用当前应用四类快捷方式,但是外接键盘是有触摸板的,未介绍触摸板手势的说明,需要添加。并且默认的快捷键存在部分功能不存在需要移除,部分快捷键的图示显示错误需要修改。

在这里插入图片描述

二、问题分析

我们需要根据设置的入口来定位实际调用快捷键说明的界面,点击实体键盘菜单查看日志:adb logcat -s SubSettings ,可以定位到 PhysicalKeyboardFragment

<activity android:name="Settings$PhysicalKeyboardActivity"android:label="@string/physical_keyboard_title"android:exported="true"android:clearTaskOnLaunch="true"><intent-filter android:priority="1"><action android:name="android.settings.HARD_KEYBOARD_SETTINGS" /><category android:name="android.intent.category.DEFAULT" /></intent-filter><meta-data android:name="com.android.settings.FRAGMENT_CLASS"android:value="com.android.settings.inputmethod.PhysicalKeyboardFragment" /><meta-data android:name="com.android.settings.HIGHLIGHT_MENU_KEY"android:value="@string/menu_key_system"/>
</activity>

再定位到快捷键的点击事件执行的是 requestShowKeyboardShortcuts

Settings/src/com/android/settings/inputmethod/PhysicalKeyboardFragment.java
private void toggleKeyboardShortcutsMenu() {getActivity().requestShowKeyboardShortcuts();
}

查看此方法具体执行的发送一个广播,广播的接受者为 SystemUI

frameworks/base/core/java/android/app/Activity.java/*** Request the Keyboard Shortcuts screen to show up. This will trigger* {@link #onProvideKeyboardShortcuts} to retrieve the shortcuts for the foreground activity.*/
public final void requestShowKeyboardShortcuts() {final ComponentName sysuiComponent = ComponentName.unflattenFromString(getResources().getString(com.android.internal.R.string.config_systemUIServiceComponent));Intent intent = new Intent(Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS);intent.setPackage(sysuiComponent.getPackageName());sendBroadcastAsUser(intent, Process.myUserHandle());
}

组件如下

<!-- SystemUi service component -->
<string name="config_systemUIServiceComponent" translatable="false">com.android.systemui/com.android.systemui.SystemUIService</string>

action 如下

@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_SHOW_KEYBOARD_SHORTCUTS ="com.android.intent.action.SHOW_KEYBOARD_SHORTCUTS";

接下来根据 action name 查看 SystemUI 的 AndroidManifest.xml

<receiverandroid:name=".statusbar.KeyboardShortcutsReceiver"android:exported="true"><intent-filter><action android:name="com.android.intent.action.DISMISS_KEYBOARD_SHORTCUTS" /><action android:name="com.android.intent.action.SHOW_KEYBOARD_SHORTCUTS" /></intent-filter>
</receiver>

查看 src/com/android/systemui/statusbar/KeyboardShortcutsReceiver.java 中的 onReceive 中的处理,显示对话框调用的是 KeyboardShortcutListSearch.show(context, -1 /* deviceId unknown */);

public void onReceive(Context context, Intent intent) {if (mIsShortcutListSearchEnabled && Utilities.isLargeScreen(context)) {if (Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(intent.getAction())) {KeyboardShortcutListSearch.show(context, -1 /* deviceId unknown */);} else if (Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(intent.getAction())) KeyboardShortcutListSearch.dismiss();}} else {...
}

查看 src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java 中的 show 方法

public static void show(Context context, int deviceId) {MetricsLogger.visible(context,MetricsProto.MetricsEvent.KEYBOARD_SHORTCUTS_HELPER);synchronized (sLock) {if (sInstance != null && !sInstance.mContext.equals(context)) {dismiss();}getInstance(context).showKeyboardShortcuts(deviceId);}
}

具体执行的 showKeyboardShortcuts(int deviceId) -> showKeyboardShortcutSearchList -> handleShowKeyboardShortcutSearchList,可以查看到 对话框加载的 xml 布局

final View keyboardShortcutsView = inflater.inflate(R.layout.keyboard_shortcuts_search_view, null);

创建快捷键分类的执行的是 createHardcodedShortcuts

private void createHardcodedShortcuts() {// Add system shortcutsmKeySearchResultMap.put(SHORTCUT_SYSTEM_INDEX, true);mSystemGroup.add(getMultiMappingSystemShortcuts(mContext));mSystemGroup.add(getSystemMultitaskingShortcuts(mContext));// Add input shortcutsmKeySearchResultMap.put(SHORTCUT_INPUT_INDEX, true);mInputGroup.add(getMultiMappingInputShortcuts(mContext));// Add open apps shortcutsfinal List<KeyboardShortcutMultiMappingGroup> appShortcuts =Arrays.asList(getDefaultMultiMappingApplicationShortcuts());if (appShortcuts != null && !appShortcuts.isEmpty()) {mOpenAppsGroup = appShortcuts;mKeySearchResultMap.put(SHORTCUT_OPENAPPS_INDEX, true);} else {mKeySearchResultMap.put(SHORTCUT_OPENAPPS_INDEX, false);}
}

当前应用 是动态创建的,执行 showKeyboardShortcuts 创建

// Add specific app shortcuts
if (result.isEmpty()) {mKeySearchResultMap.put(SHORTCUT_SPECIFICAPP_INDEX, false);
} else {KeyboardShortcuts.sanitiseShortcuts(result);mSpecificAppGroup = reMapToKeyboardShortcutMultiMappingGroup(result);mKeySearchResultMap.put(SHORTCUT_SPECIFICAPP_INDEX, true);
}

具体的创建的每条快捷键说明的逻辑都在 KeyboardShortcutListSearch 类中,我们可以使用 adb 命令直接调出快捷键的对话框

adb shell am broadcast -a com.android.intent.action.SHOW_KEYBOARD_SHORTCUTS -p com.android.systemui

三、解决方案

1. 在 keyboard_shortcuts_search_view 创建触摸板分类

res/layout/keyboard_shortcuts_search_view.xml

<Buttonandroid:id="@+id/shortcut_touch_pad"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="12dp"style="@style/ShortCutButton"android:text="@string/keyboard_shortcut_touch_pad"/>

2. 在代码创建触摸板分类

private static int SHORTCUT_TOUCHPAD_INDEX = 4;private List<KeyboardShortcutMultiMappingGroup> mTouchPadGroup = new ArrayList<>();private Button mButtonTouchPad;

3. 创建触摸板快捷键说明

private void createHardcodedShortcuts() {...// Add keyboard touchpad usagemKeySearchResultMap.put(SHORTCUT_TOUCHPAD_INDEX, true);mTouchPadGroup.add(getTouchPadShortcuts(mContext));...
}private static KeyboardShortcutMultiMappingGroup getTouchPadShortcuts(Context context) {KeyboardShortcutMultiMappingGroup touchPadGroup =new KeyboardShortcutMultiMappingGroup(context.getString(R.string.keyboard_shortcut_group_touchpad),new ArrayList<>());// TouchPad shortcuts:String[] shortcutLabels = {context.getString(R.string.touchpad_press_left),context.getString(R.string.touchpad_press_right),context.getString(R.string.touchpad_one_finger_sliding),context.getString(R.string.touchpad_one_finger_click),context.getString(R.string.touchpad_two_fingers_click),context.getString(R.string.touchpad_two_fingers_sliding_left_right),context.getString(R.string.touchpad_two_fingers_sliding_up_down),context.getString(R.string.touchpad_three_fingers_sliding_up),context.getString(R.string.touchpad_three_fingers_sliding_down),context.getString(R.string.touchpad_three_fingers_sliding_left_right),};String[] shortcutCommandLabels = {context.getString(R.string.touchpad_command_press_left),context.getString(R.string.touchpad_command_press_right),context.getString(R.string.touchpad_command_one_finger_sliding),context.getString(R.string.touchpad_command_one_finger_click),context.getString(R.string.touchpad_command_two_fingers_click),context.getString(R.string.touchpad_command_two_fingers_sliding_left_right),context.getString(R.string.touchpad_command_two_fingers_sliding_up_down),context.getString(R.string.touchpad_command_three_fingers_sliding_up),context.getString(R.string.touchpad_command_three_fingers_sliding_down),context.getString(R.string.touchpad_command_three_fingers_sliding_left_right),};for (int i = 0; i < shortcutLabels.length; i++) {List<ShortcutKeyGroup> shortcutKeyGroups = Arrays.asList(new ShortcutKeyGroup(new KeyboardShortcutInfo(shortcutLabels[i],KeyEvent.KEYCODE_DPAD_UP,KeyEvent.META_META_ON | KeyEvent.META_CTRL_ON),shortcutCommandLabels[i]));ShortcutMultiMappingInfo shortcutMultiMappingInfo =new ShortcutMultiMappingInfo(shortcutLabels[i],null,shortcutKeyGroups);touchPadGroup.addItem(shortcutMultiMappingInfo);}return touchPadGroup;
}void showKeyboardShortcuts(int deviceId) {retrieveKeyCharacterMap(deviceId);mWindowManager.requestAppKeyboardShortcuts(new KeyboardShortcutsReceiver() {@Overridepublic void onKeyboardShortcutsReceived(final List<KeyboardShortcutGroup> result) {...//add keyboard touchpad usagemFullShortsGroup.add(SHORTCUT_TOUCHPAD_INDEX, mTouchPadGroup);...showKeyboardShortcutSearchList(mFullShortsGroup);}}, deviceId);
}

4. 添加按钮的点击事件

private void setButtonsDefaultStatus(View keyboardShortcutsView) {...mButtonTouchPad = keyboardShortcutsView.findViewById(R.id.shortcut_touch_pad);...// add keyboard touchpad usagemButtonTouchPad.setOnClickListener(v -> {setCurrentCategoryIndex(SHORTCUT_TOUCHPAD_INDEX);populateKeyboardShortcutSearchList(keyboardShortcutsView.findViewById(R.id.keyboard_shortcuts_container));});...mFullButtonList.add(mButtonTouchPad);...	
}
http://www.xdnf.cn/news/1369261.html

相关文章:

  • 常用Nginx正则匹配规则
  • ruoyi-vue(十二)——定时任务,缓存监控,服务监控以及系统接口
  • 软件检测报告:XML外部实体(XXE)注入漏洞原因和影响
  • 服务器初始化流程***
  • 在分布式环境下正确使用MyBatis二级缓存
  • 在 UniApp 中,实现下拉刷新
  • Python爬虫: 分布式爬虫架构讲解及实现
  • IjkPlayer 播放 MP4 视频时快进导致进度回退的问题
  • iOS 26 正式版即将发布,Flutter 完成全新 devicectl + lldb 的 Debug JIT 运行支持
  • 深度学习(三):PyTorch 损失函数:按任务分类的实用指南
  • Milvus介绍及多模态检索实践
  • 系统设计中的幂等性
  • 【LeetCode 热题 100】31. 下一个排列
  • 进入docker中mysql容器的方法
  • Linux(二十二)——服务器初始化指南
  • 把 shell 脚本里的「后台接收」-- 以 UART/CAN 双总线监听为例
  • 影响服务器托管费用的因素​
  • 论文阅读-CompletionFormer
  • 山中游玩播报
  • 简单聊聊光栅化技术
  • 虚拟机中kubeadim部署的k8s集群,虚拟机关机了,重新开机后集群状态能否正常恢复的两种可能(详解)
  • vue2 创建threejs场景
  • ubuntu20.04 终端安装claude
  • 事件驱动架构详解
  • .gitignore 文件相关使用配置
  • 服务器数据恢复—热备盘上线失败如何恢复数据?
  • Ansible 自动化运维工具:介绍与完整部署(RHEL 9)
  • 如何基于阿里云OpenSearch LLM搭建智能客服平台
  • 亚马逊类目合规风暴:高压清洗机品类整顿背后的运营重构与风险防御
  • 零基础构建MCP服务器TypeScriptPython双语言实战指南