SeekBarVolumizer.java

从类的名字上看,这个类应该是一个音量的SeekBar。

1、对于SeekBar,需要着重关注的就是其三个回调函数。

public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) {
        if (fromTouch) {
            postSetVolume(progress);
        }
        if (mCallback != null) {
            mCallback.onProgressChanged(seekBar, progress, fromTouch);
        }
}

public void onStartTrackingTouch(SeekBar seekBar) {
}

public void onStopTrackingTouch(SeekBar seekBar) {
        postStartSample();
}

2、对于音量,这个类注册了广播监听,Action为:

AudioManager.VOLUME_CHANGED_ACTION
AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION
NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED
AudioManager.STREAM_DEVICES_CHANGED_ACTION

3、同时注册了一个关于StreamType音量变化的监听

 mVolumeObserver = new Observer(mHandler);
 mContext.getContentResolver().registerContentObserver(
     System.getUriFor(System.VOLUME_SETTINGS[mStreamType]),
     false, mVolumeObserver);

知道了以上三个信息,现在来分析,当我们滑动SeekBar的时候会发生什么情况。

从onProgressChanged回调可以知道,滑动SeekBar的过程中会不断地去设置音量。

从onStopTrackingTouch回调可以知道,滑动完成之后,会播放sample。

注:这里可以看到,如果我们第一次滑动完毕,其实sample正在播放,我们在播放过程中滑动SeekBar的滑,此时sample播放的声音会随着我们的滑动而改变。

因为我们注册了AudioManager.VOLUME_CHANGED_ACTION,所以在滑动的过程中,由于我们设置了音量,那么我们将会收到这个广播,于是收到该广播我们又会去更新SeekBar。

对于两个成员变量的作用:

mAffectedByRingerMode = mAudioManager.isStreamAffectedByRingerMode(mStreamType);
mNotificationOrRing = isNotificationOrRing(mStreamType);

mAffectedByRingerMode的作用比较明显,就是判断StreamType是否受响铃模式影响。

mNotificationOrRing从变量名可以看出,是判断Stream是否属于Notification或者Ring其中一种的一个标识位。

这个变量的具体作用在于,当我们收到音量变化的广播的时候,我们需要去判断,发生音量变化的StreamType和我们这个类所控制的StreamType是否一样,如果一样,我们才会去更新SeekBar。也就是说,当Ring和Notification的音量会同时变化,当我们调整Ring的音量的时候,Notificaion的音量也会发生改变,要使得Notification和Ring互相不影响,只需要把streamMatch = streamType == mStreamType就可以了,也就是说,当跟我当前表示的StreamType发生音量变化的时候,我才去更新SeekBar.

private void updateVolumeSlider(int streamType, int streamValue) {
            final boolean streamMatch = mNotificationOrRing ? isNotificationOrRing(streamType)
                    : (streamType == mStreamType);
            if (mSeekBar != null && streamMatch && streamValue != -1) {
                final boolean muted = mAudioManager.isStreamMute(mStreamType)
                        || streamValue == 0;
                mUiHandler.postUpdateSlider(streamValue, mLastAudibleStreamVolume, muted);
            }
}

相关类图:我们知道SeekBarVolumizer是一个可以播放Uri并且控制音量的SeekBar。而VolumeSeekBarPrefernce则是一个可以播放Uri并且控制音量的SeekBarPreference。所以这里VolumeSeekBarPreference继承SeekBarPreference代表一种特别的SeekBarPreference,而其“可以播放Uri并且控制音量”这个功能则通过 "has-a" SeekBarVolumizer来实现。



Note for myself:对于Notification图标的修改,需要RingVolumePreferenceController.java中的updatePreferenceIcon(),同时需要修改SeekBarVolumizer.java中收到RingerMode变化广播的时候,更新图标。

else if (AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION.equals(action)) {
                if (mNotificationOrRing) {
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值