接入智能教练SDK及参数设置

简要描述

主要协助第三方App接入智能教练,并且设置相应参数的功能代码示例

主要内容

版本号:1.13.2beta

minSdk:21

引入方式:maven

支持的ABI:armeabi-v7a、arm64-v8a

代码设置

1、引入相关nexus服务 相关IP白名单配置请联系项目负责人

  1. maven{
  2. allowInsecureProtocol = true
  3. url 'https://devinner.yunxuetang.com.cn/nexus/content/repositories/releases/'}
  4. maven{
  5. allowInsecureProtocol = true
  6. url 'https://nexus-sdk.yunxuetang.com.cn/repository/maven-public/'}

2、引入智能教练库

  1. implementation("com.yxt.sdk.library_sparring:core:1.13.1")

3、添加SDK相关权限依赖

  1. <!--连接网络权限,用于执行云端语音能力 -->
  2. <uses-permission android:name="android.permission.INTERNET"/>
  3. <!--获取手机录音机使用权限,听写、识别、语义理解需要用到此权限 -->
  4. <uses-permission android:name="android.permission.RECORD_AUDIO"/>
  5. <!--读取网络信息状态 -->
  6. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
  7. <!--获取当前wifi状态 -->
  8. <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
  9. <!--允许程序改变网络连接状态 -->
  10. <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
  11. <!--读取手机信息权限 -->
  12. <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
  13. <!--读取联系人权限,上传联系人需要用到此权限 -->
  14. <uses-permission android:name="android.permission.READ_CONTACTS"/>
  15. <!--外存储写权限,构建语法需要用到此权限 -->
  16. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  17. <!--外存储读权限,构建语法需要用到此权限 -->
  18. <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
  19. <!--手机定位信息,用来为语义等功能提供定位,提供更精准的服务-->
  20. <!--摄相头权限,拍照需要用到 -->
  21. <uses-permission android:name="android.permission.CAMERA" />

4、Webview配置自定义WebChromeClient用于解析协议智能教练的入口均为H5,原生与H5交互通过yxt协议通信 (JsPrompt)

  1. //可参考以下代码
  2. import android.net.Uri;
  3. import android.text.TextUtils;
  4. import android.webkit.JsPromptResult;
  5. import android.webkit.JsResult;
  6. import android.webkit.WebChromeClient;
  7. import android.webkit.WebView;
  8. import org.json.JSONObject;
  9. public class YxtWebChromeClient extends WebChromeClient {
  10. @Override
  11. public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
  12. result.confirm();
  13. Uri uri = Uri.parse(message);
  14. String host = uri.getHost();
  15. if (TextUtils.isEmpty(host))
  16. return false;
  17. String key_schema_3 = "yxtapp://";
  18. if (message.startsWith(key_schema_3)) {
  19. String keyParam = "param";
  20. String param = uri.getQueryParameter(keyParam);
  21. String name = getProtoPrm(param, "name");
  22. switch (name){
  23. //AI智能陪练 开始陪练
  24. case "biz.sparring.start":
  25. String codeStart = getProtoPrm(param, "code");
  26. String isPreview = getProtoPrm(param, "isPreview");
  27. SparringUtils.openSparringService(view.getContext(),view,codeStart,isPreview,1);
  28. break;
  29. //AI智能陪练 练习回顾
  30. case "biz.sparring.review":
  31. String codeReview = getProtoPrm(param, "code");
  32. SparringUtils.openSparringService(view.getContext(),view,codeReview,"",2);
  33. break;
  34. //AI智能陪练 开始陪练
  35. case "biz.sparring.open":
  36. String codeOpen = getProtoPrm(param, "code");
  37. SparringUtils.openSparringService(view.getContext(),view,codeOpen,"",3);
  38. break;
  39. }
  40. }
  41. return true;
  42. }
  43. @Override
  44. public boolean onJsAlert(WebView webView, String s, String s1, JsResult jsResult) {
  45. jsResult.confirm();
  46. return true;
  47. }
  48. public static String getProtoPrm(String p, String key) {
  49. String res = "";
  50. try {
  51. JSONObject j = new JSONObject(p);
  52. if (j.isNull(key)) {
  53. res = "";
  54. } else {
  55. res = j.optString(key, "");
  56. }
  57. } catch (Exception e) {
  58. e.printStackTrace();
  59. }
  60. return res;
  61. }
  62. }

5、协议解析成功后,获取到的相关参数进行初始化后打开智能教练SDK即可

  1. SparringUtils.openSparringService(view.getContext(),view,codeStart,isPreview,1);

工具类可参考以下代码

  1. import android.content.Context;
  2. import android.webkit.WebView;
  3. import com.yxt.sparring.SparringManager;
  4. import com.yxt.sparring.utils.http.StartType;
  5. /**
  6. * create by yxtAdmin on 2022年02月16日16:04:05
  7. * 智能教练工具类
  8. */
  9. public class SparringUtils {
  10. /**
  11. * 打开智能教练
  12. * @param context 上下文
  13. * @param webView 加载器
  14. * @param code 智能教练code码
  15. * @param isPreview 是否为预览
  16. * @param type 打开方式
  17. */
  18. public static void openSparringService(Context context, WebView webView, String code, String isPreview, int type) {
  19. StartType startType = StartType.DEFAULT;
  20. switch (type) {
  21. case 1:
  22. startType = StartType.DEFAULT;
  23. break;
  24. case 2:
  25. startType = StartType.REVIEW;
  26. break;
  27. case 3:
  28. startType = StartType.OPEN_PAGE;
  29. break;
  30. default:
  31. break;
  32. }
  33. initSparringManagerConfig(context,webView,code,isPreview,startType);
  34. }
  35. private static int environment = 1;// 1:测试 2:产线 3:预发布
  36. /**
  37. * 初始化智能教练
  38. * @param mContext 上下文
  39. * @param webView 加载器
  40. * @param code 智能教练code码
  41. * @param isPreview 是否位预览
  42. * @param type 打开方式
  43. */
  44. public static void initSparringManagerConfig(Context mContext, WebView webView, String code, String isPreview, StartType type) {
  45. if (!code.isEmpty()) {
  46. //AI陪练初始化
  47. SparringManager.SparringConfig config = new SparringManager.SparringConfig();
  48. config.setEnableLog(true);
  49. config.setSource("503");
  50. config.setEnableReachabilityToast(false);
  51. config.setSdkCloseCallBack(() -> {
  52. String js = "javascript:window.InterFaceForSP.sparringActive()";
  53. //sdk关闭回调js - H5协议
  54. webView.loadUrl(js);
  55. });
  56. if (environment == 1) {
  57. //测试
  58. config.setEnvironment(SparringManager.AISparringEnvironment.DEVELOPMENT);
  59. } else if (environment == 2) {
  60. //产线
  61. config.setEnvironment(SparringManager.AISparringEnvironment.PRODUCTION);
  62. } else if (environment == 3) {
  63. //预发布
  64. config.setEnvironment(SparringManager.AISparringEnvironment.STAGE);
  65. }
  66. SparringManager.INSTANCE.init(mContext, config,new ImageLoaderImp());
  67. //调起sdk
  68. SparringManager.INSTANCE.start(code, isPreview, type);
  69. }
  70. }
  71. }

为尽量避免项目编译、依赖冲突,图片加载能力由外部传入,可参考以下代码Glide

  1. package com.yxt.sparringintegrationdemo.utils;
  2. import android.content.Context;
  3. import android.graphics.drawable.Drawable;
  4. import android.widget.ImageView;
  5. import androidx.annotation.Nullable;
  6. import com.bumptech.glide.Glide;
  7. import com.bumptech.glide.load.DataSource;
  8. import com.bumptech.glide.load.engine.GlideException;
  9. import com.bumptech.glide.load.resource.gif.GifDrawable;
  10. import com.bumptech.glide.request.RequestListener;
  11. import com.bumptech.glide.request.target.Target;
  12. import com.yxt.sparring.utils.glide.IGlideLoad;
  13. import java.io.File;
  14. import java.util.concurrent.ExecutionException;
  15. /**
  16. * create by yxtAdmin on 2022年02月18日14:31:35
  17. * 图片加载实现类
  18. */
  19. public class ImageLoaderImp implements IGlideLoad {
  20. @Override
  21. public void load(Context context, String url, ImageView view) {
  22. Glide.with(context).load(url).into(view);
  23. }
  24. @Override
  25. public void load(Context context, String url, ImageView view, LoadResultCallback loadResultCallback) {
  26. Glide.with(context).load(url).listener(new RequestListener<Drawable>() {
  27. @Override
  28. public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
  29. if (loadResultCallback != null) {
  30. loadResultCallback.onFailure();
  31. }
  32. return false;
  33. }
  34. @Override
  35. public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
  36. if (loadResultCallback != null) {
  37. loadResultCallback.onSuccess();
  38. }
  39. return false;
  40. }
  41. }).into(view);
  42. }
  43. @Override
  44. public void loadGif(Context context, String url, ImageView view, LoadResultCallback loadResultCallback) {
  45. Glide.with(context).asGif().load(url).listener(new RequestListener<GifDrawable>() {
  46. @Override
  47. public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<GifDrawable> target, boolean isFirstResource) {
  48. if (loadResultCallback != null) {
  49. loadResultCallback.onFailure();
  50. }
  51. return false;
  52. }
  53. @Override
  54. public boolean onResourceReady(GifDrawable resource, Object model, Target<GifDrawable> target, DataSource dataSource, boolean isFirstResource) {
  55. if (loadResultCallback != null) {
  56. loadResultCallback.onSuccess();
  57. }
  58. return false;
  59. }
  60. }).into(view);
  61. }
  62. @Override
  63. public void downloadOnly(Context context, String url) {
  64. try {
  65. Glide.with(context).downloadOnly().load(url).submit().get();
  66. } catch (ExecutionException | InterruptedException e) {
  67. e.printStackTrace();
  68. }
  69. }
  70. @Override
  71. public File getFile(Context context, String url) {
  72. try {
  73. return Glide.with(context).downloadOnly().load(url).submit().get();
  74. } catch (ExecutionException | InterruptedException e) {
  75. e.printStackTrace();
  76. }
  77. return null;
  78. }
  79. }