# 实现一对一通话
本章将介绍如何实现一对一语音通话,一对一语音通话的 API 调用时序见下图:
# 获取设备权限
使用 checkSelfPermission (opens new window) 方法,在开启 Activity 时检查并获取 Android 移动设备的麦克风使用权限。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 获取设备权限
requestPermission();
}
/*动态申请权限*/
private void requestPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED ||
ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED ||
ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO, Manifest.permission.CAMERA}, 1000);
}
}
}
# 初始化
调用 JCMediaDevice.create (opens new window) 和 JCCall.create (opens new window) 以初始化实现一对一通话需要的模块。
// 声明对象
JCMediaDevice mMediaDevice;
JCCall mCall;
// 初始化函数
public boolean initialize(Context context) {
//1. 媒体类
mMediaDevice = JCMediaDevice.create(mClient, new JCMediaDeviceCallback() {
@Override
public void onCameraUpdate() {
}
@Override
public void onAudioOutputTypeChange(int i) {
}
@Override
public void onRenderReceived(JCMediaDeviceVideoCanvas jcMediaDeviceVideoCanvas) {
}
@Override
public void onRenderStart(JCMediaDeviceVideoCanvas jcMediaDeviceVideoCanvas) {
}
});
//2. 通话类
mCall = JCCall.create(mClient, mMediaDevice, new JCCallCallback() {
@Override
public void onCallItemAdd(JCCallItem jcCallItem) {
}
@Override
public void onCallItemRemove(JCCallItem jcCallItem, int i, String s) {
}
@Override
public void onCallItemUpdate(JCCallItem jcCallItem, JCCallItem.ChangeParam changeParam) {
}
@Override
public void onMessageReceive(String s, String s1, JCCallItem jcCallItem) {
}
@Override
public void onMissedCallItem(JCCallItem jcCallItem) {
}
});
}
# 拨打通话
调用 call (opens new window) 发起语音通话,需要填写的参数有:
userID
填写对方的用户ID。video
选择是否为视频通话, true 表示拨打视频通话, false 表示拨打语音通话。callParam
通话参数对象,此参数可为空,详细定义见:JCCallParam (opens new window)
// 发起语音呼叫
mCall.call("userID", isVideo , new JCCall.CallParam("extraParam", "ticket"));
拨打通话后,主叫和被叫均会收到新增通话的回调 onCallItemAdd (opens new window) ,此时通话状态变为 STATE_PENDING (opens new window) 。您可以通过重写 onCallItemAdd (opens new window) 执行逻辑操作。
示例代码
// 1. 发起语音通话
mCall.call("userID", isVideo , new JCCall.CallParam("extraParam", "ticket"));
// 2. 重写回调
@Override
public void onCallItemAdd(JCCallItem item) {
// 业务逻辑
if (item.getDirection() == JCCall.DIRECTION_IN) {
// 如果是被叫
...
}else{
// 如果是主叫
...
}
}
TIP
如果主叫想取消通话,可以直接转到挂断通话部分。调用挂断接口后,通话状态变为 STATE_CANCEL。
# 应答通话
被叫收到 onCallItemAdd (opens new window) 回调,在回调中调用 JCCallItem (opens new window) 中的 getVideo (opens new window) 方法获取
video
属性来判断是视频呼入还是语音呼入,从而做出相应的处理。@Override public void onCallItemAdd(JCCallItem item) { // 1. 如果是语音呼入且在振铃中 if (item.getDirection() == JCCall.DIRECTION_IN && !item.getVideo()) { // 2. 做出相应的处理,如在界面上显示“振铃中” ... } }
调用 answer (opens new window) 接听通话。
mCall.answer(item, false);
通话接听后,通话状态变为 STATE_CONNECTING。
TIP
如果被叫要在此时拒绝通话,请调用挂断通话的接口。这种情况下调用挂断后,通话状态变为 STATE_CANCELED。
# 挂断通话
主叫或者被叫均可以挂断通话。
调用 getActiveCallItem (opens new window) 获取当前活跃的通话对象:
mCall.getActiveCallItem();
调用 term (opens new window) 挂断当前活跃通话:
mCall.term(item, reason, description);
示例代码
// 1. 获取当前活跃通话
JCCallItem item = mCall.getActiveCallItem();
// 2. 挂断当前活跃通话
mCall.term(item, JCCall.REASON_NONE, null);