跳转至
400-881-9892

文档中心

官方文档,可查阅产品介绍、快速入门、用户指南、开发指南、API参考、SDK参考、帮助等信息。

文档中心 互动课堂

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 SDK 集成步骤

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.1.3 gradle设置

添加下列代码后,执行gradle编译, 下载第三方库资源:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
//非必选 教室内需要语音字幕功能的依赖。(此功能收费请找商务了解开通)
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'
4.17.4后续版本的sdk使用下边的版本
implementation 'com.tencent.liteav:LiteAVSDK_Professional:11.9.0.14445'

2.2 配置Application

1
2
3
4
5
    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
//是否开启设备检测上报 默认不开启
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 注册回调

//注册进入教室信息接口: RoomClient.getInstance().regiestInterface(this,this);

2.4.2 进入房间

调用 RoomClient.getInstance().joinRoom(this, params); 是示例

1
2
3
4
5
6
7
8
    //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.3 进入教室方法回调

调用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() 摄像头打开失败回调
void onOpenEyeProtection() 是否打开护眼模式

JoinmeetingCallBack 回调错误码详见 Sdk错误码

2.4.4 播放回放(常规录制件,含记录播放进度选填)

方法 joinPlayBackRoom

1
2
3
4
Map<String, Object> params = new HashMap<String, Object>();
params.put("serial", "1008611");//教室号
params.put("recordtitle", "*******");//根据后台返回的数据(回放标题)
RoomClient.getInstance().joinPlayBackRoom(this, params);

2.4.5 播放回放(MP4视频)

方法 joinPlayMp4Back

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
进入mp4的播放页面需要记录时长的
/*
@param activity
@param mp4Url mp4 播放地址
@param skipTime 当前进度时长
@param breakUrl 上传播放进度的url
*/
public void joinRoomWithMediaUrl(Activity activity,String mp4Url,String skipTime,String breakUrl)
public void joinRoomWithMediaUrl(Activity activity,String mp4Url)
/*
@param activity
@param mp4Url mp4 播放地址
@param map 参数 //用于播放mp4时 打点日志上传至拓课云
       mp4Title 视频标题
       recordtitle 录制件资源id 根据后台返回的数据
       serial      教室号
       company_id  企业ID
       user_id     用户ID
*/
public void joinRoomWithMediaUrl(Activity activity,String mp4Url, Map<String, String> map)

2.4.6加载不同的gif需要调用的方法

SkinTool.getmInstance().setLoadingImg(Object loadingImg);参数可以是String类型的url或者本地int类型drawable

Caution

1
2
3
1、在app首页的onCreate里面调用,并且需要在SkinTool.getmInstance().setLoadingSkin(this, loadingImageView);方法之前调用
2、不需要替换loading GIF的话不需要调用
3、当需要链接进教室的时候需要在handleIntentemm方法里面添加

2.5 功能接口

必须导入TalkPlusFunctionDomain-release 该版本只开放了 umeng统计和分享的接口实现,不需要umeng统计和分享的客户可以不再依赖三方库的包了 以下三种方式都需要在application里配置

2.5.1 不需要umeng功能
1
2
在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:巡课 暂无使用
void onEventObject( String eventId, HashMap map); eventId: video_layout 上报视频布局类型 layoutType: 视频居右,视频居左,主讲布局,自由布局
void onEventObject( String eventId, HashMap map); eventId: user_list_icon_click 花名册点击事件上报 key, value:取消/授权画笔,打开/关闭 麦克风,加入/移除黑名单,设为/取消 主讲人,上下台
void onEventObject( String eventId, HashMap map); eventId: video_list_icon_click 视频上控件点击事件上报 key, value: 取消/授权画笔,打开/关闭 麦克风,加入/移除黑名单,设为/取消 主讲人,上下台,奖励减少奖杯,打开关闭摄像头,视频交换,视频复位
void onEventObject( String eventId, HashMap map); eventId: all_control 全体场控 key, value:全体开关麦,全体允许禁止翻页课件,全体奖励,全体复位
void onEventObject( String eventId, HashMap map); eventId: chat_page_translate 聊天页面翻译事件 key, value:translate:翻译
## 3 常见问题
  • 进入教室 加载动画
1
java.lang.ClassCastException:SkinCompatLinearLayout cannot be cast to relativelayout

解决方法 : 加载动画xml不使用标签加载,提取xml文件至include处

  • 如何替换 logo 在 app 模块的 drawable 目录下 tk_logo.png

  • 奖杯动画过程中,缩放动画在某些机型上会显示不全,原因是动画被父布局遮盖

解决方案:允许子view超过父布局即可,即给父view设置属性

1
2
         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下添加

1
2
3
    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);
  • 以后集成了umeng分享 需要在app 下的build.gradle 的defaultConfig 里添加
1
manifestPlaceholders = [qqappid: 1106834082]
  • 版本以后无需配置,根据功能接口配置来确定是否需要umeng功能

  • 版本后 把请求权限放入在进入教室流程里,需要把之前版本集成的请求权限代码删除 并按照新文档 在activity里添加 权限请求结果回调代码 详见文档-进入教室 2.4.1.1