android设置中拖动音量条调节音量流程(android5.1)
来源:互联网 发布:windows光盘修复系统 编辑:程序博客网 时间:2024/05/16 14:59
前言:问题起源于客户通过SoundPool播放提示音,想要增大音量,硬件无法通过QACT查看音频参数,只能通过增大音源的办法,不过客户还是觉得轻了。中间需要我写个DEMO实验一下,但是上层怎样才能让硬件通过QACT看到音频参数,我实在是不知道,知道的同学可以留言指导我一下。
然后驱动就各种找碴,要我提供上层调节音量的流程,因为通过设置中拖动音量条是可以通过QACT看到参数的,并且也是短音频。所以我花了一番功夫追了下代码,现在记下来作为备用。(最后驱动通过一个列表查到SoundPool方法播放的是低延迟音频不经过DSP,明明驱动一眼能看到的东西非要我们上层查,真的烦!)
上层通过设置UI搜索到布局文件notification_settings.xml
notification_settings.xml(/packages/apps/Settings/res/xml)<!-- Media volume --><com.android.settings.notification.VolumeSeekBarPreference android:key="media_volume" android:icon="@*android:drawable/ic_audio_vol" android:title="@string/media_volume_option_title" /><!-- Alarm volume --><com.android.settings.notification.VolumeSeekBarPreference android:key="alarm_volume" android:icon="@*android:drawable/ic_audio_alarm" android:title="@string/alarm_volume_option_title" /><!-- Ring volume --><com.android.settings.notification.VolumeSeekBarPreference android:key="ring_volume" android:icon="@*android:drawable/ic_audio_ring_notif" android:title="@string/ring_volume_option_title" />
通过代码构造UI,初始化时会重写onProgressChanged方法
VolumeSeekBarPreference.java(/packages/apps/Settings/src/com/android/settings/notification)private void init() { ... @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) { if (mCallback != null) { mCallback.onStreamValueChanged(mStream, progress); } } ...}
下面这个callback找了很久,其实很简单
SeekBarVolumizer.java(/frameworks/base/core/java/android/preference)public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) { if (fromTouch) { postSetVolume(progress); } if (mCallback != null) { mCallback.onProgressChanged(seekBar, progress, fromTouch); }}public void onStopTrackingTouch(SeekBar seekBar) { postStartSample();}private void postStartSample() { if (mHandler == null) return; mHandler.removeMessages(MSG_START_SAMPLE); mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_START_SAMPLE), isSamplePlaying() ? CHECK_RINGTONE_PLAYBACK_DELAY_MS : 0);}@Overridepublic boolean handleMessage(Message msg) { switch (msg.what) { case MSG_START_SAMPLE: onStartSample(); break; }}private void onStartSample() { if (!isSamplePlaying()) { if (mCallback != null) { mCallback.onSampleStarting(this); } if (mRingtone != null) { try { mRingtone.play(); //走这里 } catch (Throwable e) { Log.w(TAG, "Error playing ringtone, stream " + mStreamType, e); } } }}Ringtone.java(/frameworks/base/media/java/android/media)/** * Plays the ringtone. */public void play() { if (mLocalPlayer != null) { // do not play ringtones if stream volume is 0 // (typically because ringer mode is silent). if (mAudioManager.getStreamVolume( AudioAttributes.toLegacyStreamType(mAudioAttributes)) != 0) { mLocalPlayer.start(); //走这里 } } else if (mAllowRemote && (mRemotePlayer != null)) { final Uri canonicalUri = mUri.getCanonicalUri(); try { mRemotePlayer.play(mRemoteToken, canonicalUri, mAudioAttributes); } catch (RemoteException e) { if (!playFallbackRingtone()) { Log.w(TAG, "Problem playing ringtone: " + e); } } } else { if (!playFallbackRingtone()) { Log.w(TAG, "Neither local nor remote playback available"); } }}MediaPlayer.java(/frameworks/base/media/java/android/media)public void start() throws IllegalStateException { if (isRestricted()) { _setVolume(0, 0); } stayAwake(true); _start();}private native void _start() throws IllegalStateException;android_media_MediaPlayer.cpp(/frameworks/base/media/jni){"_start", "()V", (void *)android_media_MediaPlayer_start},static voidandroid_media_MediaPlayer_start(JNIEnv *env, jobject thiz){ sp<MediaPlayer> mp = getMediaPlayer(env, thiz); if (mp == NULL ) { jniThrowException(env, "java/lang/IllegalStateException", NULL); return; } process_media_player_call( env, thiz, mp->start(), NULL, NULL ); //mp->start()}
之后的流程请参考:
[Android] AudioTrack::start
另外,拖动音量条时会播放一段示例音,媒体、闹钟、铃声都不同,加载资源的地方在构造SeekBarVolumizer时就定了:
SeekBarVolumizer.java(/frameworks/base/core/java/android/preference)public SeekBarVolumizer(Context context, int streamType, Uri defaultUri, Callback callback) { mContext = context; mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); mStreamType = streamType; mAffectedByRingerMode = mAudioManager.isStreamAffectedByRingerMode(mStreamType); mNotificationOrRing = isNotificationOrRing(mStreamType); if (mNotificationOrRing) { mRingerMode = mAudioManager.getRingerModeInternal(); } mMaxStreamVolume = mAudioManager.getStreamMaxVolume(mStreamType); mCallback = callback; mOriginalStreamVolume = mAudioManager.getStreamVolume(mStreamType); mMuted = mAudioManager.isStreamMute(mStreamType); if (mCallback != null) { mCallback.onMuted(mMuted); } if (defaultUri == null) { //根据不同流类型指定Uri资源 if (mStreamType == AudioManager.STREAM_RING) { defaultUri = Settings.System.DEFAULT_RINGTONE_URI; } else if (mStreamType == AudioManager.STREAM_NOTIFICATION) { defaultUri = Settings.System.DEFAULT_NOTIFICATION_URI; } else { defaultUri = Settings.System.DEFAULT_ALARM_ALERT_URI; } } mDefaultUri = defaultUri;}
阅读全文
0 0
- android设置中拖动音量条调节音量流程(android5.1)
- android5.0设置模块音量调节流程
- android 音量设置条
- audiosystem 音量调节流程
- Android 4.4 音量调节流程分析(一)
- Android 4.4 音量调节流程分析(二)
- Android 4.4 音量调节流程分析(一)
- Android 4.4 音量调节流程分析
- Android 4.4 音量调节流程分析(二)
- Android 4.4 音量调节流程分析(一)
- 拖动条音量控制
- Android5.1 Audio计算音量流程
- Android Audio音量设置流程
- 005 音量上下键调节音量流程
- Android音量调节原理
- Android调节音量
- Android音量控制调节
- Android之音量调节
- 3. 定位并添加Marker
- 使用SpringMVC和js实现文件及字段上传中遇到的坑
- Sublime Text格式化json数据
- 区分mp4格式里面mdat中的音频和视频数据
- UESTC
- android设置中拖动音量条调节音量流程(android5.1)
- 【《Real-Time Rendering 3rd》 提炼总结】(六) 第七章 · 高级着色:BRDF及相关技术
- Linux安装tomcat部署java web项目
- Mybatis中的resultType和resultMap
- CSU 1336: Interesting Calculator<BFS+优化><湖南省赛真题>
- ajax传递的参数值包含单引号
- 【G
- 热更plist后,游戏永远无法读取或者是重启后才可以读取的
- WEB-INF下jsp引用外部的静态资源