【Android】系统按键音流程

需求

系统按键音设置后不起作用,需要放开
系统:Android8.1

相关文件查找

布局文件

通过代码搜索“触摸提示音”,找到string对应的名称:“touch_sounds_title”,最后将文件定位到other_sound_settings.xml以及sound_settings.xml

<!-- Touch sounds -->
        <SwitchPreference
          android:key="touch_sounds"
          android:title="@string/touch_sounds_title" />

java文件

通过touch_sounds定位到文件TouchSoundPreferenceController.java

流程

安卓设置中的声音设置页面

通过ARDC开启监测,定位到当前页面内的activity
在这里插入图片描述
找到Settings\AndroidManifest.xml

<activity
            android: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) {
            @Override
            protected boolean setSetting(final Context context, final int value) {
                AsyncTask.execute(new Runnable() {
                    @Override
                    public 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调用AudioService
        sService = 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{
	...
	@Override
	public 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,开启之后会与其他应用冲突,所以选择了隐藏,触摸提示音时不走该方法

待定

  • 点击后音效播放的加载、实现流程
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值