一、开发步骤
1.1、注册 VoIP 通话回调事件
使用方法详见 2.1 订阅voipCallUiEvent事件。
1.2、上报来/去电事件
应用内部建立通话连接之后,需要向VoIP Service Kit上报去电,并携带通话信息,详见接口文档2.15 VoipCall通话属性。
//来电
CallKitManager.getInstance().reportIncomingCall(call);
//去电
CallKitManager.getInstance().reportOutgoingCall(call);接口使用方法详见:2.3上报来电消息、2.4 上报去电消息。
1.3、上报通话状态
当对端用户接听后,向 VoIP Service Kit 上报通话状态。
CallKitManager.getInstance().updateCallState(callId, CallKitConstants.VOIP_CALL_STATE_ACTIVE);接口使用方法详见:2.5 上报应用内通话状态变化。
1.4、上报静音或解除静音事件
用户在通话过程中可以选择静音通话和解除静音,当用户点击通知横幅中的静音/解除静音按钮,应用会收到静音回调 mute(String callId, boolean mute),在应用内部完成静音/解除静音后,需调用接口上报静音状态。
CallKitManager.getInstance().reportCallMuteEvent(callId, mute); // mute=true 静音,mute=false 解除静音接口使用方法详见:2.8 上报应用通话中的静音事件。
1.5、上报通话中的音频事件
在通话过程中,用户可以根据实际需要选择不同的音频通路,包括手机听筒、免提扬声器、蓝牙设备和有线耳机等。当通话的音频通路被切换,VoIP 应用会接收到切换通话音频通路回调 changeAudioRoute,应用在完成通话音频通路切换后,需通过调用接口上报当前通知的音频通路。
CallKitManager.getInstance().reportCallAudioRouteEvent(callId, currentRoute, supportRoute);接口使用方法详见:2.7 上报通话中的音频事件。
1.6、上报应用内通话类型变化
通话类型分视频通话和语音通话两种,对于视频来电语音接听、通话中视频降语音或者语音升视频,需要应用调用接口上报通话类型变化。
CallKitManager.getInstance().updateCallType(callId, CallKitConstants.VOIP_CALL_TYPE_VOICE);接口使用方法详见:2.6 上报应用内通话类型变化。
1.7、上报通话结束
用户在通知上点击挂断按钮,应用会收到挂断电话回调 disconnectCall,在应用内处理完成挂断后,需立即通过调用接口上报通话结束状态。
CallKitManager.getInstance().updateCallState(callId, CallKitConstants.VOIP_CALL_STATE_DISCONNECTED);接口使用方法详见:2.5 上报应用内通话状态变化。
1.8、取消注册
通话结束后取消订阅。
CallKitManager.getInstance().off();接口使用方法详见:2.2 取消订阅voipCallUiEvent事件。
1.9、上报通话异常
当通话出现异常时,应用需通过接口上报通话失败的原因。
CallKitManager.getInstance().reportCallError(callId, errorCode, errorMessage);接口使用方法详见:2.9 通知来电消息建立失败。
二、VoIP Service Kit SDK API
2.1、订阅voipCallUiEvent事件
要求有通话时(通话由APP自行管理)再进行订阅
int on(Application context)
| 接口名称 | on(Application context) | ||
| 接口说明 | 绑定voip service服务 | ||
| 参数 | 参数名 | 参数类型 | 参数含义 |
| context | Application | 应用程序上下文 | |
| 返回值 | 返回类型 | 返回值含义 | |
| int | 参考ErrorReason | ||
使用方法示例
CallKitManager.getInstance().on(application);int register(CallKitCallBack callback)
| 接口名称 | register(CallKitCallBack callback) | ||
| 接口说明 | 订阅voipCallUiEvent事件。使用Callback的方式获取订阅voipCallUiEvent事件的结果 与on配合使用,返回成功后,再进行注册 | ||
| 参数 | 参数名 | 参数类型 | 参数含义 |
| callback | CallKitCallBack | 回调函数,返回通话事件详细信息对象 | |
| 返回值 | 返回类型 | 返回值含义 | |
| int | 参考ErrorReason | ||
CallKitCallBack接口方法列表:
该回调即用户对于VoipService通知显示的点击事件回调。
例:用户点击通知上的接听按钮,即回调answerCall。
回调中,APP自行实现逻辑
| 接口方法名称 | 说明 |
| void answerCall(String callId) | 用户接听电话回调 |
| void rejectCall(String callId) | 用户拒接电话回调 |
| void disconnectCall(String callId) | 用户挂断电话回调 |
| void mute(String callId, boolean mute) | 用户设置静音回调 |
| void changeAudioRoute(String callId, int route) | 用户改变接听方式回调 |
| void onCallKitEvent(int event, Bundle extras) | 额外的通话事件 |
| void answerCallWithType(String callId, int callType) | 选择calltype接通(视频选择语音) |
| void changeCallType(String callId, int callType) | 切换calltype |
使用方法示例(建议回调方法中加入必要log)
// callback
CallKitCallBack mCallKitCallBack = new CallKitCallBack() {
@Override
public void answerCall(String callId) {
CallKitLog.i(TAG, "answerCall callId " + callId);
CallKitManager.getInstance().updateCallState(callId, CallKitConstants.VOIP_CALL_STATE_ACTIVE);
}
@Override
public void answerCallWithType(String callId, int callType) {
CallKitLog.i(TAG, "answerCallWithType callId " + callId + ", type " + callType);
}
@Override
public void rejectCall(String callId) {
CallKitLog.i(TAG, "rejectCall callId " + callId);
CallKitManager.getInstance().updateCallState(callId, CallKitConstants.VOIP_CALL_STATE_DISCONNECTED);
}
@Override
public void changeCallType(String callId, int callType) {
CallKitLog.i(TAG, "changeCallType callId " + callId + ", type " + callType);
}
@Override
public void disconnectCall(String callId) {
CallKitLog.i(TAG, "disconnectCall callId " + callId);
CallKitManager.getInstance().updateCallState(callId, CallKitConstants.VOIP_CALL_STATE_DISCONNECTED);
}
@Override
public void mute(String callId, boolean mute) {
CallKitLog.i(TAG, "mute callId " + callId + ", mute " + mute);
CallKitManager.getInstance().reportCallMuteEvent(callId, mute);
}
@Override
public void changeAudioRoute(String callId, int route) {
CallKitLog.i(TAG, "changeAudioRoute callId " + callId + ", route " + route);
int supportRoute = CallKitConstants.ROUTE_EARPIECE | CallKitConstants.ROUTE_BLUETOOTH | CallKitConstants.ROUTE_WIRED_HEADSET | CallKitConstants.ROUTE_SPEAKER;
CallKitManager.getInstance().reportCallAudioRouteEvent(callId, route, supportRoute);
}
@Override
public void onCallKitEvent(int event, Bundle extras) {
CallKitLog.i(TAG,"onCallKitEvent: " + event + " , extras " + extras);
}
};
//订阅绑定,注册
int workable = CallKitManager.getInstance().on(context);
if (workable == CallKitConstants.ERROR_NONE) {
CallKitManager.getInstance().register(mCallKitCallBack);
}2.2、取消订阅voipCallUiEvent事件
APP通话结束后,开发者需要立刻取消订阅。
int off()
| 接口名称 | off() | ||
| 接口说明 | 取消订阅voipCallUiEvent事件。使用Callback的方式获取取消订阅voipCallUiEvent事件的结果 | ||
| 参数 | 参数名 | 参数类型 | 参数含义 |
| 无 | 无 | 无 | |
| 返回值 | 返回类型 | 返回值含义 | |
| int | 参考ErrorReason | ||
使用方法示例
CallKitManager.getInstance().off();2.3、上报来电消息
int reportIncomingCall(VoipCall VoipCall)
| 接口名称 | reportIncomingCall(VoipCall voipCall) | ||
| 接口说明 | 通知来电消息,如果应用来电消息建立失败,需调用reportCallError通知来电建立失败。需设置通话详细信息,见VoipCall | ||
| 参数 | 参数名 | 参数类型 | 参数含义 |
| voipCall | VoipCall | 应用内通话详细信息如用户头像、用户昵称、通话唯一标识等,详情请参见VoipCall | |
| 返回值 | 返回类型 | 返回值含义 | |
| int | 参考ErrorReason | ||
使用方法示例
VoipCall call = new VoipCall();
call.setCallId("xxx");
call.setMsgId("xxx");
call.setUserName("xxx");
call.setUserProfile(imageBytes); //用户头像,byte[]类型
call.setPackageName(getPackageName());
call.setActivityName(this.getClass().getName());
call.setVoipCallType(CallKitConstants.VOIP_CALL_TYPE_VOICE);
call.setVoipCallState(CallKitConstants.VOIP_CALL_STATE_RINGING);
call.setDirection(CallKitConstants.DIRECTION_INCOMING);
// 上报来电事件
CallKitManager.getInstance().reportIncomingCall(call);2.4、上报去电消息
int reportOutgoingCall (VoipCall voipCall)
| 接口名称 | reportOutgoingCall (VoipCall voipCall) | ||
| 接口说明 | 应用上报去电。需设置通话详细信息,见VoipCall | ||
| 参数 | 参数名 | 参数类型 | 参数含义 |
| voipCall | VoipCall | 应用内通话详细信息如用户头像、用户昵称、通话唯一标识等,详情请参见VoipCall | |
| 返回值 | 返回类型 | 返回值含义 | |
| int | 参考ErrorReason | ||
使用方法示例
VoipCall call = new VoipCall();
call.setCallId("xxx");
call.setMsgId("xxx");
call.setUserName("xxx");
call.setUserProfile(imageBytes); //用户头像,byte[]类型
call.setPackageName(getPackageName());
call.setActivityName(this.getClass().getName());
call.setVoipCallType(CallKitConstants.VOIP_CALL_TYPE_VOICE);
call.setVoipCallState(CallKitConstants.VOIP_CALL_STATE_RINGING);
call.setDirection(CallKitConstants.DIRECTION_INCOMING);
// 上报去电事件
CallKitManager.getInstance().reportOutgoingCall(call);2.5、上报应用内通话状态变化
void updateCallState (String callId, int callState)
| 接口名称 | updateCallState (String callId, int callState) | ||
| 接口说明 | 应用上报通话状态变化,如接通、挂断等 | ||
| 参数 | 参数名 | 参数类型 | 参数含义 |
| callId | String | 通话唯一标识 | |
| callState | int | 通话状态,参考2.11 VoipCallState | |
| 返回值 | 返回类型 | 返回值含义 | |
| void | 无返回 | ||
使用方法示例
String callId = "xxx";
CallKitManager.getInstance().updateCallState(callId, CallKitConstants.VOIP_CALL_STATE_ACTIVE);2.6、上报应用内通话类型变化
void updateCallType(String callId, int callType)
| 接口名称 | updateCallType(String callId, int callType) | ||
| 接口说明 | 通知应用内通话类型变化 对于视频来电语音接听、通话中视频降语音或者语音升视频,需要调用该接口,并传入正确的callType | ||
| 参数 | 参数名 | 参数类型 | 参数含义 |
| callId | String | 通话唯一标识 | |
| callType | int | 通话类型,参考VoipCallType | |
| 返回值 | 返回类型 | 返回值含义 | |
| void | 无返回 | ||
使用方法示例
String callId = "xxx";
CallKitManager.getInstance().updateCallType(callId, CallKitConstants.VOIP_CALL_TYPE_VOICE);2.7、上报通话中的音频事件
void reportCallAudioRouteEvent(String callId, int currentRoute, int supportRoute)
| 接口名称 | reportCallAudioRouteEvent(String callId, int currentRoute, int supportRoute) | ||
| 接口说明 | 应用上报通话中音频事件 | ||
| 参数 | 参数名 | 参数类型 | 参数含义 |
| callId | String | 通话唯一标识 | |
| currentRoute | int | 当前Route类型 | |
| supportRoute | int | 支持的Route类型 | |
| 返回值 | 返回类型 | 返回值含义 | |
| void | 无返回 | ||
使用方法示例
String callId = "xxx";
int currentRoute = CallKitConstants.ROUTE_SPEAKER;
int supportRoute = CallKitConstants.ROUTE_EARPIECE | CallKitConstants.ROUTE_BLUETOOTH | CallKitConstants.ROUTE_SPEAKER;
CallKitManager.getInstance().reportCallAudioRouteEvent(callId, currentRoute, supportRoute);2.8、上报应用通话中的静音事件
void reportCallMuteEvent(String callId, boolean mute)
| 接口名称 | reportCallMuteEvent(String callId, boolean mute) | ||
| 接口说明 | 应用上报通话中的静音事件 | ||
| 参数 | 参数名 | 参数类型 | 参数含义 |
| callId | String | 通话唯一标识。 | |
| mute | boolean | 是否禁音状态,true:已静音,false:未静音。 | |
| 返回值 | 返回类型 | 返回值含义 | |
| void | 无返回 | ||
使用方法示例
String callId = "xxx";
CallKitManager.getInstance().reportCallMuteEvent(callId, true);2.9、通知来电消息建立失败
void reportCallError(String callId, int errorCode, String errorMessage)
| 接口名称 | reportCallError(String callId, int errorCode, String errorMessage) | ||
| 接口说明 | 通知来电消息建立失败的原因 | ||
| 参数 | 参数名 | 参数类型 | 参数含义 |
| callId | String | 通话唯一标识 | |
| errorCode | int | 来电消息建立失败原因,参考VoipCallFailureCause | |
| errorMessage | String | 错误信息 | |
| 返回值 | 返回类型 | 返回值含义 | |
| void | 无返回 | ||
使用方法示例
String callId = "10086";
int errorCode = CallKitConstants.INVALID_CALL;
String errorMessage = "无效通话";
CallKitManager.getInstance().reportCallError(callId, errorCode, errorMessage);2.10、通话类型
| 参数名 | 类型 | 说明 |
| 通话类型 | int | 表示通话类型的枚举 |
| 枚举名称 | 值 | 说明 |
| VOIP_CALL_TYPE_VOICE | 0 | 语音通话 |
| VOIP_CALL_TYPE_VIDEO | 1 | 视频通话 |
2.11、通话状态
| 参数名 | 类型 | 说明 |
| VoipCallState | int | 表示通话状态的枚举 |
| 枚举名称 | 值 | 说明 |
| VOIP_CALL_STATE_IDLE | 0 | 空闲 |
| VOIP_CALL_STATE_CONNECTING | 1 | 建立通话连接 |
| VOIP_CALL_STATE_DIALING | 3 | 拨号中 |
| VOIP_CALL_STATE_RINGING | 4 | 来电响铃 |
| VOIP_CALL_STATE_ACTIVE | 5 | 通话中 |
| VOIP_CALL_STATE_HOLDING | 6 | 通话保持 |
| VOIP_CALL_STATE_DISCONNECTED | 7 | 通话结束 |
| VOIP_CALL_STATE_ABORTED | 8 | 通话中断 |
| VOIP_CALL_STATE_DISCONNECTING | 9 | 通话结束 |
| VOIP_CALL_STATE_PULLING | 10 | 通话切回 |
| VOIP_CALL_STATE_ANSWERED | 11 | 接听中 |
2.12、通话事件
| 参数名 | 类型 | 说明 |
| VoipCallUiEvent | int | 表示通话事件的枚举 |
| 枚举名称 | 值 | 说明 |
| VOIP_CALL_EVENT_NONE | 0 | 空闲 |
| VOIP_CALL_EVENT_VOICE_ANSWER | 1 | 通话语音接听事件 |
| VOIP_CALL_EVENT_VIDEO_ANSWER | 2 | 通话视频接听事件 |
| VOIP_CALL_EVENT_REJECT | 3 | 通话拒接事件 |
| VOIP_CALL_EVENT_HANGUP | 4 | 通话挂断事件 |
| VOIP_CALL_EVENT_MUTED | 5 | 静音事件 |
| VOIP_CALL_EVENT_UNMUTED | 6 | 取消静音事件 |
| VOIP_CALL_EVENT_SPEAKER_ON | 7 | 开启扬声器事件 |
| VOIP_CALL_EVENT_SPEAKER_OFF | 8 | 关闭扬声器事件 |
2.13、错误码
| 参数名 | 类型 | 说明 |
| ErrorReason | int | 表示错误码类型的枚举。 |
| 枚举名称 | 值 | 说明 |
| ERROR_NONE | 0 | 无错误出现。 |
| CELLULAR_CALL_EXISTS | 1 | 当前已存在蜂窝通话。 |
| VOIP_CALL_EXISTS | 2 | 当前已存在其他应用内通话。 |
| INVALID_CALL | 3 | 通话无效,比如传入的callId未通过校验等。 |
| USER_ANSWER_CELLULAR_FIRST | 4 | 用户选择接听蜂窝。 |
2.14、消息建立失败原因
| 参数名 | 类型 | 说明 |
| VoipCallFailureCause | int | 表示消息建立失败的枚举 |
| 名称 | 值 | 说明 |
| OTHER | 0 | 其他失败原因 |
| ROUTE_BUSY | 1 | 应用线路忙 |
| CONNECTION_FAILED | 2 | 通话连接建立失败 |
2.15、VoipCall通话属性
| 参数 | 类型 | 只读 | 可选 | 说明 |
| callId | string | 否 | 否 | 应用内通话唯一ID |
| voipCallType | VoipCallType | 否 | 否 | 应用内通话类型 |
| userName | string | 否 | 否 | 应用内通话用户昵称 |
| userProfile | byte[] | 否 | 否 | 用户头像 |
| packageName | string | 否 | 否 | 接听后需加载的应用名 |
| activityName | string | 否 | 否 | 接听后需加载的应用界面名 |
| voipCallState | VoipCallState | 否 | 否 | 应用内通话状态 |
| showBannerForIncomingCall | boolean | 否 | 是 | 支持应用上报来电是否显示横幅通知。 true:应用设置来电显示横幅通知, false:应用设置来电不显示横幅通知。 默认值为true。 |
| isConferenceCall | boolean | 否 | 是 | 通话是否为会议。 true:来电是会议, false:来电不是会议。 默认值为false |
| isVoiceAnswerSupported | boolean | 否 | 是 | 视频来电是否支持语音接听。 true:支持, false:不支持。 默认值为true |
2.16、通话音频事件
| 参数名 | 类型 | 说明 |
| 通话音频通路 | int | 表示通话事件的枚举 |
| 枚举名称 | 值 | 说明 |
| ROUTE_EARPIECE | 1 | 听筒 |
| ROUTE_BLUETOOTH | 2 | 蓝牙 |
| ROUTE_WIRED_HEADSET | 4 | 耳机 |
| ROUTE_SPEAKER | 8 | 免提 |
| ROUTE_STREANG | 16 | 外接设备 |
| ROUTE_WIRED_OR_EARPIECE | 5 | 耳机或听筒 |
| ROUTE_ALL | 31 | 所有通路 |