本文转载自:http://blog.csdn.net/Jin_HeZai/article/details/46791567

近期任务,涉及Android触摸提示音。 
首先,定位源码目标。很显然的,在原生的设置的声音功能页里面就包含了触摸音的开关。 
那么我们找到对应的java代码,SoundSettings.java

package com.android.settings;
import java.util.List; public class SoundSettings extends SettingsPreferenceFragment implements
Preference.OnPreferenceChangeListener {
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

可以看到 这是个PreferenceFragment的子类。(这里的SettingsPreferenceFragment是继承PreferenceFragment)。那么找到它对应的xml文件。

 @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ContentResolver resolver = getContentResolver();
int activePhoneType = TelephonyManager.getDefault().getCurrentPhoneType(); mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); addPreferencesFromResource(R.xml.sound_settings);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

常识性的,它在onCreate里面,找到addPreferencesFromResource,然后查看sound_settings的xml文件。 
这里我通过查找中文string资源文件,标示了xml文件的一些item的title。

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
android:title="@string/sound_settings"
android:key="sound_settings"
xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"> <!-- 音量-->
<com.android.settings.RingerVolumePreference
android:key="ring_volume"
android:title="@string/all_volume_title"
android:dialogTitle="@string/all_volume_title"
android:persistent="false"
android:streamType="ring" />
<!-- 音乐效果-->
<Preference
android:key="musicfx"
android:title="@string/musicfx_title">
<intent android:targetPackage="com.android.musicfx"
android:targetClass="com.android.musicfx.ControlPanelPicker" />
</Preference>
<!-- 来电铃声和振动-->
<PreferenceCategory
android:key="category_calls_and_notification"
android:title="@string/sound_category_call_ringtone_vibrate_title"/> <!-- Do not nest these, or removals in code will break
手机铃声
-->
<com.android.settings.DefaultRingtonePreference
android:key="ringtone"
android:title="@string/ringtone_title"
android:dialogTitle="@string/ringtone_title"
android:persistent="false"
android:ringtoneType="ringtone" /> <!-- 响铃时振动-->
<CheckBoxPreference
android:key="vibrate_when_ringing"
android:title="@string/vibrate_when_ringing_title"
android:persistent="false" />
<!-- 系统-->
<PreferenceCategory
android:title="@string/sound_category_system_title"/> <!-- Do not nest these, or removals in code will break -->
<!-- 默认通知提示音-->
<com.android.settings.DefaultRingtonePreference
android:key="notification_sound"
android:title="@string/notification_sound_title"
android:dialogTitle="@string/notification_sound_dialog_title"
android:persistent="false"
android:ringtoneType="notification" /> <!-- 拨号键盘触摸音效-->
<CheckBoxPreference
android:key="dtmf_tone"
android:title="@string/dtmf_tone_enable_title"
android:defaultValue="true" />
<!-- 触摸提示音-->
<CheckBoxPreference
android:key="sound_effects"
android:title="@string/sound_effects_enable_title"
android:defaultValue="true" /> <!-- 锁屏提示音-->
<CheckBoxPreference
android:key="lock_sounds"
android:title="@string/lock_sounds_enable_title"
android:defaultValue="true" />
<!-- 触摸时振动-->
<CheckBoxPreference
android:key="haptic_feedback"
android:title="@string/haptic_feedback_enable_title"
android:defaultValue="true" />
<!-- 紧急提示音-->
<ListPreference
android:key="emergency_tone"
android:title="@string/emergency_tone_title"
android:entries="@array/emergency_tone_entries"
android:entryValues="@array/emergency_tone_values" />
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81

OK,接着我们在SoundSettings里面搜索关键字: sound_effects

private static final String KEY_SOUND_EFFECTS = "sound_effects";
  • 1
  • 2

接着搜索:KEY_SOUND_EFFECTS

        // 触摸提示音相关
mSoundEffects = (CheckBoxPreference) findPreference(KEY_SOUND_EFFECTS);
mSoundEffects.setPersistent(false);
mSoundEffects.setChecked(Settings.System.getInt(resolver,
Settings.System.SOUND_EFFECTS_ENABLED, 1) != 0);
  • 1
  • 2
  • 3
  • 4
  • 5
    @Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
if (preference == mVibrateWhenRinging) {
Settings.System.putInt(getContentResolver(), Settings.System.VIBRATE_WHEN_RINGING,
mVibrateWhenRinging.isChecked() ? 1 : 0);
} else if (preference == mDtmfTone) {
Settings.System.putInt(getContentResolver(), Settings.System.DTMF_TONE_WHEN_DIALING,
mDtmfTone.isChecked() ? 1 : 0); } else if (preference == mSoundEffects) {
if (mSoundEffects.isChecked()) {
mAudioManager.loadSoundEffects();
} else {
mAudioManager.unloadSoundEffects();
}
Settings.System.putInt(getContentResolver(), Settings.System.SOUND_EFFECTS_ENABLED,
mSoundEffects.isChecked() ? 1 : 0); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

这里我们很容易的看清楚它的实例和点击监听,都是通过修改系统配置来进行操作的,那么这玩意到底在哪里整呢? 
首先,触摸提示音,是对所有的view的点击时间都会有触发效果,那么我们看看View.java的类。 
View.java有将近2万行,想研究的彻底很明显是不现实,或者说,不轻松的。那么我们搜素SOUND_EFFECTS_ENABLED 这个关键字

    /**
* View flag indicating whether this view should have sound effects enabled
* for events such as clicking and touching.
*/
public static final int SOUND_EFFECTS_ENABLED = 0x08000000;
  • 1
  • 2
  • 3
  • 4
  • 5

看注释,意思是是否启动声音效果。

    /**
* Set whether this view should have sound effects enabled for events such as
* clicking and touching.
*
* <p>You may wish to disable sound effects for a view if you already play sounds,
* for instance, a dial key that plays dtmf tones.
*
* @param soundEffectsEnabled whether sound effects are enabled for this view.
* @see #isSoundEffectsEnabled()
* @see #playSoundEffect(int)
* @attr ref android.R.styleable#View_soundEffectsEnabled
*/
public void setSoundEffectsEnabled(boolean soundEffectsEnabled) {
setFlags(soundEffectsEnabled ? SOUND_EFFECTS_ENABLED: 0, SOUND_EFFECTS_ENABLED);
} /**
* @return whether this view should have sound effects enabled for events such as
* clicking and touching.
*
* @see #setSoundEffectsEnabled(boolean)
* @see #playSoundEffect(int)
* @attr ref android.R.styleable#View_soundEffectsEnabled
*/
@ViewDebug.ExportedProperty
public boolean isSoundEffectsEnabled() {
return SOUND_EFFECTS_ENABLED == (mViewFlags & SOUND_EFFECTS_ENABLED);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

看到这2个方法我就有底了。很明显,我们要查看isSoundEffectsEnabled的调用关系。

    /**
* Play a sound effect for this view.
*
* <p>The framework will play sound effects for some built in actions, such as
* clicking, but you may wish to play these effects in your widget,
* for instance, for internal navigation.
*
* <p>The sound effect will only be played if sound effects are enabled by the user, and
* {@link #isSoundEffectsEnabled()} is true.
*
* @param soundConstant One of the constants defined in {@link SoundEffectConstants}
*/
public void playSoundEffect(int soundConstant) {
if (mAttachInfo == null || mAttachInfo.mRootCallbacks == null || !isSoundEffectsEnabled()) {
return;
}
mAttachInfo.mRootCallbacks.playSoundEffect(soundConstant);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

接着我们看谁调用了它,找到在AudioServeice.java中

    /** @see AudioManager#playSoundEffect(int) */
public void playSoundEffect(int effectType) {
playSoundEffectVolume(effectType, -1.0f);
} /** @see AudioManager#playSoundEffect(int, float) */
public void playSoundEffectVolume(int effectType, float volume) {
sendMsg(mAudioHandler, MSG_PLAY_SOUND_EFFECT, SENDMSG_QUEUE,
effectType, (int) (volume * 1000), null, 0);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

写到这里,就是完了。接下来的需要,也就是对触摸音的资源文件的修改,它的位置在framework/base/data/sounds/effects 文件夹下。(同时这个文件夹的ogg下面也有一个相同的文件,这个我还不清楚)Effect_Tick.ogg。 
对应的是在Android system/media/audio/ui Effect_Tick.ogg的文件。 
想要修改它的话,可以在编译room的时候替换了它,或者push 一个新的同名文件。

Android 触摸提示音【转】的更多相关文章

  1. 修改Android系统的触摸提示音【学习笔记】

    平台信息:内核:Linux version 3.10.0系统:android/android6.0平台:rk3288 作者:庄泽彬(欢迎转载,请注明作者) 邮箱:2760715357@qq.com 本 ...

  2. 【转】Android中通知的提示音、震动和LED灯效果小例子

    通知(Notification)是 Android 系统中比较有特色的一个功能,当某个应用程序希望向用户发出一些提示信息,而该应用程序又不在前台运行时,就可以借助通知来实现.发出一条通知后,手机最上方 ...

  3. android开发(44) 使用了 SoundPool 播放提示音

    SoundPool 一个声音播放的辅助类,从名字可以看出,它具有 “池”的能力,它先加载声音文件到内存,以支持多次播放声音文件. 特点 SoundPool适合 短小的 声音文件 SoundPool适合 ...

  4. Android 极光推送JPush---自定义提示音

    极光推送提供三种方法实现Notification通知 三方开发平台发送普通消息,客户端设置PushNotificationBuilder,实现基础的Notification通知 三方开放平台发送普通消 ...

  5. Android笔记: 播放提示音 的简单方法

    public static void sendSound(Context mContext) { //上下文 Uri mUri= RingtoneManager.getDefaultUri(Ringt ...

  6. Android 手动按power键上锁,没有锁屏提示音,无法恢复【单机必现】

    測试步骤 [測试版本号]T0606 [模块版本号] NAVI锁屏:5.0.0.ck [測试步骤] 1.手动按power键上锁, [測试结果] 没有锁屏提示音,无法恢复[单机必现] [预期结果] 有提示 ...

  7. Android IOS WebRTC 音视频开发总结(六)-- iOS开发之含泪经验

    前段时间在搞webrtc iOS开发,所以将标题改为了Android IOS WebRTC 音视频开发总结, 下面都是开发过程中的经验总结,转载请说明出处(博客园RTC.Blacker): 1. IO ...

  8. Android IOS WebRTC 音视频开发总结(八十五)-- 使用WebRTC广播网络摄像头视频(下)

    本文主要介绍WebRTC (我们翻译和整理的,译者:weizhenwei,校验:blacker),最早发表在[编风网] 支持原创,转载必须注明出处,欢迎关注我的微信公众号blacker(微信ID:bl ...

  9. Android IOS WebRTC 音视频开发总结(八十三)-- 使用WebRTC广播网络摄像头视频(上)

    本文主要介绍WebRTC (我们翻译和整理的,译者:weizhenwei,校验:blacker),最早发表在[编风网] 支持原创,转载必须注明出处,欢迎关注我的微信公众号blacker(微信ID:bl ...

随机推荐

  1. Win实用好用软件清单推荐

    1. 我的Win实用软件清单 排名不分先后且长期更新 有更好用的或者需要帮助的可以留言----最后一次更新于 2019.06.25 1. Dism++ 1.1. 功能: ​ 系统精简.垃圾清理.系统升 ...

  2. Python学习第二阶段Day2,模块time/datetime、random、os、sys、shutil

    1.Time.  Datetime(常用) UTC时间:为世界标准时间,时区为0的时间 北京时间,UTC+8东八区 import time print(time.time()) # timestamp ...

  3. PAT 1020. Tree Traversals

    PAT 1020. Tree Traversals Suppose that all the keys in a binary tree are distinct positive integers. ...

  4. codechef 写题计划

    此后将查找各种codechef的脑洞题和好题写

  5. SpringSecurity 获取认证信息 和 认证实现

    JdbcDaoImpl 实现获取认证信息 PasswordEncoder 实现具体认证过程

  6. unigui的ini文件读写【6】

    procedure THeaderFooterForm.writerParas; var IniFile : TIniFile; begin try IniFile:=TIniFile.Create( ...

  7. Microsoft 根证书计划弃用 SHA-1 哈希算法

    Microsoft 根证书计划弃用 SHA-1 哈希算法 微软官方2016年1月12日发布安全通报,自2016年1月1日起Microsoft 已经发布代码弃用变更,也就是说2016年1月1号后用SHA ...

  8. ceph 简介

    Ceph 存储集群 数据的存储 伸缩性和高可用性 CRUSH 简介 集群运行图 高可用监视器 高可用性认证 智能程序支撑超大规模 动态集群管理 关于存储池 PG 映射到 OSD 计算 PG ID 互联 ...

  9. CodeForcesGym 100753F Divisions

    Divisions Time Limit: 2000ms Memory Limit: 262144KB This problem will be judged on CodeForcesGym. Or ...

  10. C. Hexadecimal's Numbers

    C. Hexadecimal's Numbers time limit per test 1 second memory limit per test 64 megabytes input stand ...