Android系统铃声设置的流程
Sound & notification
–> General —> Phone ringtone
Default notification sound
单卡情况下:
直接跳到RingtonePickerActivity这个list列表,进行选择铃声的操作。
双卡情况下:
调到选择sub sim卡的界面,待选择完sim卡,然后载调到RingtonePickerActivity这个list列表,进行选择铃声的操作。
到底是怎么跳转到RingtonePickerActvity界面的,因为在EditProfile界面并未看到任何显示或者隐式打开RingtonePickerActivity的入口。
以ringtone的设置为例:
private void initRingtone(PreferenceScreen parent) {
//这里看到,找控件,也就是Phone ringtone这个preference,可以看出其实际为 DefaultRingtonePreference
mVoiceRingtone = (DefaultRingtonePreference) parent.findPreference(KEY_RINGTONE);
mVideoRingtone = (DefaultRingtonePreference) parent.findPreference(KEY_VIDEO_RINGTONE);
mSipRingtone = (DefaultRingtonePreference) parent.findPreference(KEY_SIP_RINGTONE);
}
在EditProfile中找不到跳转的入口,那就进入DefaultRingtonePreference去看下有没有,但是仍然找不到,只能找到onPrepareRingtonePickerIntent方法,看着像,但是并未有哪里执行了startActvity啊。
public class DefaultRingtonePreference extends RingtonePreference {。。。。}
那可以看到DefaultRingtonePreference 的父类为RingtonePreference ,所以可以看下,是不是在父类中有相应的解释,追踪到
frameworks/base/core/java/android/preference/RingtonePreference.java
果然找到了,父类内部实现了onclick事件,并且在其中调用onPrepareRingtonePickerIntent方法,将其中初始化的intent同样作为参数,start出去。现在就一目了然了。
@Override
protected void onClick() {
// Launch the ringtone picker 那就是这里了,隐式得跳转,通过action
Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
onPrepareRingtonePickerIntent(intent);
PreferenceFragment owningFragment = getPreferenceManager().getFragment();
if (owningFragment != null) {
owningFragment.startActivityForResult(intent, mRequestCode);
} else {
getPreferenceManager().getActivity().startActivityForResult(intent, mRequestCode);
}
}
而且可以发现,其是以startActvityForResult的方式来跳转,那么必然有onActivityResult方法。
public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == mRequestCode) {
if (data != null) {
Uri uri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
if (callChangeListener(uri != null ? uri.toString() : "")) {
//这里会调用onSaveRingtone方法
onSaveRingtone(uri);
}
}
return true;
}
return false;
}
正好可以对应到,在ringtonePicker列表中选择完毕铃声后,返回后设置了铃声的动作,这里在其子类DefaultRingtonePreference中完成了重写。
/**
* Called when the ringtone is choosen, set the selected ringtone uri to framework
*
* @param ringtoneUri
* the selected ringtone uri
*/
@Override
protected void onSaveRingtone(Uri ringtoneUri) {
//xxw
int simNum = SubscriptionManager.from(getContext()).getActiveSubscriptionInfoCount();
if(simNum == 0){
Toast.makeText(mContext, mContext.getString(R.string.no_sim_card_tip), 2000).show();
}else {//xxw .
SharedPreferences prefs = this.getContext().getSharedPreferences(
"DefaultRingtonePreference", Context.MODE_PRIVATE);
mSimId = prefs.getLong(PREF_SIM_ID_VALUME, -1);
mProfileManager.setRingtoneUri(mKey, getRingtoneType(), mSimId, ringtoneUri);
Log.d("kiki","onSaveRingtone ringtoneUri="+ringtoneUri.toString());
}//xxw
}