Android关于view按键音的修改

本文探讨了Android系统中View的按键音,揭示了按键音实际上是与媒体音量(STREAM_MUSIC)绑定的。通过分析源码,从View的点击事件开始,追踪到AudioService,发现按键音的STREAM_TYPE为STREAM_SYSTEM,但其音量受媒体音量控制。

首先简单介绍下预备知识:

1.Android的audio流的类型有以下12种:

/* The audio stream for phone calls */
    public static final int STREAM_VOICE_CALL = 0;//通话连接时的音频流(通话声)
    /* The audio stream for system sounds */
    public static final int STREAM_SYSTEM = 1;//系统音频流
    /* The audio stream for the phone ring and message alerts */
    public static final int STREAM_RING = 2;//来电铃声
    /* The audio stream for music playback */
    public static final int STREAM_MUSIC = 3;//媒体音频流
    /* The audio stream for alarms */
    public static final int STREAM_ALARM = 4;//闹钟音频流
    /* The audio stream for notifications */
    public static final int STREAM_NOTIFICATION = 5;//通知音频流
    /* @hide The audio stream for phone calls when connected on bluetooth */
    public static final int STREAM_BLUETOOTH_SCO = 6;//从注释上看时使用蓝牙耳机通话的音频流
    /* @hide The audio stream for enforced system sounds in certain countries (e.g camera in Japan) */
    public static final int STREAM_SYSTEM_ENFORCED = 7;//一些国家强制使用的音频流??不太明白
    /* @hide The audio stream for DTMF tones */
    public static final int STREAM_DTMF = 8;//DTMF音频流
    /* @hide The audio stream for text to speech (TTS) */
    public static final int STREAM_TTS = 9;//TTS: Text to Speech:文件到语言的音频流,即机器说话
    /* @hide The audio stream for Fm */
    public static final int STREAM_FM = 10;//FM的音频流
    /* @hide The audio stream for MATV */
    public static final int STREAM_MATV = 11;//TV的音频流

每种音频流所规定的最大值:


   /** @hide Maximum volume index values for audio streams */
    private int[] MAX_STREAM_VOLUME = new int[] {
        6,  // STREAM_VOICE_CALL
        7,  // STREAM_SYSTEM
        7,  // STREAM_RING
        12, // STREAM_MUSIC
        7,  // STREAM_ALARM
        7,  // STREAM_NOTIFICATION
        15, // STREAM_BLUETOOTH_SCO
        7,  // STREAM_SYSTEM_ENFORCED
        15, // STREAM_DTMF
        15, // STREAM_TTS
        13, //STREAM_FM
        13  //stream_MATV
    };

2.所有的按键事件都是touch事件,这部分我会另外开篇博文介绍。


开始本文正文,Anndroid系统中所有View带有按键音,用户可以通过Settings>Sound>勾选Audible Selection即可开启按键音。但是有个奇怪的地方:此按键音是与媒体音量(即STREAM_MUSIC)绑定的,难道按键音的STREAM TYPE就是STREAM_MUSIC吗?我们从代码中寻找一下。


首先所有的View点击的时候都有按键音,我们从View.java的点击事件找起,在view的响应的onTouchEvent()方法中有如下代码:


 switch (event.getAction()) {
                case MotionEvent.ACTION_UP:
                    boolean prepressed = (mPrivateFlags & PREPRESSED) != 0;
                    if ((mPrivateFlags & PRESSED) != 0 || prepressed) {
                        // take focus if we don't have it already and we should in
                        // touch mode.
                        boolean focusTaken = false;
                        if (isFocusable() && isFocusableInTouchMode() && !isFocused()) {
                            focusTaken = requestFocus();
                        }

                        if (!mHasPerformedLongPress) {
                         
<think> 首先,用户的问题是:“我想查找在Android TV上屏蔽按键音的方法 请问Android TV屏蔽按键音的方法”。这是在Android TV上禁用按键声音的查询。 从系统级指令中,我需要遵循规则: - 所有行内数学表达式使用 $...$ 格式。 - 独立公式使用 $$...$$ 格式并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 在回答中引用的段落末尾自然地添加引用标识,如 [^1]。 回顾用户提供的引用: - 引用[1]: 讨论了按键音无效的情况,可能因为按键被拦截或消费。提到使用adb命令检查声音设置:`adb shell Settings get sound_effects_enabled`(1开启0关闭)。还描述了按键事件的处理流程。 - 引用[2]: 关于控制焦点按键速度,用于解决RecyclerView焦点问题。 - 引用[3]: Android TV默认关闭系统触摸和遥控器按键音,通过修改SettingsProvider的defaults.xml文件:`<bool name="def_sound_effects_enabled">false</bool>`。 用户的问题是屏蔽按键音的方法,所以我应该基于这些引用提供方法。 关键点: - 按键音由系统的声音效果设置控制。 - 方法可能包括: - 系统级别:修改默认设置,如引用[3]所示。 - 应用级别:在代码中拦截按键事件或使用API禁用声音。 用户的查询是“屏蔽按键音的方法”,所以我需要提供一个清晰的步骤指南。 回答结构: 1. **介绍问题**:简要解释Android TV按键音。 2. **提供方法**:列出几种屏蔽按键音的方法,基于引用。 - 方法1:通过系统设置禁用声音效果(用户手动设置)。 - 方法2:在应用中代码控制,如使用`playSoundEffect()`或拦截按键事件。 - 方法3:修改系统默认设置(开发者或设备制造商级别)。 3. **引用来源**:在相关部分末尾添加引用标识。 4. **生成相关问题**:在结尾添加相关问题部分。 确保回答真实可靠: - 基于Android开发文档和常见实践。 - 使用引用作为支持。 步骤: 1. **检查当前设置**:建议用户先检查声音效果是否已启用,使用adb命令:`adb shell Settings get sound_effects_enabled` [^1]。 2. **在应用中禁用按键音**: - 在按键事件处理中,覆盖`dispatchKeyEvent`或类似方法,不调用`playSoundEffect()`。 - 示例代码:如果用户注册了点击监听器,确保不触发声音。 3. **全局禁用按键音**: - 用户可以在系统设置中手动禁用(如果可用)。 - 对于开发者:可以在代码中设置系统设置,例如: ```java Settings.System.putInt(getContentResolver(), Settings.System.SOUND_EFFECTS_ENABLED, 0); ``` - 设备制造商:可以通过修改`defaults.xml`文件设置默认关闭,如引用[3]所示 [^3]。 4. **处理按键事件**:如果按键被拦截或消费,按键音可能不会被播放,如引用[1]中提到 [^1]。 生成相关问题: - 基于主题,生成3-4个相关问题,例如: 1. 如何检查Android TV上的按键音设置? 2. 在应用中如何自定义按键音? 3. Android TV按键事件分发机制是什么? 4. 如何处理RecyclerView中的焦点问题? 回答格式: - 使用中文。 - 结构清晰:引言、方法列表、代码示例(如果需要)、相关问题。 - 添加引用标识自然地在末尾。 完整回答大纲: 1. 引言:解释Android TV按键音控制方式。 2. 方法1:通过adb或系统设置检查并禁用声音效果。 3. 方法2:在应用中代码控制按键音。 4. 方法3:修改系统默认设置。 5. 相关问题部分。 </think> ### Android TV屏蔽按键音的方法 在Android TV上,按键音(按键反馈声音)是由系统声音效果设置控制的。屏蔽按键音的方法包括系统级别和应用级别的操作。以下是基于引用资料的逐步说明,确保方法真实可靠。(注意:某些操作需要开发权限或root访问。) #### 1. **检查当前按键音设置** 在尝试屏蔽前,建议先确认声音效果是否已启用。使用adb命令检查系统设置: ```bash adb shell Settings get sound_effects_enabled ``` - 返回值 `1` 表示启用,`0` 表示禁用。 - 如果返回 `0`,按键音已被屏蔽;否则需要进一步操作 [^1]。 #### 2. **在应用中代码级别屏蔽按键音** 如果按键音在特定页面无效(如引用[1]所述),可能是通过按键事件拦截实现的。在Activity或Fragment中覆盖按键分发方法: - **覆盖`dispatchKeyEvent`或`onKeyDown/onKeyUp`**:在这些方法中消费按键事件,避免调用`playSoundEffect()`。 ```java @Override public boolean dispatchKeyEvent(KeyEvent event) { if (event.getAction() == KeyEvent.ACTION_DOWN) { // 消费事件,不播放声音 return true; // 返回true表示事件被消费,按键音不会触发 } return super.dispatchKeyEvent(event); } ``` - **避免在点击监听器中触发声音**:如果用户注册了`OnClickListener`,确保不调用`playSoundEffect()`。例如: ```java button.setOnClickListener(v -> { // 执行操作,但不调用 v.playSoundEffect(SoundEffectConstants.CLICK); }); ``` 此方法适用于屏蔽特定View按键音,但需注意过度拦截可能影响焦点导航 [^1]。 #### 3. **全局屏蔽按键音(系统级别)** - **用户手动禁用**:在Android TV系统设置中导航到“声音”或“辅助功能”,关闭“按键音效”(路径可能因设备而异)。 - **通过代码修改系统设置**:在应用中动态禁用声音效果(需要`WRITE_SETTINGS`权限)。 ```java Settings.System.putInt(getContentResolver(), Settings.System.SOUND_EFFECTS_ENABLED, 0); ``` 此方法对所有应用生效,但需用户授权。 - **设备制造商或ROM级别修改**:引用[3]显示,Android TV默认关闭按键音可通过修改系统文件实现。在源码中编辑: ```xml <!-- frameworks/base/packages/SettingsProvider/res/values/defaults.xml --> <bool name="def_sound_effects_enabled">false</bool> <!-- 设为false关闭默认按键音 --> ``` 适用于开发者或OEM,需重新编译系统 [^3]。 #### 4. **特殊情况处理** - **焦点问题导致的按键音失效**:如引用[2]所述,焦点速度控制可能间接影响按键音。在`BaseActivity`中添加按键延迟处理: ```java @Override public boolean dispatchKeyEvent(KeyEvent event) { if (event.getRepeatCount() > 0) { // 长按事件 return true; // 消费事件,避免按键音和焦点混乱 } return super.dispatchKeyEvent(event); } ``` 此方法可解决RecyclerView长按焦点问题,同时屏蔽多余按键音 [^2]。 ### 注意事项 - **权限要求**:代码修改需要`android.permission.WRITE_SETTINGS`权限,并在AndroidManifest.xml中声明。 - **测试建议**:使用adb命令`adb shell settings put system sound_effects_enabled 0`临时测试效果。 - **兼容性**:不同Android TV版本(如Android 10+)可能有API差异,建议在目标设备验证。
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值