按键音流程"/>
【Android】系统按键音流程
需求
系统按键音设置后不起作用,需要放开
系统:Android8.1
相关文件查找
布局文件
通过代码搜索“触摸提示音”,找到string对应的名称:“touch_sounds_title”,最后将文件定位到other_sound_settings.xml以及sound_settings.xml
<!-- Touch sounds --><SwitchPreferenceandroid:key="touch_sounds"android:title="@string/touch_sounds_title" />
java文件
通过touch_sounds定位到文件TouchSoundPreferenceController.java
流程
安卓设置中的声音设置页面
通过ARDC开启监测,定位到当前页面内的activity
找到Settings\AndroidManifest.xml
<activityandroid:name="Settings$SoundSettingsActivity"android:label="@string/sound_settings"android:icon="@drawable/ic_homepage_sound"android:exported="true"android:taskAffinity="com.android.settings"android:parentActivityName="Settings"><intent-filter android:priority="1"><action android:name="com.android.settings.SOUND_SETTINGS" /><action android:name="android.settings.SOUND_SETTINGS" /><action android:name="android.settings.ACTION_OTHER_SOUND_SETTINGS" /><category android:name="android.intent.category.DEFAULT" /></intent-filter><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.DEFAULT" /><category android:name="android.intent.category.VOICE_LAUNCH" /><category android:name="com.android.settings.SHORTCUT" /></intent-filter><intent-filter android:priority="6"><action android:name="com.android.settings.action.SETTINGS" /></intent-filter><meta-data android:name="com.android.settings.category"android:value="com.android.settings.category.ia.homepage" /><meta-data android:name="com.android.settings.FRAGMENT_CLASS"android:value="com.android.settings.notification.SoundSettings" /><meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"android:value="true" /><meta-data android:name="com.android.settings.summary"android:resource="@string/sound_dashboard_summary"/></activity>
其中
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"android:value="com.android.settings.notification.SoundSettings" />
表明点击会跳转至该页面(fragment),也就是SoundSettings页面
里面有各种声音相关的设置,其中TouchSoundPreferenceController就是触摸提示音相关
TouchSoundPreferenceController
\packages\apps\Settings\src\com\android\settings\notification\TouchSoundPreferenceController.java
public TouchSoundPreferenceController(Context context, SettingsPreferenceFragment parent,Lifecycle lifecycle) {super(context, parent, lifecycle);mPreference = new SettingPref(TYPE_SYSTEM, KEY_TOUCH_SOUNDS, System.SOUND_EFFECTS_ENABLED, DEFAULT_ON) {@Overrideprotected boolean setSetting(final Context context, final int value) {AsyncTask.execute(new Runnable() {@Overridepublic void run() {final AudioManager am =(AudioManager) context.getSystemService(Context.AUDIO_SERVICE);if (value != 0) {am.loadSoundEffects();} else {am.unloadSoundEffects();}}});return super.setSetting(context, value);}};}
先对System属性值赋值
mPreference = new SettingPref(TYPE_SYSTEM, KEY_TOUCH_SOUNDS, System.SOUND_EFFECTS_ENABLED, DEFAULT_ON){};
PS:使用adb获取按键提示音的状态
adb shell settings get system sound_effects_enabled
监听按键的变化,来选择加载或关闭提示音
am.loadSoundEffects();
am.unloadSoundEffects();
进入framework层,调用系统服务等
framework
framework\base\media\java\android\media\AudioManager.java
public void loadSoundEffects() {final IAudioService service = getService();//获取AudioService对象try {service.loadSoundEffects();//调用AudioService中方法} catch (RemoteException e) {throw e.rethrowFromSystemServer();}}
private static IAudioService getService(){if (sService != null) {return sService;}IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE);//通过binder调用AudioServicesService = IAudioService.Stub.asInterface(b);return sService;}
framework\base\services\core\java\com\android\server\audio\AudioService.java
public boolean loadSoundEffects() {int attempts = 3;LoadSoundEffectReply reply = new LoadSoundEffectReply();synchronized (reply) {sendMsg(mAudioHandler, MSG_LOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, reply, 0);while ((reply.mStatus == 1) && (attempts-- > 0)) {try {reply.wait(SOUND_EFFECTS_LOAD_TIMEOUT_MS);} catch (InterruptedException e) {Log.w(TAG, "loadSoundEffects Interrupted while waiting sound pool loaded.");Thread.currentThread().interrupt();}}}return (reply.mStatus == 0);}
其中,发送广播
sendMsg(mAudioHandler, MSG_LOAD_SOUND_EFFECTS, SENDMSG_QUEUE, 0, 0, reply, 0);
内部处理
private class AudioHandler extend Handler{...@Overridepublic void handleMessage(Message msg){switch(msg.what){case MSG_LOAD_SOUND_EFFECTS:boolean loaded = onLoadSoundEffects();//调用方法,加载音效if (msg.obj != null) {LoadSoundEffectReply reply = (LoadSoundEffectReply)msg.obj;synchronized (reply) {reply.mStatus = loaded ? 0 : -1;reply.notify();}}break;}}
}
同时也就是在这里,我找到了处理播放音效的方法,之前一直对System.SOUND_EFFECTS_ENABLED赋值不起作用,是该处将onPlaySoundEffect方法进行了屏蔽,放开,编译,刷机,成功,而且默认就是开启的
case MSG_PLAY_SOUND_EFFECT:onPlaySoundEffect(msg.arg1,msg.arg2);
至于为什么会关闭/隐藏该方法,之前合入三方应用的时候提过这个bug,开启之后会与其他应用冲突,所以选择了隐藏,触摸提示音时不走该方法
待定
- 点击后音效播放的加载、实现流程
更多推荐
【Android】系统按键音流程
发布评论