接入智能教练SDK及参数设置
简要描述
主要协助第三方App接入智能教练,并且设置相应参数的功能代码示例
主要内容
版本号:1.13.2beta
minSdk:21
引入方式:maven
支持的ABI:armeabi-v7a、arm64-v8a
代码设置
1、引入相关nexus服务 相关IP白名单配置请联系项目负责人
maven{
allowInsecureProtocol = true
url 'https://devinner.yunxuetang.com.cn/nexus/content/repositories/releases/'}
maven{
allowInsecureProtocol = true
url 'https://nexus-sdk.yunxuetang.com.cn/repository/maven-public/'}
2、引入智能教练库
implementation("com.yxt.sdk.library_sparring:core:1.13.1")
3、添加SDK相关权限依赖
<!--连接网络权限,用于执行云端语音能力 -->
<uses-permission android:name="android.permission.INTERNET"/>
<!--获取手机录音机使用权限,听写、识别、语义理解需要用到此权限 -->
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<!--读取网络信息状态 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!--获取当前wifi状态 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<!--允许程序改变网络连接状态 -->
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<!--读取手机信息权限 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<!--读取联系人权限,上传联系人需要用到此权限 -->
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<!--外存储写权限,构建语法需要用到此权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!--外存储读权限,构建语法需要用到此权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<!--手机定位信息,用来为语义等功能提供定位,提供更精准的服务-->
<!--摄相头权限,拍照需要用到 -->
<uses-permission android:name="android.permission.CAMERA" />
4、Webview配置自定义WebChromeClient用于解析协议智能教练的入口均为H5,原生与H5交互通过yxt协议通信 (JsPrompt)
//可参考以下代码
import android.net.Uri;
import android.text.TextUtils;
import android.webkit.JsPromptResult;
import android.webkit.JsResult;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import org.json.JSONObject;
public class YxtWebChromeClient extends WebChromeClient {
@Override
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
result.confirm();
Uri uri = Uri.parse(message);
String host = uri.getHost();
if (TextUtils.isEmpty(host))
return false;
String key_schema_3 = "yxtapp://";
if (message.startsWith(key_schema_3)) {
String keyParam = "param";
String param = uri.getQueryParameter(keyParam);
String name = getProtoPrm(param, "name");
switch (name){
//AI智能陪练 开始陪练
case "biz.sparring.start":
String codeStart = getProtoPrm(param, "code");
String isPreview = getProtoPrm(param, "isPreview");
SparringUtils.openSparringService(view.getContext(),view,codeStart,isPreview,1);
break;
//AI智能陪练 练习回顾
case "biz.sparring.review":
String codeReview = getProtoPrm(param, "code");
SparringUtils.openSparringService(view.getContext(),view,codeReview,"",2);
break;
//AI智能陪练 开始陪练
case "biz.sparring.open":
String codeOpen = getProtoPrm(param, "code");
SparringUtils.openSparringService(view.getContext(),view,codeOpen,"",3);
break;
}
}
return true;
}
@Override
public boolean onJsAlert(WebView webView, String s, String s1, JsResult jsResult) {
jsResult.confirm();
return true;
}
public static String getProtoPrm(String p, String key) {
String res = "";
try {
JSONObject j = new JSONObject(p);
if (j.isNull(key)) {
res = "";
} else {
res = j.optString(key, "");
}
} catch (Exception e) {
e.printStackTrace();
}
return res;
}
}
5、协议解析成功后,获取到的相关参数进行初始化后打开智能教练SDK即可
SparringUtils.openSparringService(view.getContext(),view,codeStart,isPreview,1);
工具类可参考以下代码
import android.content.Context;
import android.webkit.WebView;
import com.yxt.sparring.SparringManager;
import com.yxt.sparring.utils.http.StartType;
/**
* create by yxtAdmin on 2022年02月16日16:04:05
* 智能教练工具类
*/
public class SparringUtils {
/**
* 打开智能教练
* @param context 上下文
* @param webView 加载器
* @param code 智能教练code码
* @param isPreview 是否为预览
* @param type 打开方式
*/
public static void openSparringService(Context context, WebView webView, String code, String isPreview, int type) {
StartType startType = StartType.DEFAULT;
switch (type) {
case 1:
startType = StartType.DEFAULT;
break;
case 2:
startType = StartType.REVIEW;
break;
case 3:
startType = StartType.OPEN_PAGE;
break;
default:
break;
}
initSparringManagerConfig(context,webView,code,isPreview,startType);
}
private static int environment = 1;// 1:测试 2:产线 3:预发布
/**
* 初始化智能教练
* @param mContext 上下文
* @param webView 加载器
* @param code 智能教练code码
* @param isPreview 是否位预览
* @param type 打开方式
*/
public static void initSparringManagerConfig(Context mContext, WebView webView, String code, String isPreview, StartType type) {
if (!code.isEmpty()) {
//AI陪练初始化
SparringManager.SparringConfig config = new SparringManager.SparringConfig();
config.setEnableLog(true);
config.setSource("503");
config.setEnableReachabilityToast(false);
config.setSdkCloseCallBack(() -> {
String js = "javascript:window.InterFaceForSP.sparringActive()";
//sdk关闭回调js - H5协议
webView.loadUrl(js);
});
if (environment == 1) {
//测试
config.setEnvironment(SparringManager.AISparringEnvironment.DEVELOPMENT);
} else if (environment == 2) {
//产线
config.setEnvironment(SparringManager.AISparringEnvironment.PRODUCTION);
} else if (environment == 3) {
//预发布
config.setEnvironment(SparringManager.AISparringEnvironment.STAGE);
}
SparringManager.INSTANCE.init(mContext, config,new ImageLoaderImp());
//调起sdk
SparringManager.INSTANCE.start(code, isPreview, type);
}
}
}
为尽量避免项目编译、依赖冲突,图片加载能力由外部传入,可参考以下代码Glide
package com.yxt.sparringintegrationdemo.utils;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.widget.ImageView;
import androidx.annotation.Nullable;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.load.resource.gif.GifDrawable;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target;
import com.yxt.sparring.utils.glide.IGlideLoad;
import java.io.File;
import java.util.concurrent.ExecutionException;
/**
* create by yxtAdmin on 2022年02月18日14:31:35
* 图片加载实现类
*/
public class ImageLoaderImp implements IGlideLoad {
@Override
public void load(Context context, String url, ImageView view) {
Glide.with(context).load(url).into(view);
}
@Override
public void load(Context context, String url, ImageView view, LoadResultCallback loadResultCallback) {
Glide.with(context).load(url).listener(new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
if (loadResultCallback != null) {
loadResultCallback.onFailure();
}
return false;
}
@Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
if (loadResultCallback != null) {
loadResultCallback.onSuccess();
}
return false;
}
}).into(view);
}
@Override
public void loadGif(Context context, String url, ImageView view, LoadResultCallback loadResultCallback) {
Glide.with(context).asGif().load(url).listener(new RequestListener<GifDrawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<GifDrawable> target, boolean isFirstResource) {
if (loadResultCallback != null) {
loadResultCallback.onFailure();
}
return false;
}
@Override
public boolean onResourceReady(GifDrawable resource, Object model, Target<GifDrawable> target, DataSource dataSource, boolean isFirstResource) {
if (loadResultCallback != null) {
loadResultCallback.onSuccess();
}
return false;
}
}).into(view);
}
@Override
public void downloadOnly(Context context, String url) {
try {
Glide.with(context).downloadOnly().load(url).submit().get();
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
}
@Override
public File getFile(Context context, String url) {
try {
return Glide.with(context).downloadOnly().load(url).submit().get();
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
return null;
}
}