Android
从6.0开始,允许用户设置默认短信和默认电话应用,使用相应的 Intent
便可以设置默认应用
从 API
21 开始,谷歌添加了 TelecomManager
用于提供对电话通讯状态的监听
API
23 之后,又开放了 Telecom framework,这个框架允许第三方应用开发者编写应用来替换系统默认电话应用,而其中大部分接口就添加在 android.telecom
包下
Telecom framework 其实提供了两个方面的 API
,一个是 ConnectionService 用于实现通讯(比如通过电信服务商提供的电话连接服务),另一个就是我们这次的需要用到的 InCallService,它主要负责提供 UI
来管理电话
一般系统自带的电话应用同样也是实现这套 API
来提供电话通信的交互界面
API
21 相关代码代码位置:/frameworks/base/telecomm/java/android/telecom/TelecomManager.java
代码概览:TelecomManager.java
可看到这个时候,虽然有代码状态的监听接口,但其属性值设置为 @hide
这就意味着,要么系统软件可以使用,要么就使用反射调用,一般用于
API
23 相关代码代码位置:/frameworks/base/telecomm/java/android/telecom/
代码概览:Telecom Framework
这边的接口,主要关注一个基类 InCallService.java 这个类就是第三方电话应用需要去继承实现的类
1. 继承 `InCallService` 并实现需要用到的方法
2. 添加一个 Activity 用于提供用户界面
Service
相关InCallService
中有两个方法,onCallAdded
和 onCallRemoved
,分别代表电话进来与断开时会被调用,一般我们会在 onCallAdded
中注册电话状态监听,并在 onCallRemoved
中解除监听
public class PhoneCallService extends InCallService {
private Call.Callback callback = new Call.Callback() {
@Override
public void onStateChanged(Call call, int state) {
super.onStateChanged(call, state);
switch (state) {
case Call.STATE_ACTIVE: {
break; // 通话中
}
case Call.STATE_DISCONNECTED: {
break; // 通话结束
}
}
}
};
@Override
public void onCallAdded(Call call) {
super.onCallAdded(call);
call.registerCallback(callback);
}
@Override
public void onCallRemoved(Call call) {
super.onCallRemoved(call);
call.unregisterCallback(callback);
}
}
此 Service
的注册,需要添加相应的 data
和 filter
<service
android:name=".PhoneCallService"
android:permission="android.permission.BIND_INCALL_SERVICE">
<meta-data
android:name="android.telecom.IN_CALL_SERVICE_UI"
android:value="true" />
<intent-filter>
<action android:name="android.telecom.InCallService" />
intent-filter>
service>
Activity
相关在做默认电话相关界面的时候,注册的时候也必须有相应的添加相对应
<intent-filter>
<action android:name="android.intent.action.DIAL" />
<data android:scheme="tel" />
intent-filter>
<intent-filter>
<action android:name="android.intent.action.DIAL" />
intent-filter>
和默认短信一样,默认电话也有设为默认的 Action
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Intent intent = new Intent(TelecomManager.ACTION_CHANGE_DEFAULT_DIALER);
intent.putExtra(TelecomManager.EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME,
getPackageName());
startActivity(intent);
}
Permission.READ_PHONE_STATE
Permission.READ_CONTACTS
Permission.WRITE_CONTACTS
Permission.READ_CALL_LOG
Permission.WRITE_CALL_LOG
Permission.PROCESS_OUTGOING_CALLS
Permission.CALL_PHONE
Permission.GET_ACCOUNTS
注意:默认电话的读写权限有些手机会一同授予,有些则不会
public static boolean isDefaultPhoneCallApp(Context context) {
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
TelecomManager manger = (TelecomManager) context.getSystemService(TELECOM_SERVICE);
if (manger != null) {
String name = manger.getDefaultDialerPackage();
return name.equals(context.getPackageName());
}
}
return false;
}