可视对讲移动端SDK接口说明[Andriod]
1. 概述
1.1 编写目的
本文是可视对讲设备云对讲和呼手机功能SDK接口说明。
1.2 名词解释
名词 | 解释 |
IoT | 物联网 |
2. 介绍
通过集成对接SDK可以使门禁设备快速实现包括门禁机呼叫APP、APP调看门禁机、门禁机呼叫⼿机号等对讲功能。本⽂旨在描述该SDK的集成⽅式及主要业务代码。
限制条件:
编译过程基于Android Studio 4.1.3
推荐使用GradlePlugin版本:4.1.2
推荐使用Gradle版本:6.5
推荐编译SDK版本:30
最小支持SDK版本:21
3. SDK集成方法
3.1 导入所需文件
新建或打开已有工程,拷贝leephone.aar包到app/libs目录下.
在app/build.gradle中添加aar包的引用,如图所示。
...
android {
...
defaultConfig {
...
ndk.abiFilters "armeabi-v7a", "arm64-v8a"
}
}
...
repositories {
flatDir {
dirs 'libs' // aar dir
}
}
...
dependencies {
implementation(name:'leephone', ext:'aar')
...
}
3.2 在AndroidManifest.xml配置
⽀持的最低SDK版本为5.0:
<uses-sdk android:minSdkVersion="21" />
添加必要权限:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
3.3 代码混淆配置
如果有做代码混淆,请确保以下类不加入混淆
-keep class com.evideo.voip.** { *; }
-keep class com.lee.phone.** { *; }
4. 类及接口列表
4.1 类说明
类名 | 说明 |
EVVoipManager | 负责登录SIP |
EVVoipAccount | SIP会话 |
EVVoipCall | 负责SIP通话 |
EVVideoView | 负责视频显示 |
EVVoipCallParams | 通话参数 |
4.2 接口说明
4.2.1流程关键接口
名称 | 类名 | 方法名 |
初始化 | EVVoipManager | init(Context context, EVVoipManager.OnInitCallback callback) |
反初始化 | EVVoipManager | deInit(Context context) |
登录SIP服务器 | EVVoipManager | EVVoipAccount login(String sipnum, String password, String displayName, String domain, int port) |
账号状态监听 | EVVoipAccount | setAccountStateCallback(EVVoipAccount.AccountStateCallbackaccountStateCallback) |
来电监听 | EVVoipManager | setIncomingCallback(EVVoipManager.IncomingCallbackincomingCallback) |
呼叫APP | EdgeBoxManager | callRoomID(String roomID, EVVoipCallParams params, EdgeBoxManager.OnCallRoomCallback callback) |
接听 | EVVoipCall | accept(EVVideoView display) |
挂断 | EVVoipCall | hangup() |
通话状态监听 | EVVoipCall | setCallStateCallback(EVVoipCall.CallStateCallbackcallStateCallback) |
5. 主要业务流程
5.1 初始化
在进⾏对讲业务之前,需要先初始化该SDK,才能保证后续业务正常,后续的所有API调⽤都必须在SDK初始化成功的情况下执⾏。在应⽤的⽣命周期内,⼀般只进⾏⼀次初始化。
public static void init(Context context, EVVoipManager.OnInitCallback callback)
// 初始化对讲SDK
EVVoipManager.init(getApplicationContext(), new EVVoipManager.OnInitCallback() {
@Override
public void complete() {
// 对讲SDK初始化成功
}
@Override
public void error(int code) {
// 对讲SDK初始化失败,错误代码code
}
});
当不再使⽤对讲业务时,可以调⽤deInit进⾏SDK反初始化。
// 反初始化对讲SDK
EVVoipManager.deInit(getApplicationContext());
5.2 登入SIP服务器
在对讲SDK初始化成功之后,需要进⾏SIP服务器登入,登入成功后可以得到EVVoipAccount对象。
EVVoipAccount EVVoipManager.login(String sipnum, String password, String displayName, String domain, int port)
为了能够实时显示账号状态,本SDK提供 AccountStateCallback 接⼝实时监听当前账号状态。
mEVVoipAccount.setAccountStateCallback(new EVVoipAccount.AccountStateCallback() {
@Override
public void onState(EVVoipAccount.AccountState state) {
/* 获取该账号的状态
* AccountState.ONLINE 在线
* AccountState.OFFLINE 离线
* AccountState.LOGINPROCESS 登入中
* AccountState.NONE ⽆账号、未登入
*/
}
});
当不再使⽤对讲业务,可以通过以下接⼝进⾏登出操作。
mEVVoipAccount.logoutEdgeBox();
5.3 呼叫监听
为了使APP能够响应设备通话请求,需要注册⼀个来电回调监听接⼝。
EVVoipManager.setIncomingCallback(new EVVoipManager.IncomingCallback() {
@Override
public void inComing(EVVoipCall evCall) {
// evCall表示当前来电的通话
}
});
为了能够实时获取当前的通话状态,可以在EVVoipCall对象上设置⼀个通话状态回调接⼝。
evCall.setCallStateCallback(new EVVoipCall.CallStateCallback() {
@Override
public void onState(CallState state, EndReason reason) {
// 参考⻔禁机呼叫APP示例
}
});
5.4 通话接听
为了显示设备的对讲画面,需要提供⼀个EVVideoView作为视频容器,如果不提供则为⾳频通话。
private EVVideoView eVideoView;
public int accept(EVVideoView display) throws EVVoipException;
// 初始化视频绘制容器,EVVideoView是⼀个android.app.Fragment,⽬前只⽀持在xml布局⽂件中配置
mEVVideoView= (EVVideoView) getFragmentManager().findFragmentById(R.id.display_view);
try {
// 响应监控请求
evCall.accept(mEVVideoView);
} catch (EVVoipException e) {
e.printStackTrace();
}
5.5 通话挂断
evVoipCall.setCallStateCallback(null);
try {
evVoipCall.hangup();
} catch (EVVoipException e) {
e.printStackTrace();
}
5.6 开门
通话中可以发送开门指令,在发送开门指令前先设置监听器,通过监听获取开门指令执行结果。
EVVoipCall.unlock
evVoipCall.setUnlockCallback(new EVVoipCall.UnlockCallback() {
@Override
public void onSuccess() {
//开门成功
}
@Override
public void onFailure() {
//开门失败
}
});
int ret = call.unlock();//开门
5.7 通话中呼叫监听
EVVoipManager.setSwitchCallback
mOnSwitchCallback = new OnSwitchCallBack() {
@Override
public void onSwitch(EVVoipCall call) {
}
@Override
public void onResume(EVVoipCall call) {
}
@Override
public void onPause(EVVoipCall call) {
}
};
EVVoipManager.setSwitchCallback(mOnSwitchCallback);
5.8 对话视频
evVoipCall.setOnRemoteVideoMuteListener(new OnRemoteVideoMuteListener() {
@Override
public void onRemoteVideoMuteAnswer(boolean mute) {
}
@Override
public void onRemoteVideoMuteOffer(boolean mute) {
}
});
5.9 开关视频
evVoipCall.enableVideo
5.10 通话协议监听
evVoipCall.setOnIceNatListener(new OnIceNatListener() {
@Override
public void OnAudioIceNatListener(int iceNet) {
case IceNatType.ICE_NAT_TYPE_HOST:
case IceNatType.ICE_NAT_TYPE_SRFLX:
case IceNatType.ICE_NAT_TYPE_PRFLX:
case IceNatType.ICE_NAT_TYPE_RELAY:
}
@Override
public void OnVideoIceNatListener(int iceNet) {
case IceNatType.ICE_NAT_TYPE_HOST:
case IceNatType.ICE_NAT_TYPE_SRFLX:
case IceNatType.ICE_NAT_TYPE_PRFLX:
case IceNatType.ICE_NAT_TYPE_RELAY:
}
});
evVoipCall.setOnMonitorListener(new OnMonitorListener() {
@Override
public void onMonitor() {
}
});
问题1:setOnMonitorListener接口作用
5.11 APP调看门禁机
呼叫对讲设备
evVoipCall = VoipManager.getInstance().call(sipNum, evVoipCallParams);
设置通话状态监听
evVoipCall.setCallStateCallback(new CallStateCallback {
@Override
void onState(EVVoipCall.CallState var1, EVVoipCall.EndReason var2) {
}
});
设置呼叫失败监听
evVoipCall.setCallFailureCallback(new CallFailureCallback() {
@Override
public void onFailure() {
}
});
开启麦克风(本地还是远端)
evVoipCall.enableMicrophone(true); //true-关闭麦克风,false-开启麦克风
开启扬声器
evVoipCall.enableSpeaker(true); //true-开启扬声器,false-关闭扬声器
设置远程视频禁止监听
evVoipCall.setOnRemoteVideoMuteListener(new OnRemoteVideoMuteListener() {
@Override
public void onRemoteVideoMuteAnswer(boolean mute) {
}
@Override
public void onRemoteVideoMuteOffer(boolean mute) {
}
});
6.调试方法
6.1日志抓取方法
6.2关键流程日志
6.3 启动功能选择Activity
adb shell am start com.lee.phone.demo/com.lee.phone.demo.ChooseActivity
6.4 强制关闭Demo
adb shell am force-stop com.lee.phone.demo
7.FAQ
7.1 Debug版本工作正常,Release工作启动异常
2021-10-12 15:13:51.270 30733-30733/? A/DEBUG: Abort message: 'JNI DETECTED ERROR IN APPLICATION: mid == null
in call to CallStaticIntMethod
from void com.lee.phone.jni.LeeJni.leeInit(java.lang.String, java.lang.String, int, int, boolean, java.lang.String, java.lang.String, java.lang.String)'
2021-10-12 15:13:51.270 30733-30733/? A/DEBUG: x0 0000000000000000 x1 00000000000077db x2 0000000000000006 x3 0000007ffe2299b0
2021-10-12 15:13:51.270 30733-30733/? A/DEBUG: x4 fefeff71731e1f97 x5 fefeff71731e1f97 x6 fefeff71731e1f97 x7 7f7f7f7f7f7f7fff
2021-10-12 15:13:51.270 30733-30733/? A/DEBUG: x8 00000000000000f0 x9 156478bff1817c09 x10 0000000000000001 x11 0000000000000000
2021-10-12 15:13:51.270 30733-30733/? A/DEBUG: x12 fffffff0fffffbdf x13 ffffffffffffffff x14 0000000000000004 x15 ffffffffffffffff
2021-10-12 15:13:51.270 30733-30733/? A/DEBUG: x16 00000072780c3958 x17 000000727809fa70 x18 00000072795bc000 x19 00000000000077db
2021-10-12 15:13:51.270 30733-30733/? A/DEBUG: x20 00000000000077db x21 00000000ffffffff x22 00000071e1f50300 x23 00000071f2565945
2021-10-12 15:13:51.270 30733-30733/? A/DEBUG: x24 00000071f258754b x25 0000000000000001 x26 00000071f2bbc258 x27 0000007278bca9a0
2021-10-12 15:13:51.270 30733-30733/? A/DEBUG: x28 00000071f2a91338 x29 0000007ffe229a50
2021-10-12 15:13:51.270 30733-30733/? A/DEBUG: sp 0000007ffe229990 lr 000000727804f704 pc 000000727804f730
2021-10-12 15:13:51.650 30733-30733/? A/DEBUG: backtrace:
2021-10-12 15:13:51.650 30733-30733/? A/DEBUG: #00 pc 0000000000083730 /apex/com.android.runtime/lib64/bionic/libc.so (abort+160) (BuildId: 34c26ab262e93abd89e0bece8eedd768)
2021-10-12 15:13:51.650 30733-30733/? A/DEBUG: #01 pc 00000000004b9f68 /apex/com.android.runtime/lib64/libart.so (art::Runtime::Abort(char const*)+2280) (BuildId: 0e606603700990d6d4117e187ef17d14)
2021-10-12 15:13:51.650 30733-30733/? A/DEBUG: #02 pc 000000000000b458 /system/lib64/libbase.so (android::base::LogMessage::~LogMessage()+580) (BuildId: 34ca25523d4cef6dbfb222bd871ca0ed)
2021-10-12 15:13:51.650 30733-30733/? A/DEBUG: #03 pc 000000000037885c /apex/com.android.runtime/lib64/libart.so (art::JavaVMExt::JniAbort(char const*, char const*)+1584) (BuildId: 0e606603700990d6d4117e187ef17d14)
2021-10-12 15:13:51.650 30733-30733/? A/DEBUG: #04 pc 00000000003b605c /apex/com.android.runtime/lib64/libart.so (art::JNI::CallStaticIntMethod(_JNIEnv*, _jclass*, _jmethodID*, ...)+1464) (BuildId: 0e606603700990d6d4117e187ef17d14)
2021-10-12 15:13:51.650 30733-30733/? A/DEBUG: #05 pc 0000000000290da0 /data/app/com.mqsz.life-JDTtNTsP89Vr90VYRjaCTQ==/lib/arm64/libleephone.so (lee_phone_detect_cameras+132) (BuildId: d1fde14fc5dc0807eb669a513e0e682a303e5ada)
2021-10-12 15:13:51.650 30733-30733/? A/DEBUG: #06 pc 000000000045e644 /data/app/com.mqsz.life-JDTtNTsP89Vr90VYRjaCTQ==/lib/arm64/libleephone.so (lee_android_camera_init+120) (BuildId: d1fde14fc5dc0807eb669a513e0e682a303e5ada)
检查Release模式下混淆配置是否正确,参考《3.3 代码混淆配置》
7.2 leeMuteSpeaker和enableSpeaker区别
leeMuteSpeaker是SDK中把收到的音频直接扔掉,不通过扬声器播放这一步
enableSpeaker是android系统标准接口,切换扬声器和听筒