初記 cm-11中,「設置-音量中,調節鬧鐘音量,無聲音預覽播放」bug fix

tags:    時間:2014-05-04 13:21:59
小記 cm-11中,「設置-音量中,調節鬧鐘音量,無聲音預覽播放」bug fix
rt,cm11中,在設置Settings中,調節音樂或通知音量,都有聲音預覽,唯獨調節鬧鐘沒有。

一。我們先來看Settings代碼

SoundSettings.java是聲音設置界面,具體的音量調節界面是RingerVolumePreference.java,但是這個類里沒有針對滑動seekbar做任何播放操作,只有預覽播放的回調protected void onSampleStarting(SeekBarVolumizer volumizer) {。


在RingerVolumePreference.java的onBindDialogView(View view)綁定方法中,
可以看到不同鈴聲seekbar的綁定。
         for (int i = 0; i < SEEKBAR_ID.length; i++) {             SeekBar seekBar = (SeekBar) view.findViewById(SEEKBAR_ID[i]);             mSeekBars[i] = seekBar;             if (SEEKBAR_TYPE[i] == AudioManager.STREAM_MUSIC) {                 mSeekBarVolumizer[i] = new SeekBarVolumizer(getContext(), seekBar,                         SEEKBAR_TYPE[i], getMediaVolumeUri(getContext()));             } else {                 mSeekBarVolumizer[i] = new SeekBarVolumizer(getContext(), seekBar,                         SEEKBAR_TYPE[i]);             }             Uri u = getMediaVolumeUri(getContext());             Log.d("cchen", "uri " + u);         } 


但是注意SeekBarVolumizer這個類,從名字上也能看出是單獨定義的控制項。

經過查找
SeekBarVolumizer是
frameworks/base/core/java/android/preference/VolumePreference.java的內部類。

二。查看framework中的SeekBarVolumizer


SeekBarVolumizer中
initSeekBar的初始化方法
             if (defaultUri == null) {                 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;                 }             }              mRingtone = RingtoneManager.getRingtone(mContext, defaultUri);              if (mRingtone != null) {                 mRingtone.setStreamType(mStreamType);             } 

可以看到鬧鈴的seekbar綁定的是Settings.System.DEFAULT_ALARM_ALERT_URI。
但是在SettingsProvider數據里,system這張表中,經過查詢,只有38|notification_sound|content://media/internal/audio/media/71

卻沒有Settings.System.DEFAULT_ALARM_ALERT_URI的記錄。


三。通過log分析

查到這裡代碼暫時不好查了。
這時我們來看下滑動鬧鈴seekbar的adb log

 D/MediaPlayer( 3081): Couldn't open file on client side, trying server side E/MediaPlayerService( 2551): Couldn't open fd for content://settings/system/alarm_alert E/MediaPlayer( 3081): Unable to create media player  


可以看待播放器的日誌,是setUri時候報了錯誤。
再往下,可以查到MediaScanner.java中,獲取默認鈴聲的代碼

     private void setDefaultRingtoneFileNames() {         mDefaultRingtoneFilename = SystemProperties.get(DEFAULT_RINGTONE_PROPERTY_PREFIX                 + Settings.System.RINGTONE);         mDefaultNotificationFilename = SystemProperties.get(DEFAULT_RINGTONE_PROPERTY_PREFIX                 + Settings.System.NOTIFICATION_SOUND);         mDefaultAlarmAlertFilename = SystemProperties.get(DEFAULT_RINGTONE_PROPERTY_PREFIX                 + Settings.System.ALARM_ALERT);     }  


可以看到是尋找build.prop中的鍵值對 ro.config.alarm_alert
我們通過adb shell getprop | grep alarm
可以看到ro.config.alarm_alert=Alarm_Classic.ogg,有這一欄。
那為什麼SettingsProvider中有notification_sound卻沒有alarm_alert呢?

四。分析build.prop

我們再到設備上 adb shell find | grep Alarm_Classic.ogg,發現設備上根本沒有這個文件。
system/media/audio/alarms下面也確實沒有,那我們已經找到這個問題的root cause了。
即:ro.config.alarm_alert=Alarm_Classic.ogg中的ogg文件不存在。

---------------------------
fix辦法:
 --- a/target/product/core_base.mk +++ b/target/product/core_base.mk @@ -18,7 +18,7 @@    PRODUCT_PROPERTY_OVERRIDES := \      ro.config.notification_sound=OnTheHunt.ogg \ -    ro.config.alarm_alert=Alarm_Classic.ogg +    ro.config.alarm_alert=Alarm_Beep_03.ogg   


完美解決。

推薦閱讀文章

Bookmark the permalink ,來源:互聯網