通话保持常亮(不息屏)
在网上搜索的 Android保持屏幕常亮的方法,一种是 getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
另一种是通过 wakeLock, 经过测试发现在 InCallActivity.java 中 onCreate()使用第一种并不生效,看网上说的要放到 setContentView()之前
然而试了也没生效,放到自己写的测试demo中,继承自 AppCompatActivity, setFlags需要传递两个参数,如下的方法生效了
getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
修改 InCallActivity 中的方法,编译时发现报错了,参数不合法,看到 InCallActivity 继承自 FragmentActivity, 不知道跟这个有没有关系,
于是采用第二种方法。
修改位置
alps\vendor\mediatek\proprietary\packages\apps\Dialer\java\com\android\incallui\InCallActivity.java
private PowerManager.WakeLock mWakeLock; @Override protected void onCreate(Bundle icicle) { super.onCreate(icicle); //getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); //add keep inCallActivity keepScreenOn PowerManager powerManager= (PowerManager) getSystemService(Context.POWER_SERVICE); mWakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, "keep_screen_on_tag"); } @Override protected void onResume() { super.onResume(); mWakeLock.acquire(); } @Override protected void onDestroy() { super.onDestroy(); mWakeLock.release(); }
android.permission.WAKE_LOCK 权限 AndroidManifest 文件中已经存在,就不用添加了
Android系统中的WakeLoke类型有以下几种:
PARTIAL_WAKE_LOCK:保持COU正常运转,屏幕和键盘灯有可能会关闭。
SCREEN_DIM_WAKE_LOCK:保存CPU运转,允许保存屏幕显示但有可能变暗,允许关闭键盘灯。
FULL_WAKE_LOCK:保持CPU运转,保持屏幕高亮显示,键盘灯也保持亮度。
ACQUIRE_CAUSES_WAKEUP:强制屏幕亮起,这种锁主要用于一些必须通知用的操作。
ON_AFTER_RELEASE:当锁被释放时,保持屏幕亮起一段时间。
接听方式上下滑动,改为按钮接听
安卓源码中提供了两种接听方式,一种为上下滑动,另一种为按钮接听。有点像苹果手机接听一样,有时候是滑动接听,
有时候是两个按钮,一个绿色的接听,一个红色的挂断。效果图如下
滑动接听方式
按钮接听方式
修改位置
vendor\mediatek\proprietary\packages\apps\Dialer\java\com\android\incallui\answer\impl\answermethod\AnswerMethodFactory.java
@NonNull public static AnswerMethod createAnswerMethod(@NonNull Activity activity) { if (needTwoButton(activity)) { return new TwoButtonMethod(); } else { //return new FlingUpDownMethod(); return new TwoButtonMethod(); } }
TwoButtonMethod.java 对应按钮接听方式
FlingUpDownMethod.java 对应滑动接听方式
简单说下逻辑,接听界面对应的类为 AnswerFragment,布局文件为 fragment_incoming_call,
接听部分布局id为 answer_method_container,通过加载 Fragment 进行替换
AnswerMethodFactory.createAnswerMethod(getActivity()),此方法去实例化按钮接听方式和滑动接听方式
接通时发送广播通知app(通话界面开始计时)
为啥需要这么干,通过监听状态改变也能判断电话接通,但是没有系统优先级高,这就需要我们来改源码了
**8.1 修改位置 **
vendor\mediatek\proprietary\packages\apps\Dialer\java\com\android\incallui\contactgrid\ContactGridManager.java
public void setCallState(PrimaryCallState primaryCallState) { this.primaryCallState = primaryCallState; if (DialerCall.State.ACTIVE == primaryCallState.state) { Log.e("InCallFragment", "sendBrocast Call.State.ACTIVE =" + primaryCallState.state); //cczheng add , send broadcast when is active Intent broIntent = new Intent(); broIntent.setAction("com.call.state.active"); context.sendBroadcast(broIntent); //cczheng add , send broadcast when is active } updatePrimaryNameAndPhoto(); updateBottomRow(); updateTopRow(); }
6.0 修改位置
packages\apps\InCallUI\src\com\android\incallui\CallCardFragment.java
@Override public void setCallState( int state, int videoState, int sessionModificationState, DisconnectCause disconnectCause, String connectionLabel, Drawable callStateIcon, String gatewayNumber, boolean isWifi, boolean isConference) { boolean isGatewayCall = !TextUtils.isEmpty(gatewayNumber); CallStateLabel callStateLabel = getCallStateLabelFromState(state, videoState, sessionModificationState, disconnectCause, connectionLabel, isGatewayCall, isWifi, isConference); .... if (Call.State.ACTIVE == state) { Log.d(this, "sendBrocast Call.State.ACTIVE " + state); //cczheng add , send broadcast when is active Intent broIntent=new Intent(); broIntent.setAction("com.call.state.active"); getActivity().sendBroadcast(broIntent); if(CallUtils.isVideoCall(videoState)){ //videoCall final View buttonsView=getView().findViewById(R.id.buttons_container); buttonsView.setBackgroundColor(Color.argb(0x99,0xff,0xff,0xff)); videoFragment.setBGColor(Color.argb(0xff,0x00,0x00,0x00)); } } }
简单说下,通过打印日志可以看到8.1的接通状态值变化为
CONNECTING(13)->DIALING(6)->ACTIVE(3)->DISCONNECTING(9)->DISCONNECTED(10)->IDLE(2)
alps\vendor\mediatek\proprietary\packages\apps\Dialer\java\com\android\incallui\call\DialerCall.java
public static class State { public static final int INVALID = 0; public static final int NEW = 1; /* The call is new. */ public static final int IDLE = 2; /* The call is idle. Nothing active */ public static final int ACTIVE = 3; /* There is an active call */ public static final int INCOMING = 4; /* A normal incoming phone call */ public static final int CALL_WAITING = 5; /* Incoming call while another is active */ public static final int DIALING = 6; /* An outgoing call during dial phase */ public static final int REDIALING = 7; /* Subsequent dialing attempt after a failure */ public static final int ONHOLD = 8; /* An active phone call placed on hold */ public static final int DISCONNECTING = 9; /* A call is being ended. */ public static final int DISCONNECTED = 10; /* State after a call disconnects */ public static final int CONFERENCED = 11; /* DialerCall part of a conference call */ public static final int SELECT_PHONE_ACCOUNT = 12; /* Waiting for account selection */ public static final int CONNECTING = 13; /* Waiting for Telecom broadcast to finish */ public static final int BLOCKED = 14; /* The number was found on the block list */ public static final int PULLING = 15; /* An external call being pulled to the device */ /// M: [Modification for finishing Transparent InCall Screen if necessary] /// such as:ALPS02302461,occur JE when MT call arrive at some case. @{ public static final int WAIT_ACCOUNT_RESPONSE = 100; }