diff --git a/app/build.gradle b/app/build.gradle index 5824efe..90ff28c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -3,9 +3,7 @@ apply plugin: 'com.android.application' android { compileSdkVersion 30 buildToolsVersion "30.0.3" - buildFeatures { - dataBinding = true - } + dataBinding { enabled = true } defaultConfig { applicationId "qianmu.container" @@ -17,7 +15,7 @@ android { testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles 'consumer-rules.pro' - ndk { abiFilters "armeabi-v7a", "arm64-v8a" } + ndk { abiFilters "armeabi-v7a" } javaCompileOptions { annotationProcessorOptions { @@ -97,7 +95,7 @@ dependencies { implementation files('libs\\jna-min.jar') implementation files('libs\\toolbox_kit.jar')//灰度主板 罗湖寻车机 implementation files('libs\\shockman.jar')//指路机 - implementation files('libs/signway.jar') //欣威视通 + implementation files('libs\\signway.jar') //欣威视通 implementation files('libs\\sdkapi.jar') //Bv-3588 implementation files('libs\\smdt.jar') //视美泰 testImplementation 'junit:junit:4.12' @@ -105,8 +103,10 @@ dependencies { androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' implementation 'com.squareup.retrofit2:retrofit:2.5.0' implementation 'com.squareup.retrofit2:converter-gson:2.5.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' - implementation 'com.lzy.net:okgo:3.0.4' + implementation 'com.squareup.okhttp3:okhttp:3.12.13' + implementation ('com.lzy.net:okgo:3.0.4') { + exclude group: 'com.squareup.okhttp3' // 排除 OkGo 自带的 OkHttp 3.8.1 + } implementation 'org.greenrobot:eventbus:3.1.1' implementation 'com.alibaba:arouter-api:1.5.0' implementation 'com.github.bumptech.glide:glide:4.9.0' @@ -114,7 +114,7 @@ dependencies { annotationProcessor 'com.alibaba:arouter-compiler:1.2.2' implementation 'org.java-websocket:Java-WebSocket:1.5.1' implementation 'com.google.android.exoplayer:exoplayer:2.11.4' - + implementation 'com.yanzhenjie.andserver:api:2.0.4' annotationProcessor 'com.yanzhenjie.andserver:processor:2.0.4' implementation files('libs/java-unrar-1.7.0-8.jar') // rar解压 @@ -133,8 +133,8 @@ dependencies { implementation 'cn.hutool:hutool-all:5.8.26' //清除页面缓存 - debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.3' - releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.3' + debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3' + releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3' //检测内存泄漏 // debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.12' diff --git a/app/libs/AndroidScreenCap.jar b/app/libs/AndroidScreenCap.jar new file mode 100644 index 0000000..169b0b7 Binary files /dev/null and b/app/libs/AndroidScreenCap.jar differ diff --git a/app/libs/zckjAPI-2.6.jar b/app/libs/zckjAPI-2.6.jar new file mode 100644 index 0000000..81c2d1e Binary files /dev/null and b/app/libs/zckjAPI-2.6.jar differ diff --git a/app/release/app-release.apk b/app/release/app-release.apk index aac903a..9560089 100644 Binary files a/app/release/app-release.apk and b/app/release/app-release.apk differ diff --git a/app/release/app_andorid_V2_卓策iot分屏容器_V2.0.7.30.apk b/app/release/app_andorid_V2_卓策iot分屏容器_V2.0.7.30.apk new file mode 100644 index 0000000..ab2ec8d Binary files /dev/null and b/app/release/app_andorid_V2_卓策iot分屏容器_V2.0.7.30.apk differ diff --git a/app/release/app_andorid_V2_亿晟3576iot分屏容器_V2.0.7.30.apk b/app/release/app_andorid_V2_卓策iot分屏容器_V2.0.7.31.apk similarity index 85% rename from app/release/app_andorid_V2_亿晟3576iot分屏容器_V2.0.7.30.apk rename to app/release/app_andorid_V2_卓策iot分屏容器_V2.0.7.31.apk index 8e00736..d38599b 100644 Binary files a/app/release/app_andorid_V2_亿晟3576iot分屏容器_V2.0.7.30.apk and b/app/release/app_andorid_V2_卓策iot分屏容器_V2.0.7.31.apk differ diff --git a/app/release/app_andorid_V2_卓策iot分屏容器_V2.0.8.0.apk b/app/release/app_andorid_V2_卓策iot分屏容器_V2.0.8.0.apk new file mode 100644 index 0000000..2818502 Binary files /dev/null and b/app/release/app_andorid_V2_卓策iot分屏容器_V2.0.8.0.apk differ diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json index 748ea83..81d7a5a 100644 --- a/app/release/output-metadata.json +++ b/app/release/output-metadata.json @@ -11,7 +11,7 @@ "type": "SINGLE", "filters": [], "versionCode": 6, - "versionName": "V2.0.7.30", + "versionName": "V2.0.8.0", "outputFile": "app-release.apk" } ] diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index dbb952e..e42c0ae 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,51 +2,36 @@ - - - - - - - - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + - - - + + + + - + - - - - + android:screenOrientation="nosensor" /> + android:screenOrientation="nosensor" /> - - - - + + android:exported="true" /> - - @@ -124,7 +105,6 @@ - @@ -132,7 +112,6 @@ - diff --git a/app/src/main/java/qianmu/container/activity/H5/WebViewActivity.java b/app/src/main/java/qianmu/container/activity/H5/WebViewActivity.java index 8c8aa35..7e180e6 100644 --- a/app/src/main/java/qianmu/container/activity/H5/WebViewActivity.java +++ b/app/src/main/java/qianmu/container/activity/H5/WebViewActivity.java @@ -4,6 +4,8 @@ import android.annotation.SuppressLint; import android.app.ActivityManager; import android.content.Context; import android.content.Intent; +import android.media.MediaPlayer; +import android.net.Uri; import android.os.Bundle; import android.os.Debug; import android.os.Handler; @@ -40,8 +42,11 @@ import com.shockman.sm.vendor.SmUtils; import com.shockman.sm.vendor.TargetVo; import org.greenrobot.eventbus.EventBus; +import org.java_websocket.drafts.Draft_6455; +import org.java_websocket.enums.ReadyState; import java.io.File; +import java.net.URI; import java.text.SimpleDateFormat; import java.util.List; import java.util.Scanner; @@ -63,16 +68,21 @@ import qianmu.container.entity.KdxfBean; import qianmu.container.entity.MessageEvent; import qianmu.container.entity.ResourceFileBean; import qianmu.container.entity.ScreenSaver; +import qianmu.container.entity.TTSMessage; import qianmu.container.entity.Vocbean; import qianmu.container.listener.QueryFinishListener; +import qianmu.container.socket.SocketClient; import qianmu.container.util.AppUtil; +import qianmu.container.util.AudioPlay; import qianmu.container.util.CalendarUtils; import qianmu.container.util.DeviceUtil; import qianmu.container.util.FileUtil; +import qianmu.container.util.GsonUtil; import qianmu.container.util.KeyboardUtil; import qianmu.container.util.LoggerUtil; import qianmu.container.util.SignWayUtil; import qianmu.container.util.StringUtil; +import qianmu.container.util.TTSUtil; import qianmu.container.util.ToastUtils; import static qianmu.container.service.ContainerService.initFirstTime; @@ -86,36 +96,27 @@ public class WebViewActivity extends BaseActivity { static final int TYPE_GO_SAVESCREEN = 300;//导视通知跳转屏保 static final int TYPE_HINT_PASSWORD = 3;//隐藏密码输入框 static final int TYPE_START_SERVER = 4;//重新启动web服务 - static final int TYPE_SHENG_HTML_MAG = 5;//返回接口请求值给h5 - static String HtmlUrl = "http://127.0.0.1:8080/index.html";//webServer服务地址 - String vocMsg = "";//语音内容 - // 语音听写对象 - private SpeechRecognizer mIat; + //static String HtmlUrl = "http://127.0.0.1:8080/index.html";//webServer服务地址 + static String HtmlUrl = "http://192.168.1.218:5173/";//webServer服务地址 int time = 0; - String interfaceRequestData=""; + SocketClient localSocketClient; Handler handler = new Handler() { @SuppressLint("HandlerLeak") @Override public void handleMessage(@NonNull Message msg) { super.handleMessage(msg); - switch (msg.what){ - case TYPE_REFURBISH_WEBVIEW://刷新webview try { binding.web.clearCache(true); binding.web.loadUrl(HtmlUrl); Constant.isCoreService=true; }catch (Exception e){ - } - - break; case TYPE_GO_SAVESCREEN://导视通知跳转屏保 - try { initFirstTime(); if (!ScreenSaverData.isProgramPlay()) return; @@ -137,25 +138,13 @@ public class WebViewActivity extends BaseActivity { removeMessages(TYPE_HINT_PASSWORD); } time++; - try { - - }catch (Exception e){ - - } break; - case TYPE_START_SERVER: removeMessages(TYPE_REFURBISH_WEBVIEW); sendEmptyMessageDelayed(TYPE_REFURBISH_WEBVIEW,2000); startService(new Intent(WebViewActivity.this, CoreService.class)); LoggerUtil.e("WebViewActivity","CoreService重启"); break; - - case TYPE_SHENG_HTML_MAG: - getHandWriting(interfaceRequestData); - interfaceRequestData=""; - DeviceData.saveInterfaceRequest(""); - break; } } }; @@ -165,10 +154,73 @@ public class WebViewActivity extends BaseActivity { DeviceUtil.screenType(this); getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); binding = DataBindingUtil.setContentView(this, R.layout.activity_webview); + // 设置背景透明度 + binding.web.setBackgroundColor(0); + binding.web.getBackground().setAlpha(0); + + Uri videoUri = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.bg); + binding.bgVideo.setVideoURI(videoUri); + binding.bgVideo.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { + @Override + public void onPrepared(MediaPlayer mp) { + mp.setLooping(true); // 可选:设置循环播放 + binding.bgVideo.start(); // 开始播放视频 + } + }); + Uri videoUri1 = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.hello); + binding.helloVideo.setVideoURI(videoUri1); + binding.helloVideo.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { + @Override + public void onPrepared(MediaPlayer mp) { + mp.setLooping(true); // 可选:设置循环播放 + } + }); + + Uri videoUri2 = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.speek); + binding.speekVideo.setVideoURI(videoUri2); + binding.speekVideo.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { + @Override + public void onPrepared(MediaPlayer mp) { + mp.setLooping(true); // 可选:设置循环播放 + } + }); //设置密码 initPass(); - //初始化科大讯飞 - initKDXF(); + connectLocalSocket(); + } + + //切换视频 + public void changeVideo(String type){ + binding.helloVideo.setZOrderOnTop(false); + binding.helloVideo.setZOrderMediaOverlay(false); + binding.speekVideo.setZOrderOnTop(false); + binding.speekVideo.setZOrderMediaOverlay(false); + if("hello".equals(type)){ + binding.helloVideo.setZOrderOnTop(true); + binding.helloVideo.setZOrderMediaOverlay(true); + binding.helloVideo.setVisibility(View.VISIBLE); + binding.helloVideo.start(); + binding.speekVideo.stopPlayback(); + binding.speekVideo.setVisibility(View.GONE); + binding.bgVideo.stopPlayback(); + binding.bgVideo.setVisibility(View.GONE); + }else if("answer".equals(type)){ + binding.speekVideo.setZOrderOnTop(true); + binding.speekVideo.setZOrderMediaOverlay(true); + binding.speekVideo.setVisibility(View.VISIBLE); + binding.speekVideo.start(); + binding.helloVideo.stopPlayback(); + binding.helloVideo.setVisibility(View.GONE); + binding.bgVideo.stopPlayback(); + binding.bgVideo.setVisibility(View.GONE); + }else{ + binding.bgVideo.setVisibility(View.VISIBLE); + binding.bgVideo.start(); + binding.helloVideo.stopPlayback(); + binding.helloVideo.setVisibility(View.GONE); + binding.speekVideo.stopPlayback(); + binding.speekVideo.setVisibility(View.GONE); + } } @Override @@ -190,28 +242,8 @@ public class WebViewActivity extends BaseActivity { //加载web currRoute = Constant.ROUTE_WEB_VIEW; loadH5Url(getIntent().getBooleanExtra(Constant.KEY_LOAD_H5_URL, false)); - //加载语音 - initVoice(); - } - - //初始化科大讯飞 - private void initKDXF(){ - try { - KdxfBean kdxf = H5Data.getKdxf(); - if(kdxf.getData()==null || kdxf.getData().getDeployType()==null || kdxf.getData().getDeployType().isEmpty() || kdxf.getData().getDeployType().toLowerCase().equals("saas")){ - SpeechUtility.createUtility(this, SpeechConstant.APPID +"=5c2055f8"); - }else { - SpeechUtility.createUtility(this, SpeechConstant.APPID + "=5c2055f8" + "," + "net_type=custom, proxy_ip="+kdxf.getData().getXfyunIp()+", proxy_port="+kdxf.getData().getXfyunPort()); - } - }catch (Throwable t) { - LoggerUtil.e("初始化语音", StringUtil.getThrowableStr(t)); - } } - //初始化语音 - private void initVoice(){ - mIat = SpeechRecognizer.createRecognizer(this, mInitListener); - } @Override protected void setListener() { @@ -223,7 +255,6 @@ public class WebViewActivity extends BaseActivity { } }); - binding.web.setOnLongClickListener((View v) -> { LoggerUtil.e("OnLongClick", "用户长按了页面"); return false; @@ -296,7 +327,6 @@ public class WebViewActivity extends BaseActivity { handler.sendEmptyMessageDelayed(TYPE_START_SERVER,1000); return; } - } @Override @@ -310,19 +340,14 @@ public class WebViewActivity extends BaseActivity { super.onStop(); if(handler!=null){ handler.removeMessages(TYPE_HINT_PASSWORD); - handler.removeMessages(TYPE_SHENG_HTML_MAG); } } @Override protected void onDestroy() { super.onDestroy(); + destroyLocalSocketClient(); LoggerUtil.e(TAG, "onDestroy()"); - if (mIat != null) { - // 退出时释放连接 - mIat.cancel(); - mIat.destroy(); - } } private void loadH5Url(boolean loadUrl) { @@ -344,24 +369,19 @@ public class WebViewActivity extends BaseActivity { return super.onConsoleMessage(cm); } }); - binding.web.addJavascriptInterface(new AndroidtoJs(), "android"); - } - + // JS 调用 android public class AndroidtoJs extends Object { - // 回到屏保页面 @JavascriptInterface public void goScreenSave() { - LoggerUtil.e(TAG,"JS调用了Android的方法:goScreenSave()"); if(handler!=null){ handler.removeMessages(TYPE_GO_SAVESCREEN); handler.sendEmptyMessage(TYPE_GO_SAVESCREEN); } } - // 获取是否有屏保数据 @JavascriptInterface public boolean hasProgram() { @@ -369,14 +389,12 @@ public class WebViewActivity extends BaseActivity { LoggerUtil.e(TAG,"JS调用了Android的方法:hasProgram():"+programPlay); return programPlay; } - // 获取后台地址 @JavascriptInterface public String getBaseAddress() { LoggerUtil.e(TAG,"JS调用了Android的方法:getBaseAddress()"); return Constant.getBaseAddress(); } - // h5调用android:重启webView @JavascriptInterface public void restartWebView() { @@ -384,98 +402,92 @@ public class WebViewActivity extends BaseActivity { handler.removeMessages(TYPE_REFURBISH_WEBVIEW); handler.sendEmptyMessageDelayed(TYPE_REFURBISH_WEBVIEW,3000); } + // h5调用android:开始识别语音 + @JavascriptInterface + public void startRecord() { + LoggerUtil.e(TAG,"JS调用了Android的方法:startRecord()"); + localSocketClient.send(StringUtil.strSplice("{\"method\":\"/asr/start\"}")); + } + // h5调用android:停止识别语音 + @JavascriptInterface + public void stopRecord() { + LoggerUtil.e(TAG,"JS调用了Android的方法:stopRecord()"); + localSocketClient.send(StringUtil.strSplice("{\"method\":\"/asr/stop\"}")); + } + // h5调用android:开始合成语音 + @JavascriptInterface + public void startTTS(String txt) { + LoggerUtil.e(TAG,"JS调用了Android的方法:startTTS()"); + localSocketClient.send(StringUtil.strSplice("{\"method\": \"/tts/start\",\"params\": {\"text\":\"", txt, "\", \"mode\":\"autoPlay\"}}")); + } + // h5调用android:停止合成语音 + @JavascriptInterface + public void stopTTS() { + LoggerUtil.e(TAG,"JS调用了Android的方法:stopTTS()"); + localSocketClient.send(StringUtil.strSplice("{\"method\":\"/tts/stop\"}")); + } + // h5调用android:播放指定视频 + @JavascriptInterface + public void playAudio(String str) { + LoggerUtil.e("JS调用了Android的方法:playAudio", str); + changeVideo(str); + } + } + //语音交互 + private void setLocalSocketListener() { + localSocketClient.setOnOpenListener((handshakeData) -> { + LoggerUtil.e("connectLocalSocket", "TTS客户端连接成功"); + localSocketClient.send(StringUtil.strSplice("{\"method\":\"/asr/stop\"}")); + }); - // h5调用android:开始识别语音 - @JavascriptInterface - public void startVoice() { - LoggerUtil.e(TAG,"JS调用了Android的方法:startVoice()"); - mIat.startListening(mRecognizerListener); - } - - // h5调用android:结束识别语音 - @JavascriptInterface - public void stopVoice() { - LoggerUtil.e(TAG,"JS调用了Android的方法:stopVoice()"); - - } - - // h5调用android:传入要播报语音 - @JavascriptInterface - public void TTS(String content) { - LoggerUtil.e(TAG,"JS调用了Android的方法:TTS()"); - - } - // h5调用android:停止语音播报播报语音 - @JavascriptInterface - public void TTSStop() { - LoggerUtil.e(TAG,"JS调用了Android的方法:TTSStop()"); - } - - // h5调用android:新版指路机传入的数据 - @JavascriptInterface - public void jxbData(String data) { - LoggerUtil.e(TAG,"JS调用了Android的方法:jxbData()"); - DeviceData.saveDeviceInfo(DeviceData.JXB_DATA,data); - } - - // h5调用android:接口请求post - @JavascriptInterface - public void interfaceRequest(String url , String map , boolean state) { - DeviceData.queryOfflineDataByInterfaceToPost(url, map, new QueryFinishListener() { - @Override - public void onFinish() { - if(state){ - interfaceRequestData = DeviceData.getInterfaceRequestData(); - handler.sendEmptyMessage(TYPE_SHENG_HTML_MAG); - } + localSocketClient.setOnMessageListener((conn, message) -> { + try { + TTSMessage messageBean = new Gson().fromJson(message, TTSMessage.class); + TTSMessage.Params content = messageBean.getParams(); + if (content == null) return; + LoggerUtil.e("ttsSocket:", messageBean.getMethod()); + if("asr.text".equals(messageBean.getMethod())){ + LoggerUtil.e("ttsSocket:",content.getText()); + runOnUiThread(new Runnable() { + @Override + public void run() { + binding.web.loadUrl(StringUtil.strSplice("javascript:window.giveAskText('", content.getText(), "');")); + } + }); } - }); - -// LoggerUtil.e(TAG,"JS调用了Android的方法:interfaceRequest1():"+url+","+map); - - } - - // h5调用android:接口请求get - @JavascriptInterface - public void interfaceRequest(String url , boolean state) { - - DeviceData.queryOfflineDataByInterfaceToGet(url, new QueryFinishListener() { - @Override - public void onFinish() { - if(state){ - interfaceRequestData = DeviceData.getInterfaceRequestData(); - handler.sendEmptyMessage(TYPE_SHENG_HTML_MAG); - } + if("asr.result".equals(messageBean.getMethod())){ + LoggerUtil.e("ttsSocket:",content.getText()); + runOnUiThread(new Runnable() { + @Override + public void run() { + localSocketClient.send(StringUtil.strSplice("{\"method\":\"/asr/stop\"}")); + binding.web.loadUrl(StringUtil.strSplice("javascript:window.youAskOver('", content.getText(), "');")); + } + }); } - }); -// LoggerUtil.e(TAG,"JS调用了Android的方法:interfaceRequest2():"+url); - } - - - //旧版指路机:移动手臂 - @JavascriptInterface - public void moveArm(String shopName) { - //直梯+编号 扶梯+编号 - LoggerUtil.e("MainActivity","JS调用了Android的方法:moveArm:"+shopName); - getMoveArm(shopName); - } - - //旧版指路机:是否轮播摇臂 - @JavascriptInterface - public void setRotateSwitcher(String isRotate) { - - try { - SmUtils instance = SmUtils.getInstance(); - instance.rotateSwitcher(Boolean.parseBoolean(isRotate)); - }catch (Exception e){ - + if("tts.result".equals(messageBean.getMethod())){ + LoggerUtil.e("ttsSocket:",content.getSpeakUrl()); + runOnUiThread(new Runnable() { + @Override + public void run() { + changeVideo("bg"); + } + }); + } + } catch (Throwable t) { + LoggerUtil.e("setOnMessageListener", StringUtil.getThrowableStr(t)); } + }); -// LoggerUtil.e("MainActivity","JS调用了Android的方法:getArmNum:"+isCarousel); - - } - - + localSocketClient.setOnCloseListener((code, reason, remote) -> { + LoggerUtil.e("LocSocCliManager", "onClose:code="+code); + if (localSocketClient == null){ + initLocalSocketClient(); + }else { + localSocketClient.reconnect(); + } + }); + localSocketClient.setOnErrorListener((ex) -> LoggerUtil.e("LocSocCliManager", "onError")); } /** @@ -487,153 +499,6 @@ public class WebViewActivity extends BaseActivity { } } - /** - * android调用js:传送识别语音内容 - * */ - public void voiceContent(String msg){ - if(binding.web!=null){ - binding.web.loadUrl(StringUtil.strSplice("javascript:voiceContent("+ msg +");")); - LoggerUtil.e(TAG,"android调用js方法:voiceContent(),语音内容:"+msg); - } - } - - /** - * android调用js 传送接口请求数据 - * */ - public void getHandWriting(String msg){ - if(binding.web!=null){ - binding.web.loadUrl(StringUtil.strSplice("javascript:handWriting("+ msg +");")); -// LoggerUtil.e(TAG,"android调用js方法:getHandWriting(),接口请求数据:"+msg); - } - } - - /** - * 初始化监听器。 - */ - private InitListener mInitListener = new InitListener() { - - @Override - public void onInit(int code) { - - LoggerUtil.e(TAG, "语音初始化"+"SpeechRecognizer init() code = " + code); - if (code == ErrorCode.SUCCESS) { - mIat.setParameter(SpeechConstant.CLOUD_GRAMMAR, null); //设置语法ID和 SUBJECT 为空,以免因之前有语法调用而设置了此参数;或直接清空所有参数,具体可参考 DEMO 的示例。 - mIat.setParameter(SpeechConstant.SUBJECT, null); - mIat.setParameter(SpeechConstant.RESULT_TYPE, "plain"); //设置返回结果格式,目前支持json,xml以及plain 三种格式,其中plain为纯听写文本内容 - mIat.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD); //此处engineType为“cloud” - mIat.setParameter(SpeechConstant.LANGUAGE, "zh_cn"); //设置语音输入语言,zh_cn为简体中文 -// mIat.setParameter(SpeechConstant.LANGUAGE, "en_us"); //设置语音输入语言,zh_cn为简体中文 - mIat.setParameter(SpeechConstant.ACCENT, "mandarin"); //设置结果返回语言 - mIat.setParameter(SpeechConstant.VAD_BOS, "4000"); //取值范围{1000~10000} 设置语音前端点:静音超时时间,单位ms,即用户多长时间不说话则当做超时处理 - mIat.setParameter(SpeechConstant.VAD_EOS, "1000"); //自动停止录音,范围{0~10000} 设置语音后端点:后端点静音检测时间,单位ms,即用户停止说话多长时间内即认为不再输入, - mIat.setParameter(SpeechConstant.ASR_PTT, "0"); //设置标点符号,设置为"0"返回结果无标点,设置为"1"返回结果有标点 - } - } - }; - - /** - * 听写监听器。 - */ - private RecognizerListener mRecognizerListener = new RecognizerListener() { - - @Override - public void onBeginOfSpeech() { - // 此回调表示:sdk内部录音机已经准备好了,用户可以开始语音输入 - Log.e(TAG,"开始说话"); - vocMsg=""; - } - - @Override - public void onError(SpeechError error) { - // Tips: - // 错误码:10118(您没有说话),可能是录音机权限被禁,需要提示用户打开应用的录音权限。 - LoggerUtil.e(TAG, "onError " + error.getPlainDescription(true)); - Vocbean vocbean = new Vocbean(); - vocbean.setCode(error.getErrorCode()+""); - vocbean.setMsg(""); - vocMsg=new Gson().toJson(vocbean); - voiceContent(vocMsg); - } - - @Override - public void onEndOfSpeech() { - // 此回调表示:检测到了语音的尾端点,已经进入识别过程,不再接受语音输入 - LoggerUtil.e(TAG,"结束说话"); - } - - @Override - public void onResult(RecognizerResult results, boolean isLast) { - Log.e(TAG, results.getResultString()); - - if(!results.getResultString().isEmpty()){ - Vocbean vocbean = new Vocbean(); - vocbean.setCode("200"); - vocbean.setMsg(results.getResultString()); - vocMsg= new Gson().toJson(vocbean); - voiceContent(vocMsg); - } - if (isLast) { - Log.d(TAG, "onResult 结束"); - } - - } - - @Override - public void onVolumeChanged(int volume, byte[] data) { -// Log.e(TAG,"当前正在说话,音量大小 = " + volume + " 返回音频数据 = " + data.length); - } - - @Override - public void onEvent(int eventType, int arg1, int arg2, Bundle obj) { - // 以下代码用于获取与云端的会话id,当业务出错时将会话id提供给技术支持人员,可用于查询会话日志,定位出错原因 - // 若使用本地能力,会话id为null - // if (SpeechEvent.EVENT_SESSION_ID == eventType) { - // String sid = obj.getString(SpeechEvent.KEY_EVENT_SESSION_ID); - // Log.d(TAG, "session id =" + sid); - // } - } - }; - - /** - * 调用手臂方法 - * */ - public void getMoveArm(String name){ - int masterArm = H5Data.getKdxf().getData().getControlInfo().getMasterArm();//机械臂编号1、2、3 - SmUtils instance = SmUtils.getInstance(); - instance.getTargets("00:00:00:00:00:00", masterArm, new IHttp() { - @Override - public void onHttpResponse(int i, Object o) { - //获取到表单 -// Log.e("TAG","极点:"+ GsonUtil.getGson().toJson(o)); - List targetList = (List)o; - for(int x=0;x { + // 准备完成后才能播放 + mp.start(); + }); + + // 监听错误状态 + mediaPlayer.setOnErrorListener((mp, what, extra) -> { + LoggerUtil.e("MediaPlayer", "Error: " + what + ", " + extra); + // 出错后释放资源 + mp.release(); + mediaPlayer = null; + return true; + }); + + } catch (IOException e) { + e.printStackTrace(); + // 处理文件读取错误(如路径无效、权限不足) + } + } + + public static void stopPlay(){ + if(mediaPlayer != null){ + mediaPlayer.stop(); + mediaPlayer.release(); + mediaPlayer = null; + } + + } + + +} diff --git a/app/src/main/java/qianmu/container/util/FileUtil.java b/app/src/main/java/qianmu/container/util/FileUtil.java index 8e733d4..bbe0402 100644 --- a/app/src/main/java/qianmu/container/util/FileUtil.java +++ b/app/src/main/java/qianmu/container/util/FileUtil.java @@ -92,12 +92,6 @@ public class FileUtil { @Override public void onError(Response response) { super.onError(response); - try{ - downloadSuccess(response, tempFilePath); - }catch (Exception e){ - if (finishListener != null) finishListener.onFinish(); - } - if (finishListener != null) finishListener.onFinish(); } @Override @@ -149,18 +143,13 @@ public class FileUtil { public void onError(Response response) { super.onError(response); LoggerUtil.e("素材下载失败", "文件:"+tempFilePath+","+response.message()); - try{ - downloadSuccess(response, tempFilePath); - }catch (Exception e){ - if (finishListener != null) finishListener.onFinish(); - } - if (finishListener != null) finishListener.onFinish(); } @Override public void onFinish() { super.onFinish(); downloadFiles.remove(targetPath); + } }); } catch (Throwable t) { @@ -193,7 +182,7 @@ public class FileUtil { } File targetFile = new File(targetPath); tempFile.renameTo(targetFile); - } else{ + } else if (Integer.valueOf(tempFileLength) > Integer.valueOf(fileTotalLength) || tempFile.length()==0) { Log.e("下载失败", localPath); //本地文件大于待下载文件时 表示断点下载异常 删除已下载文件 tempFile.delete(); diff --git a/app/src/main/java/qianmu/container/util/SignWayUtil.java b/app/src/main/java/qianmu/container/util/SignWayUtil.java index 3583ede..36bbd3f 100644 --- a/app/src/main/java/qianmu/container/util/SignWayUtil.java +++ b/app/src/main/java/qianmu/container/util/SignWayUtil.java @@ -131,7 +131,6 @@ public class SignWayUtil { LoggerUtil.e("SignwayUtil", "app安装结果:"+msg); } }); - }else if(Constant.androidBoardType.equals("sx")){ Intent intent = new Intent("android.intent.action.apkinstall"); intent.putExtra("path",path); @@ -140,6 +139,7 @@ public class SignWayUtil { }else if(Constant.androidBoardType.equals("zc")){ zcapi zcApi=new zcapi(); zcApi.getContext(MyApplication.getInstance()); + LoggerUtil.e("appInstall: ",path); zcApi.InstallApk(path,true); }else if(Constant.androidBoardType.equals("nova")){ MessageEvent messageEvent = new MessageEvent(Constant.NOVA_UPDATE_APP); diff --git a/app/src/main/java/qianmu/container/util/TTSUtil.java b/app/src/main/java/qianmu/container/util/TTSUtil.java new file mode 100644 index 0000000..3b32abd --- /dev/null +++ b/app/src/main/java/qianmu/container/util/TTSUtil.java @@ -0,0 +1,117 @@ +package qianmu.container.util; + +import com.google.gson.Gson; + +import org.greenrobot.eventbus.EventBus; +import org.java_websocket.drafts.Draft_6455; +import org.java_websocket.enums.ReadyState; + +import java.net.URI; + +import qianmu.container.entity.TTSMessage; +import qianmu.container.socket.SocketClient; + +/** + * 思必驰 语音调用 + */ +public class TTSUtil { + + private static SocketClient localSocketClient; + + + private static void initLocalSocketClient() { + try { + URI localUri = new URI("ws://127.0.0.1:50002"); + LoggerUtil.e("TTSSocketUri", localUri.toString()); + localSocketClient = new SocketClient(localUri, new Draft_6455()); + setLocalSocketListener(); + } catch (Throwable t) { + LoggerUtil.e("initSocketClient", StringUtil.getThrowableStr(t)); + } + } + + public static void connectLocalSocket() { + try { + //客户端不存在时 创建客户端设置监听事件 + if (localSocketClient == null) initLocalSocketClient(); + //获取客户端当前的连接状态 + ReadyState state = localSocketClient.getReadyState(); + LoggerUtil.e("connectLocalSocket", "TTS客户端连接状态:"+ GsonUtil.getGson().toJson(state)); + boolean open = localSocketClient.isOpen(); + LoggerUtil.e("connectLocalSocket", "TTS客户端连接状态:open="+open); + if (open) return; + //获取客户端当前的连接状态 + if (localSocketClient.isOpen()) return; + //未连接状态时 连接服务器 + if (state.equals(ReadyState.NOT_YET_CONNECTED)) localSocketClient.connect(); + else if (state.equals(ReadyState.CLOSING) || state.equals(ReadyState.CLOSED)) { + //正在关闭或者关闭状态时 重新连接服务器 + localSocketClient.reconnect(); + } + } catch (Throwable t) { + LoggerUtil.e("connectLocalSocket", StringUtil.getThrowableStr(t)); + destroyLocalSocketClient(); + } + } + // 识别语音 + public static void startAsr(){ + localSocketClient.send(StringUtil.strSplice("{\"method\":\"/asr/start\"}")); + } + // 停止语音识别 + public static void stopAsr(){ + localSocketClient.send(StringUtil.strSplice("{\"method\":\"/asr/stop\"}")); + } + // 开始语音合成 + public static void startTts(String txt){ + localSocketClient.send(StringUtil.strSplice("{\"method\": \"/tts/start\",\"params\": {\"text\":\"", txt, "\", \"mode\":\"autoPlay\"}}")); + } + // 停止语音合成 + public static void stopTts(){ + localSocketClient.send(StringUtil.strSplice("{\"method\":\"/tts/stop\"}")); + AudioPlay.stopPlay(); + } + + private static void setLocalSocketListener() { + localSocketClient.setOnOpenListener((handshakeData) -> { + LoggerUtil.e("connectLocalSocket", "TTS客户端连接成功"); + localSocketClient.send(StringUtil.strSplice("{\"id\":123,\"method\":\"/asr/stop\"}")); + }); + + localSocketClient.setOnMessageListener((conn, message) -> { + try { + TTSMessage messageBean = new Gson().fromJson(message, TTSMessage.class); + TTSMessage.Params content = messageBean.getParams(); + if (content == null) return; + LoggerUtil.e("ttsSocket:", messageBean.getMethod()); + if("asr.text".equals(messageBean.getMethod())){ + LoggerUtil.e("ttsSocket:",content.getText()); + } + if("asr.result".equals(messageBean.getMethod())){ + LoggerUtil.e("ttsSocket:",content.getText()); + } + if("tts.result".equals(messageBean.getMethod())){ + LoggerUtil.e("ttsSocket:",content.getSpeakUrl()); + } + } catch (Throwable t) { + LoggerUtil.e("setOnMessageListener", StringUtil.getThrowableStr(t)); + } + }); + + localSocketClient.setOnCloseListener((code, reason, remote) -> { + LoggerUtil.e("LocSocCliManager", "onClose:code="+code); + if (localSocketClient == null){ + initLocalSocketClient(); + }else { + localSocketClient.reconnect(); + } + }); + localSocketClient.setOnErrorListener((ex) -> LoggerUtil.e("LocSocCliManager", "onError")); + } + + //销毁当前的客户端 + public static void destroyLocalSocketClient() { + if (localSocketClient == null) return; + localSocketClient.close(); + localSocketClient = null; + } +} diff --git a/app/src/main/res/drawable/bg.mp4 b/app/src/main/res/drawable/bg.mp4 new file mode 100644 index 0000000..a428363 Binary files /dev/null and b/app/src/main/res/drawable/bg.mp4 differ diff --git a/app/src/main/res/drawable/hello.mp4 b/app/src/main/res/drawable/hello.mp4 new file mode 100644 index 0000000..a2d0417 Binary files /dev/null and b/app/src/main/res/drawable/hello.mp4 differ diff --git a/app/src/main/res/drawable/speek.mp4 b/app/src/main/res/drawable/speek.mp4 new file mode 100644 index 0000000..956086b Binary files /dev/null and b/app/src/main/res/drawable/speek.mp4 differ diff --git a/app/src/main/res/layout/activity_test.xml b/app/src/main/res/layout/activity_test.xml new file mode 100644 index 0000000..baf924f --- /dev/null +++ b/app/src/main/res/layout/activity_test.xml @@ -0,0 +1,37 @@ + + + + +