迁移自本人cnblog旧文:
近期发现不少关于来电铃声出现无声问题,分析这个问题,需要先了解来电的流程,本篇先对该流程做个大概的总结。
一、播放流程准备工作
来电的时候,通过telecom那边的Ringer类启动播放:
packages/services/Telecomm/src/com/android/server/telecom/Ringer.java
mRingtonePlayer.play(mRingtoneFactory, foregroundCall);
而mRingtonePlayer通过AsyncRingtonePlayer构造的:
packages/services/Telecomm/src/com/android/server/telecom/AsyncRingtonePlayer.java
/** Plays the ringtone. */ public void play(RingtoneFactory factory, Call incomingCall) { Log.d(this, "Posting play."); SomeArgs args = SomeArgs.obtain(); args.arg1 = factory; args.arg2 = incomingCall; postMessage(EVENT_PLAY, true /* shouldCreateHandler */, args); }
这里通过消息传递在子线程中调用了handlePlaye方法:
@Override public void handleMessage(Message msg) { switch(msg.what) { case EVENT_PLAY: handlePlay((SomeArgs) msg.obj); break; case EVENT_REPEAT: handleRepeat(); break; case EVENT_STOP: handleStop(); break; } }
handlePlay方法中通过调用factory.getRingtone初始化了铃声播放的设置:
if (mRingtone == null) { mRingtone = factory.getRingtone(incomingCall); if (mRingtone == null) { Uri ringtoneUri = incomingCall.getRingtone(); String ringtoneUriString = (ringtoneUri == null) ? "null" : ringtoneUri.toSafeString(); Log.addEvent(null, LogUtils.Events.ERROR_LOG, "Failed to get ringtone from " + "factory. Skipping ringing. Uri was: " + ringtoneUriString); return; } }
在factory.getRingtone中,初始化了默认的uri以及stream类型:
packages/services/Telecomm/src/com/android/server/telecom/RingtoneFactory.java
public Ringtone getRingtone(Call incomingCall) { // Use the default ringtone of the work profile if the contact is a work profile contact. Context userContext = isWorkContact(incomingCall