跳转至

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(底层库-必须导入)

ClassRoomSdkWithUi-release(课件白板UI库-必须导入)

eduhdsdkrelease(教室ui库-必须导入)

TalkPlusFunctionDomain-release.aar(功能实现接口库-必须导入-集成详见2.5)

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
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
   implementation 'com.llew.huawei:verifier:1.1.2'
// 1. Common
implementation "com.android.support:appcompat-v7:27.1.1"
implementation "com.android.support:support-v4:27.1.1"
implementation 'com.android.support.constraint:constraint-layout:2.0.4'
implementation 'com.github.android-async-http:android-async-http:1.4.9'
implementation 'com.github.bumptech.glide:glide:4.9.0'
implementation 'com.belerweb:pinyin4j:2.5.0'

// 2. Edu_Module
// noinspection GradleCompatible
implementation 'com.android.support:cardview-v7:27.1.1'
implementation 'com.thetransactioncompany:jsonrpc2-base:1.38'
implementation 'org.java-websocket:Java-WebSocket:1.3.0'
implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0'
implementation 'org.apache.commons:commons-lang3:3.0'
implementation 'com.alibaba:fastjson:1.2.55'
implementation 'com.google.android:flexbox:0.3.0-alpha2'
implementation 'org.jetbrains:annotations:15.0'
implementation 'com.tencent.liteav:LiteAVSDK_Professional:9.5.11346' 腾讯播放器
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'org.nanohttpd:nanohttpd:2.3.1'
implementation 'com.github.ctiao:DanmakuFlameMaster:0.9.25'
implementation 'com.danikula:videocache:2.7.1' 
implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.30'

// 3. WB_Module
implementation('io.socket:socket.io-client:1.0.0') {
    exclude group: 'org.json', module: 'json'
}
implementation 'com.github.srikanth-lingala:zip4j_1.3.3:567af0b3e1'
implementation 'cz.msebera.android:httpclient:4.4.1.2'
implementation 'com.tencent.imsdk:imsdk-plus:5.6.1200'

2.2 配置Application

1
2
3
4
5
6
    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
//设置教室内通知样式的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);

2.4 进入教室

2.4.1 注册进入教室信息回调

实现接口:

  • MeetingNotify
  • JoinmeetingCallBack
  • 1
    2
    //注册接口:
    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 调用方式

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
        //param:Map格式,内含进入房间所需的基本参数,例如:
        HashMap<String, Object> params = new HashMap<String, Object>();
        params.put("serial", "12345678"); 房间号
        params.put("password", "1111"); 预约房间时指定的密码注意不同身份对应不同密码
        params.put("host","global.talk-cloud.net");服务器地址默认是global.talk-cloud.net非必填
        params.put("port",443);服务器http端口是80 ,服务器https端口是443非必填
        params.put("nickname","tom");本地用户的昵称
        params.put("userrole",2);学生2老师0旁听生6巡课4
        //params.put("userid","111");用户id,可选(相同id 会互踢慎用)
        params.put("clientType","2");设备类型1 PC 2 Android 3 iOS非必填
        //uiserid(用户ID,可选)、password(密码)、 clientType(设备类型1 PC 2 Android 3 iOS)
        RoomClient.getInstance().joinRoom(this, params);
    

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

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    Map<String, Object> params = new HashMap<String, Object>();
    params.put("host", "global.talk-cloud.net");//域名(非必填)
    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");//进度值,秒(记录播放进度时才传)
    params.put("breakurl", "https%3A%2F%2Fuat.chindle.com%2FstudentServer%2FchindleAdd%2FaddTalkCloudVideoRecord%3Fjsondata%3D%7B%26quot%3BclassId%26quot%3B%3A%26quot%3B1%26quot%3B%2C%26quot%3BuserId%26quot%3B%3A%26quot%3B1%26quot%3B%7D");//上传进度的url含登陆信息,(记录播放进度时才传)
    RoomClient.getInstance().joinPlayBackRoom(this, params);
    

    2.4.5 播放回放(MP4视频) 方法 joinPlayMp4Back

    RoomClient.getInstance().joinPlayMp4Back (this, “MP4播放地址”);

    1
    2
    3
    4
    5
    6
    7
    8
    进入mp4的播放页面需要记录时长的
    *
    @param activity
    @param mp4Url mp4 播放地址
    @param breakUrl 上传播放进度的url
    @param skipTime 当前进度时长
    */
    public void joinPlayMp4Back(Activity activity,String mp4Url, String breakUrl,String skipTime)
    

    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.4.7 进入播放mp4 回放 调用方法 带统计
    1
    2
    3
    4
    5
    6
    7
    8
        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功能

    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:巡课 暂无使用
    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 常见问题

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

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

    © 2016-2021 北京拓课网络科技有限公司 版权所有  京ICP备17018423号-1 京公网安备11010502043461号