Android 集成方法
1. 前言
在你阅读此文档时,我们假定您已具备基础的 Android应用开发经验,并能够理解相关基础概念.
1.1 请联系拓课销售人员获取拓课云平台企业账号
1.2 请到拓课云官方网站下载TalkCloud Android sdk
1.3 此demo的targetSdkVersion为31 ,minsdk为23, gradle 为4.4 , 请调校好本地环境
1.4 SDK aar 包在目录 talkplus/app/lib 下分别为 :
classroomsdkrelease(底层库-必须导入)
WhiteBoardSDK-release(课件白板UI库-必须导入)
eduhdsdkrelease(教室ui库-必须导入)
2 集成步骤
2.1.1 如果使用拓课云plus 样式则修改App ID, 图标, 包名, FileProvide 和 AutoUpdateUtil.Class中companydimain对应的公司域名即可.
2.1.2 aar方式集成,将 talkplus/app/lib 下 aar 文件拷贝到自己项目的 lib 目录下, 并通过 implementation fileTree方式,
引用由于本sdk中的ui库引用了第三方样式, 需要通过重新导入三方库才可正常使用
注意 有三方库冲突的引用需改为本sdk的版本,如无法改动需要联系商务或者收获 告之需求重新获取sdk
2.2.3 gradle设置: 添加下列代码后,执行gradle编译, 下载第三方库资源:
1
2
3
4
5
6
7
8
9
10
11
12
13 | //非必选 教室内需要语音字幕功能的依赖。(此功能收费请找商务了解开通)
implementation 'com.microsoft.cognitiveservices.speech:client-sdk:1.24.0'
//必需依赖
implementation 'com.llew.huawei:verifier:1.1.2'
implementation “com.android.support:appcompat-v7:28.0.0”
implementation 'com.android.support:cardview-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:2.0.4'
implementation 'com.android.support:recyclerview-v7:28.0.0'
implementation 'com.tencent.edu:TAISDK:1.2.3.89''
//如果只使用互动课堂相关(一对一,一对多教室),可以不引用tencent相关包, 如下:
implementation 'com.tencent.liteav:LiteAVSDK_Professional:9.5.11346'
|
2.2 配置Application
| ScreenScale.init(this);//适配方案
TKPluginsManager.getInstance().setContext(this).setShareData("appId"/微信,"appSecret"/微信).setStatisticsData("appId","channel").init();//配置umeng 具体详见2.5
//解决通过反射解决在HuaWei手机出现Register too many Broadcast Receivers的crash
if (!Tools.phoneIsSony(context)) {
LoadedApkHuaWei.hookHuaWeiVerifier(this);
}
|
2.3 配置相关参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 | //设置教室内通知样式的app名称
FunctionSetManage.getInstance().setAppName(R.string.app_name);
//设置教室内通知样式logo
FunctionSetManage.getInstance().setAppLogo(R.drawable.tk_logo);
//设置进入教室时是否跳过设备检测页面(选择添加)
FunctionSetManage.getInstance().setIsSkipDeviceTesting(this,false);
//设置关闭崩溃日志收集的弹窗
FunctionSetManage.getInstance().setIsSkipCrashHandleDialog(true);
//设置关闭功能引导(选择添加)
FunctionSetManage.getInstance().setIsGuide(getApplicationContext(),true);
//设置进教室的音量百分比(选择添加)
FunctionSetManage.getInstance().setMaxVolume(0.5);
//设置教室crash时日志收集的标识 例:talk
FunctionSetManage.getInstance().setCarshEnterprise("talk");
//显示崩溃弹窗 4634版本新增
FunctionSetManage.getInstance().setIsSkipCrashHandleDialog(true);
//是否开启设备检测上报 默认不开启
FunctionSetManage.getInstance().setReportDeviceTest(true);
//日志异常捕获-拓课云
new CrashHandler(this);
//是否显示教室内部设置弹框隐私协议,默认不显示
FunctionSetManage.getInstance().setIsShowSettingPrivacyAgreement(this, false);
//针对非老师端的设置, 默认false下课后 非老师端不直接退出教室 弹出课程结束界面。设置ture,非老师端不会弹出结束界面 直接退出 toast 提示课程结束(4.15.1.4新增配置项)
FunctionSetManage.getInstance().setDirectExit(false);
|
2.3.1 单独设备检测页
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 | //是否开启设备检测上报 默认不开启
FunctionSetManage.getInstance().setReportDeviceTest(true);
/**
* 进入动态设备检测页面
*
* @param domain 企业域名
* @param userid 用户id
* @param activity
*/
public void joinDynamicDeviceTesting(Activity activity, String domain, String userid) {
Intent intent = new Intent(activity, DynamicDeviceTestingActivity.class);
intent.putExtra("domain", domain);
intent.putExtra("userid", userid);
activity.startActivity(intent);
}
```
2.4 进入教室
2.4.1 注册进入教室信息回调
实现接口:
<li>MeetingNotify</li>
<li>JoinmeetingCallBack</li>
``` java
//注册接口:
RoomClient.getInstance().regiestInterface(this,this);
|
2.4.2 进入教室 ( RoomClient.class )
调用joinRoom方法之后, 如果加入房间不成功,会有相对应的错误回调如下:
|MeetingNotify 接口介绍| 说明| |--|--| |void onKickOut(int var1)|
var1=0: 您已被老师请出教室! var1=1:
有相同身份的用户进入! var1=401:
当前课程已结束 var1=402: 当前课程已被取消| |void onWarning(int var1)
| var1=1: 没有视频权限var1=2:
没有音频权限| |void onClassBegin()| 课程开始| |void onClassDismiss()| 课程结束| |void onLeftRoomComplete()|
离开课堂成功后的回调| |void onEnterRoomFailed(int result,String desc)|
result=失败原因代码 desc=失败的原因描述| |void joinRoomComplete()|
进入课堂成功后的回调| |void onCameraDidOpenError()| 摄像头打开失败回调|
2.4.3 上课 方法 joinRoom 调用方式
| //param:Map格式,内含进入房间所需的基本参数,例如:
HashMap<String, Object> params = new HashMap<String, Object>();
params.put("serial", "12345678"); 房间号
params.put("password", "1111"); 预约房间时指定的密码,注意不同身份对应不同密码
params.put("nickname","tom");本地用户的昵称
params.put("userrole",2);学生2,老师0,旁听生6,巡课4
//params.put("userid","111");用户id,可选(相同id 会互踢慎用)
RoomClient.getInstance().joinRoom(this, params);
|
2.4.4 播放回放(常规录制件,含记录播放进度选填) 方法 joinPlayBackRoom
| Map<String, Object> params = new HashMap<String, Object>();
params.put("domain", "www");//企业id
//域名加端口号+回放路径
params.put("path","global.talk-cloud.net:8081/749f3185-eadb-475b-83ed-b5944430be43-1414270898/");
params.put("serial", "1008611");//教室号
params.put("recordtitle", "*******");//根据后台返回的数据(回放标题)
params.put("skipTime", "30");//进度值,秒(记录播放进度时才传)
RoomClient.getInstance().joinPlayBackRoom(this, params);
|
2.4.5 播放回放(MP4视频) 方法 joinPlayMp4Back
RoomClient.getInstance().joinPlayMp4Back (this, “MP4播放地址”);
| 进入mp4的播放页面,需要记录时长的
*
@param activity
@param mp4Url mp4 播放地址
@param skipTime 当前进度时长
*/
public void joinPlayMp4Back(Activity activity,String mp4Url,String skipTime)
|
2.4.6加载不同的gif需要调用的方法
SkinTool.getmInstance().setLoadingImg(Object loadingImg);参数可以是String类型的url或者本地int类型drawable
| 1、在app首页的onCreate里面调用,并且需要在SkinTool.getmInstance().setLoadingSkin(this, loadingImageView);方法之前调用
2、不需要替换loading GIF的话不需要调用
3、当需要链接进教室的时候需要在handleIntentemm方法里面添加
|
2.4.7 进入播放mp4 回放 调用方法 带统计
| Map<String, String> params = new HashMap<String, String>();
params.put(“user_id”, “”); //用户id
params.put(“company_id”, “”);//企业id
params.put(“mp4Title”, “”);//标题
params.put(“recordtitle”, “”);//需要服务端返回
params.put(“mp4Url”, “https://recorddemo.talk-cloud.net/987c9582-5680-4de7-beae-b18ccdb1406b-141912260/record.mp4");//回放地址
params.put(“serial”, “”);//教室号
RoomClient.getInstance().joinPlayBackMp4(this,params);
|
2.5 功能接口
必须导入TalkPlusFunctionDomain-release 该版本只开放了 umeng统计和分享的接口实现,不需要umeng统计和分享的客户可以不再依赖三方库的包了
以下三种方式都需要在application里配置
2.5.1 不需要umeng功能
| 在application里配置
TKPluginsManager.getInstance().setContext(this).setPluginShareType(TKPluginsConstants.PLUGIN_SHARE_TYPE_NONE).setPluginStatisticsType(TKPluginsConstants.PLUGIN_STATISTICS_TYPE_NONE).init();
|
2.5.2 需要umeng功能 由拓课云实现此功能
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | 在application里配置
TKPluginsManager.getInstance().setContext(this).setShareData("appId"/微信,"appSecret"/微信).setStatisticsData("appId","channel").init();
并依赖 //友盟基础组件
//友盟统计
//友盟基础组件
implementation'com.umeng.umsdk:common:9.3.8'
implementation'com.umeng.umsdk:asms:1.2.2' // asms包依赖(必选)
implementation'com.umeng.umsdk:oaid_lenovo:1.0.0' // (可选)
implementation'com.umeng.umsdk:oaid_mi:1.0.0' // (可选)
implementation'com.umeng.umsdk:oaid_oppo:1.0.4' // (可选)
implementation'com.umeng.umsdk:oaid_vivo:1.0.0.1' // (可选)
implementation'com.umeng.umsdk:crash:0.0.4' // native crash包依赖(必选)
implementation'com.umeng.umsdk:share-core:7.1.4' //友盟分享核心库
implementation'com.umeng.umsdk:share-board:7.1.4'
implementation'com.umeng.umsdk:share-wx:7.1.4'
|
2.5.3 需要umeng 功能 自己实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 | 在application里配置
TKPluginsManager.getInstance().setContext(this).setShareApi(new TkShareApi() {
@Override
public void initShare(Context context) {
}
@Override
public boolean isShowShareButton(Context context) {
return false;
}
@Override
public void onShare(Context context, String shareLink, String shareTitle, String sharePic, String shareDesc, CallBack callBack) {
}
@Override
public void onUmengActivityResult(int requestCode, int resultCode, Intent data) {
}
@Override
public void onRelease() {
}
}).setStatisticsApi(new TkStatisticsApi() {
@Override
public void initStatistics(Context context) {
}
@Override
public void onEventObject( String eventId, HashMap map) {
}
}).init();
|
|TKPluginsManager |方法介绍 |说明 |--|--|--| |setContext(Context context) |设置上下文| Context 上下文
|setPluginShareType(int type ) |分享
|TKPluginsConstants.PLUGIN_SHARE_TYPE_UMENG,TKPluginsConstants.PLUGIN_SHARE_TYPE_NONE
|setPluginStatisticsType(int type) |统计
|TKPluginsConstants.PLUGIN_STATISTICS_TYPE_NONE,TKPluginsConstants.PLUGIN_STATISTICS_TYPE_UMENG
|setShareApi(TkShareApi shareApi) |分享自定义实现 |TkShareApi实现类 |setStatisticsApi(TkStatisticsApi
statisticsApi) |统计自定义实现 |TkStatisticsApi实现类 |setStatisticsData(String statisticsAppKey, String
statisticsChannel) |友盟统计需要参数 |友盟统计appKey,友盟统计渠道 |setShareData(String shareAppId, String
shareAppSecret) |微信分享参数 微信申请APPId,APPSecret |init() |初始化设置 |
|TkShareaApi| 接口介绍| 说明 |--|--|--| |void initShare(Context context ) |上下文 |Context 上下文 |boolean
isShowShareButton(Context context) |是否显示分享按钮 |Context 上下文 |void onShare(Context context, String
shareLink, String shareTitle, String sharePic, String shareDesc, CheckBox playShare) |分享
shareLink,分享链接, shareTitle标题, sharePic 图片, shareDesc描述, playShare 分享按钮分享成功后手动置为false |void
onUmengActivityResult(int requestCode, int resultCode, Intent data) |分享回调 |requestCode 请求code,
resultCode返回code, Intent data 数据 |void onRelease()| 释放| 无
|TkStatisticsApi |接口介绍| 说明 |--|--|--| |void initStatistics(Context context) |初始化统计sdk |Context 上下文
|void onEventObject( String eventId, HashMap map) |eventId:login_page_select_role
登录页面选择身份,上报设备类型和用户身份 |Role 0:老师,1:助教,2:学生,4:巡课 暂无使用 | |eventId: video_layout 上报视频布局类型 |layoutType:
视频居右,视频居左,主讲布局,自由布局 | |eventId: user_list_icon_click 花名册点击事件上报 |key, value:
取消/授权画笔,打开/关闭麦克风,加入/移除黑名单,设为/取消 主讲人,上下台 | |eventId: video_list_icon_click 视频上控件点击事件上报 |key, value:
取消/授权画笔,打开/关闭麦克风,加入/移除黑名单,设为/取消 主讲人,上下台,奖励减少奖杯,打开关闭摄像头,视频交换,视频复位 | |eventId: all_control 全体场控 |key,
value:全体开关麦,全体允许禁止翻页课件,全体奖励,全体复位 | |eventId: chat_page_translate 聊天页面翻译事件 |key, value:
全体开关麦,全体允许禁止翻页课件,全体奖励,全体复位
3 常见问题
| java.lang.ClassCastException:SkinCompatLinearLayout cannot be cast to relativelayout
|
解决方法 : 加载动画xml不使用标签加载,提取xml文件至include处
解决方案:允许子view超过父布局即可,即给父view设置属性
| android:clipChildren="false"
android:clipToPadding="false"
|
参考
参考文件1:RefDoc#01
参考文件2:RefDoc#02
参考文件3:RefDoc#03
- 集成xwalk时出现 error inflating class org.xwalk.core.xwalkview (3.2.4以前版本)
解决方案:build.gradle中android/defaultConfig下添加
| ndk {
abiFilters "armeabi", "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
}
|
- 集成过程中在某一些机型上出现进教室崩溃 (3.2.4以前版本)
报错:PackageManager$NameNotFoundException: com.google.android.gms
原因:webview和XWalkView冲突导致的
解决方案:建议把项目中的webview换成XWalkView,XWalkView的用法和webview极其类似。而且比webview兼容性更好。
-
使用https协议,joinRoom函数的参数port (端口) 传443。RoomClient中TKRoomManager.useSecureSocket改为true。
-
当需要多页面进入教室时A-B,需要在A页面重新注册监听 B页面不用调用 RoomClient.getInstance().resetInstance();
使用AutoSize框架的时候,出现UI错误的时候,需要在application里面初始化如下方法 当使用fragment适配时AutoSizeConfig.getInstance()
.setCustomFragment(true);需要在进入教室时callback回调code等于0的时候设置为false,退出教室的时候设置成true
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | AutoSizeConfig.getInstance().getExternalAdaptManager().addCancelAdaptOfActivity(DeviceTestingActivity.class);
AutoSizeConfig.getInstance().getExternalAdaptManager().addCancelAdaptOfActivity(LargeClassRoomActivity.class);
AutoSizeConfig.getInstance().getExternalAdaptManager().addCancelAdaptOfActivity(LivePlayBackActivity.class);
AutoSizeConfig.getInstance().getExternalAdaptManager().addCancelAdaptOfActivity(OneToManyActivity.class);
AutoSizeConfig.getInstance().getExternalAdaptManager().addCancelAdaptOfActivity(OneToOneActivity.class);
AutoSizeConfig.getInstance().getExternalAdaptManager().addCancelAdaptOfActivity(VideoViewPlayActivity.class);
AutoSizeConfig.getInstance().getExternalAdaptManager().addCancelAdaptOfActivity(HelpWebViewActivity.class);
AutoSizeConfig.getInstance().getExternalAdaptManager().addCancelAdaptOfActivity(TKEndClassActivity.class);
AutoSizeConfig.getInstance().getExternalAdaptManager().addCancelAdaptOfActivity(TransparentActivity.class);
|
- 3.6.2 以后集成了umeng分享 需要在app 下的build.gradle 的defaultConfig 里添加
| manifestPlaceholders = [qqappid: “1106834082”]
|
-
3.6.3 版本以后无需配置,根据功能接口配置来确定是否需要umeng功能
-
3.6.4 版本后 把请求权限放入在进入教室流程里,需要把之前版本集成的请求权限代码删除 并按照新文档 在activity里添加 权限请求结果回调代码 详见文档-进入教室 2.4.1.1