集成SDK之前请首先在Android Studio创建您的项目,如果您已有Android项目,可直接集成SDK。
build.gradle
android{
dataBinding {
enabled = true
}
}
// 引入aar, 需加入这个声明
repositories {
flatDir {
dirs 'libs'
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'io.reactivex.rxjava2:rxjava:2.2.0'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
implementation 'com.squareup.okhttp3:okhttp:3.11.0'
// replace with the aar name (替换成最新的aar)
implementation(name: 'xylink-sdk-release-xxx-xxx', ext: 'aar')
}
AndroidManifest.xml
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
proguard-rules.pro
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
-keepattributes *Annotation*
-ignorewarnings
-dontwarn
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclassmembers,allowoptimization enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keepattributes *Annotation*
-keep enum com.ainemo.sdk.NemoSDKListener** {
**[] $VALUES;
public *;
}
-keepnames class * implements java.io.Serializable
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
-dontwarn sun.misc.**
-keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* {
long producerIndex;
long consumerIndex;
}
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef {
rx.internal.util.atomic.LinkedQueueNode producerNode;
}
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef {
rx.internal.util.atomic.LinkedQueueNode consumerNode;
}
-keep class com.ainemo.sdk.otf.code.**{*;}
-keep class com.ainemo.sdk.otf.NemoSDK{public <methods>;}
-keep class com.ainemo.sdk.otf.NemoSDKInitCallBack{*;}
-keep class com.ainemo.sdk.otf.NemoSDKErrorCode{*;}
-keep class com.ainemo.module.call.view.opengl.GLTextureView{*;}
-keep class com.ainemo.module.call.view.opengl.GLTextureView$*{*;}
-keep class com.ainemo.sdk.otf.OpenGLTextureView{*;}
-keep class com.ainemo.sdk.otf.WhiteboardGLTextureView{*;}
-keep class com.ainemo.sdk.otf.WhiteboardGLTextureView$Renderer{*;}
-keep class com.ainemo.sdk.otf.WhiteboardGLTextureView$EGLContextFactory{*;}
-keep class com.ainemo.sdk.otf.NemoSDKListener{public <methods>;}
-keep class com.ainemo.sdk.otf.WhiteboardChangeListener{*;}
-keep class com.ainemo.sdk.otf.Settings{public <methods>;}
-keep class com.ainemo.sdk.otf.VideoInfo{*;}
-keep class com.ainemo.sdk.otf.RosterWrapper{*;}
-keep class com.ainemo.sdk.otf.Roster{*;}
-keep class com.ainemo.sdk.otf.LoginResponseData{*;}
-keep class com.ainemo.sdk.otf.NemoReceivedCallListener{*;}
-keep class com.ainemo.sdk.otf.ConnectNemoCallback{*;}
-keep class com.ainemo.sdk.otf.MakeCallResponse{*;}
-keep class com.ainemo.sdk.otf.RecordCallback{*;}
-keep class com.ainemo.sdk.otf.UpdatePwdCallback{*;}
-keep class com.ainemo.module.call.data.NewStatisticsInfo{*;}
-keep class com.ainemo.module.call.data.FECCCommand{*;}
-keep class com.ainemo.sdk.model.*{*;}
-keep class com.ainemo.sdk.model.**{*;}
-keep class com.ainemo.sdk.module.push.PushManager{public <methods>;}
-keep class com.ainemo.sdk.module.push.PushMsg{*;}
-keep class com.ainemo.sdk.module.rest.Uris{public <methods>;}
-keep class com.ainemo.sdk.module.rest.RestService{*;}
-keep class com.ainemo.sdk.module.rest.HttpFailException{*;}
-keep class com.ainemo.sdk.module.rest.model.*{*;}
-keep class com.ainemo.sdk.module.rest.model.*$*{*;}
-keep class com.ainemo.sdk.utils.Base64Utils{*;}
-keep class com.ainemo.sdk.module.data.*{*;}
-keep class com.ainemo.sdk.otf.NemoSDKListener$*{*;}
-keep class com.ainemo.sdk.otf.SimpleNemoSDkListener{*;}
-keep class com.ainemo.shared.MediaSourceID{*;}
-keep class com.ainemo.module.call.data.Enums{*;}
-keep class com.ainemo.module.call.data.RemoteUri{*;}
-keep class com.ainemo.shared.UserActionListener{*;}
-keep class vulture.module.call.sdk.**{*;}
-keep class vulture.module.call.nativemedia.NativeDataSourceManager{native <methods>;}
-keep class android.http.HttpConnector{*;}
-keep class android.utils.PrivateCloudUtils{*;}
-keep class android.log.**{*;}
-keep class android.utils.RestartHandler{*;}
-keep class android.utils.Signature{*;}
-keep class android.util.ThreadedHandler{*;}
-keep class com.llvision.**{*;}
-keep class com.ainemo.sdk.otf.AudioDataListener.**{*;}
-keep class com.ainemo.sdk.otf.VideoConfig{*;}
-keep class com.ainemo.sdk.otf.ContentType{*;}
-keep class com.ainemo.sdk.otf.Orientation{*;}
-keep class com.ainemo.util.**{*;}
-keep class com.ainemo.sdk.otf.AudioDataListener{*;}
-keep class okhttp3.** { *; }
-keep class vulture.nettool.DiagnoseException{*;}
-keep class vulture.nettool.DiagnoseException$ExceptionContent{*;}
-keep class vulture.nettool.DiagnoseResult{*;}
-keep class vulture.nettool.DiagnoseResult$DiagnoseContent{*;}
-keep class vulture.nettool.DiagnoseResult$DiagnoseContent$DiagnoseDetail{*;}
-keep class vulture.nettool.NNTJniListener{*;}
-keep class vulture.nettool.NNTJniListener$OnNetworkDiagnoseListener{*;}
-keep class vulture.nettool.NNTJni{*;}
-keep class vulture.module.call.nativemedia.*{*;}
-keep class com.ainemo.sdk.otf.CustomLayout{*;}
-keep class com.ainemo.sdk.otf.GpuInfoResult{*;}
-keep class com.ainemo.sdk.otf.LayoutElement{*;}
-keep class com.ainemo.sdk.otf.ResolutionRatio{*;}
-keep class com.ainemo.module.call.data.*{*;}
-keep class com.ainemo.module.call.model.CallReplaceEvent{*;}
-keep class vulture.module.call.sdk.CallSdkJniListener$*{*;}
-keep class com.ainemo.module.call.video.layout.*{*;}
-keep class com.ainemo.sdk.otf.LayoutPolicy{*;}
-keep class com.ainemo.sdk.otf.LayoutPolicy$LayoutBuilder{*;}
-keep class com.ainemo.sdk.otf.ConfMgmtInfo{*;}
-keep class com.ainemo.sdk.otf.Orientation{*;}
-keep class com.ainemo.sdk.module.biz.model.RestMessage{*;}
-keep class com.ainemo.sdk.otf.NemoSDK$OnStateChangeListener{*;}
-keep class com.ainemo.sdk.otf.GetGpuInfoCallback{*;}
-keep class com.ainemo.sdk.otf.SocketProxyCallback{*;}
-keep class com.ainemo.sdk.otf.SocketProxyValidateResult{*;}
-keep class com.ainemo.sdk.otf.Speaker{*;}
-keep class com.ainemo.sdk.otf.VideoStreamInfo{*;}
-keep class com.ainemo.sdk.otf.ContentType{*;}
-keep class com.ainemo.sdk.otf.VideoConfig{*;}
-keep class com.ainemo.sdk.otf.RecordingState{*;}
-keep class com.ainemo.sdk.otf.UriReason{*;}
-keep class com.ainemo.sdk.realnotify.InteractiveEventCallback{*;}
-keep class com.ainemo.sdk.realnotify.sign.SignStatus{*;}
-keep interface com.ainemo.sdk.callback.*{*;}
混淆配置当以所集成SDK包内proguard.txt内容为准!
音视频通话的API调用时序图如下:
在调用API之前需要进行初始化,您需要在该步骤中填入项目的enterpriseId,如果您已经完成准备工作中的内容,则可以从管理平台获取到enterpriseId。 在Application的onCreate方法中调用init方法即可初始化xylinkSDK:
MyApplication.java
//旧版本鉴权:
Settings settings = new Settings("企业ID");
settings.setPrivateCloudAddress("cloud.xylink.com");
NemoSDK nemoSDK = NemoSDK.getInstance();
nemoSDK.init(this, settings);
//新版本鉴权:
Settings settings = new Settings("企业ID", "ClientId", "ClientSecret");
settings.setPrivateCloudAddress("sdkapi.xylink.com");
NemoSDK nemoSDK = NemoSDK.getInstance();
nemoSDK.init(this, settings);
第三方账号登录方法定义:
NemoSDK.java
/**
* @param displayName 用户显示名称,用以在通话场景中标识当前用户
* @param externalUserId 第三方账户ID,与平台呼叫号码一一对应
* @param loginCallback 登录回调接口,用于接收登录成功或失败信息,以及成功后返回的当前用户的呼叫号码等信息
*/
public void loginExternalAccount(String displayName, String externalUserId, ConnectNemoCallback loginCallback);
第三方账号登录的示例代码如下:
LoginActivity.java
NemoSDK.loginExternalAccount(displayName, externalId, new ConnectNemoCallback() {
@Override
public void onFailed(final int errorCode) {
//登录失败后返回错误码,根据错误码可进行相关业务处理
L.e(TAG, "Login failed, errorCode:" + errorCode);
......
}
@Override
public void onSuccess(LoginResponseData data, boolean isDetectingNetworkTopology) {
//登录成功后返回登录信息
L.i(TAG, "login succeeds, data:" + data);
......
//根据是否需要进行网络探测进行相关业务处理
if (isDetectingNetworkTopology) {
......
}
......
}
@Override
public void onNetworkTopologyDetectionFinished(LoginResponseData resp) {
//网络探测结束后返回通知
L.i(TAG, "net detect onNetworkTopologyDetectionFinished 1");
}
});
}
登录成功之后,可以调用makecall方法发起呼叫,方法定义:
NemoSDK.java
/**
* @param number 会议号或终端号
* @param password 会议密码或终端密码
* @param response 呼叫的响应,返回成功或失败信息
*/
public void makeCall(String number, String password, MakeCallResponse response)
呼叫成功之后,需要通过setNemoSDKListener方法监听会议事件,根据事件回调信息进行相应的业务处理:
XyCallPresenter.java
public void start() {
//设置监听事件
NemoSDK.getInstance().setNemoSDKListener(new SimpleNemoSDkListener() {
//根据监听到的事件类型进行分类处理,以呼叫状态变更为例
public void onCallStateChange(CallState state, String reason) {
L.i(TAG, "onCallStateChange: " + state + " reason: " + reason);
switch (state) {
case CONNECTING:
......
}
}
//其他回调事件处理
......
}
}
会议连接之后,需要进行请流、布局、渲染等操作,具体流程可以参考基础功能章节。
您可以根据业务场景选择挂断呼叫的时机,挂断的方法定义:
NemoSDK.java
/**
* 挂断当前通话
*/
public void hangup()
如果用户已完全退出您的应用,需要对SDK进行销毁。
NemoSDK.java
/**
* 应用退出后销毁SDK
*/
public void shutdown()