由于Google 默認設計中來電鈴聲一路和UI啟動一路是分開跑誊爹,通常情形下UI一路的啟動要比響鈴更耗時間睛蛛;所以會存在來電界面起來比鈴聲稍晚的用戶體驗皂甘,尤其是在滅屏時候的來電鲜滩。下面的Workround方法給出了L版本上對于此問題的優(yōu)化方案搅窿。
Telecom將來電響鈴的邏輯屏蔽,InCallPresenter在收到來電消息時廊镜,判斷當前是否是亮屏狀態(tài)牙肝,如果是亮屏狀態(tài),InCall調(diào)用底層的方法進行響鈴.
如果是黑屏嗤朴,在收到來電消息的時候配椭,不做響鈴操作,在進入到InCallActivity(通話界面)的onResume方法中雹姊,調(diào)用響鈴的方法股缸。
在InCallPresenter.java中,進行以下修改:
a.增加以下引用
import android.os.PowerManager;// Add For synchronize ringer and UI
b. 增加成員
private PowerManager pm = null;
private boolean isInCallActivityStop = false;
c. 增加方法 playIncomingCallRingtone(android.telecom.Call call)
/**
* Add For synchronize ringer and UI
*
* @param call
*/
public void playIncomingCallRingtone(android.telecom.Call call){
Log.i(this, "playIncomingCallRingtone()");
TelecomAdapter.getInstance().playIncomingCallRingtone(call);
}
d.增加getPowerManager方法
public PowerManager getPowerManager(){
if(pm == null){
pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
}
return pm;
}
e. 修改onIncomingCall(Call call)方法
public void onIncomingCall(Call call) {
Log.i(this, " onIncomingCall set isInCallActivityStop = false ");
isInCallActivityStop = false;
InCallState newState = startOrFinishUi(InCallState.INCOMING);
InCallState oldState = mInCallState
Log.i(this, "Phone switching state: " + oldState + " -> " + newState);
mInCallState = newState;
//begin Add For synchronize ringer and UI
Log.d(this, "onIncomingCall the screen is on ? ----- " + getPowerManager().isScreenOn());
if(getPowerManager().isScreenOn()){
Log.d(this, "onIncomingCall the screen is on!");
playIncomingCallRingtone(call.getTelecommCall());
}
//end Add For synchronize ringer and UI
for (IncomingCallListener listener : mIncomingCallListeners) {
listener.onIncomingCall(oldState, mInCallState, call);
}
}
f.
public void setInCallActivityStop (boolean isStop ){
Log.d(this, " setInCallActivityStop : " + isStop);
isInCallActivityStop = isStop;
}
g.
public boolean getInCallActivityStop ( ){
Log.d(this, " getInCallActivityStop: " + isInCallActivityStop);
return: isInCallActivityStop;
}
2.TelecomAdapter.java中增加方法playIncomingCallRingtone(android.telecom.Call call)
//Add For synchronize ringer and UI
void playIncomingCallRingtone(android.telecom.Call call) {
if (mPhone != null) {
Log.d(this, "playIncomingCallRingtone() Call:" + call);
if (call != null) {
call.playIncomingCallRingtone();
} else {
Log.e(this, "error playIncomingCallRingtone, call is null");
}
} else {
Log.e(this, "error playIncomingCallRingtone, mPhone is null");
}
}
3.Call.java(frameworks\base\telecomm\java\android\telecom)增加方法playIncomingCallRingtone():
//Add For synchronize ringer and UI
public void playIncomingCallRingtone() {
mInCallAdapter.playIncomingCallRingtone();
}
4.InCallAdapter.java(frameworks\base\telecomm\java\android\telecom)增加方法playIncomingCallRingtone():
/**
* Add For synchronize ringer and UI
*
*/
public void playIncomingCallRingtone() {
try {
mAdapter.playIncomingCallRingtone();
} catch (RemoteException e) {
}
}
5.IInCallAdapter.aidl(frameworks\base\telecomm\java\com\android\internal\telecom)文件中增加接口:void playIncomingCallRingtone();
6.InCallAdapter.java(packages\services\telecomm\src\com\android\server\telecom)
1> 增加靜態(tài)成員:
//Add For synchronize ringer and UI
private static final int MSG_PLAY_INCOMING_RINGTONE = 1008;
2> InCallAdapterHandler的handleMessage()方法的最后添加:
case MSG_PLAY_INCOMING_RINGTONE:
mCallsManager.playIncomingCallRingtone();
break;
3> 添加成員方法:
@Override
public void playIncomingCallRingtone() {
mHandler.obtainMessage(MSG_PLAY_INCOMING_RINGTONE).sendToTarget();
}
7.CallsManager.java 中增加方法playIncomingCallRingtone()
//Add For synchronize ringer and UI
public void playIncomingCallRingtone(){
Log.v(this, "playIncomingCallRingtone()");
// check whether exist RINGING call.
for(Call call : mCalls) {
if(call.getState() == CallState.RINGING) {
mRinger.startRingingOrCallWaiting();//修改該方法為Public
break;
}
}
}
8.Ringer.java(packages\services\telecomm\src\com\android\server\telecom)中修改onForegroundCallChanged()方法如下:
@Override
public void onForegroundCallChanged(Call oldForegroundCall, Call newForegroundCall) {
if (mRingingCalls.contains(oldForegroundCall) ||
mRingingCalls.contains(newForegroundCall)) {
// Add For synchronize ringer and UI
Log.v(this, "synchronize onForegroundCallChanged() ");
//End
//Original code
//updateRinging();
}
}
9.InCallactivity.java
a. 增加以下引用
import android.os.PowerManager;// Add For synchronize ringer and UI
b.
protected void onCreate(Bundle icicle) {
Log.d(this, "onCreate()... this = " + this);
super.onCreate(icicle);
......
//begin Add For synchronize ringer and UI
Log.d(this, "AAAscreen is on ? ----- " +InCallPresenter.getInstance().getPowerManager().isScreenOn());
//end Add For synchronize ringer and UI
Log.d(this, "onCreate(): exit");
}
c.
protected void onResume() {
......
InCallPresenter.getInstance().lightOnScreenForSmartBook();
//begin Add For synchronize ringer and UI
final PowerManager pm = InCallPresenter.getInstance().getPowerManager();
final Call call = CallList.getInstance().getIncomingCall();
Log.d(this, "onResum:call: " + call);
if(call != null){
boolean isInCallActivityStop = InCallPresenter.getInstance().getInCallActivityStop();
Log.d(this, "BBBscreen is on ? ----- " + pm.isScreenOn());
Log.d(this, "BBBscreen call.getState(): " + call.getState() + " isInCallActivityStop: " + isInCallActivityStop);
if((call.getState() == Call.State.CALL_WAITING)
||((call.getState() == Call.State.INCOMING)&&(pm.isScreenOn() && isInCallActivityStop))){
InCallPresenter.getInstance().playIncomingCallRingtone(call.getTelecommCall());
InCallPresenter.getInstance().setInCallActivityStop(false);
}
}
//end Add For synchronize ringer and UI
}
d.
protected void onStop() {
Log.d(this, "onStop()...");
……………
super.onStop();
InCallPresenter.getInstance().setInCallActivityStop(true);
}