Browse Source

fix: ci

sibichiAi
高志龙 9 months ago
parent
commit
a4026ec295
  1. 20
      app/build.gradle
  2. BIN
      app/libs/AndroidScreenCap.jar
  3. BIN
      app/libs/zckjAPI-2.6.jar
  4. BIN
      app/release/app-release.apk
  5. BIN
      app/release/app_andorid_V2_卓策iot分屏容器_V2.0.7.30.apk
  6. BIN
      app/release/app_andorid_V2_卓策iot分屏容器_V2.0.7.31.apk
  7. BIN
      app/release/app_andorid_V2_卓策iot分屏容器_V2.0.8.0.apk
  8. 2
      app/release/output-metadata.json
  9. 93
      app/src/main/AndroidManifest.xml
  10. 498
      app/src/main/java/qianmu/container/activity/H5/WebViewActivity.java
  11. 78
      app/src/main/java/qianmu/container/activity/TestActivity.java
  12. 1
      app/src/main/java/qianmu/container/activity/program/ViewScreenSaver.java
  13. 6
      app/src/main/java/qianmu/container/app/Constant.java
  14. 50
      app/src/main/java/qianmu/container/app/MyApplication.java
  15. 52
      app/src/main/java/qianmu/container/entity/TTSMessage.java
  16. 60
      app/src/main/java/qianmu/container/util/AudioPlay.java
  17. 15
      app/src/main/java/qianmu/container/util/FileUtil.java
  18. 2
      app/src/main/java/qianmu/container/util/SignWayUtil.java
  19. 117
      app/src/main/java/qianmu/container/util/TTSUtil.java
  20. BIN
      app/src/main/res/drawable/bg.mp4
  21. BIN
      app/src/main/res/drawable/hello.mp4
  22. BIN
      app/src/main/res/drawable/speek.mp4
  23. 37
      app/src/main/res/layout/activity_test.xml
  24. 20
      app/src/main/res/layout/activity_webview.xml
  25. BIN
      app/src/main/res/raw/bg.mp4
  26. BIN
      app/src/main/res/raw/hello.mp4
  27. BIN
      app/src/main/res/raw/speek.mp4

20
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'

BIN
app/libs/AndroidScreenCap.jar

Binary file not shown.

BIN
app/libs/zckjAPI-2.6.jar

Binary file not shown.

BIN
app/release/app-release.apk

Binary file not shown.

BIN
app/release/app_andorid_V2_卓策iot分屏容器_V2.0.7.30.apk

Binary file not shown.

BIN
app/release/app_andorid_V2_亿晟3576iot分屏容器_V2.0.7.30.apk → app/release/app_andorid_V2_卓策iot分屏容器_V2.0.7.31.apk

Binary file not shown.

BIN
app/release/app_andorid_V2_卓策iot分屏容器_V2.0.8.0.apk

Binary file not shown.

2
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"
}
]

93
app/src/main/AndroidManifest.xml

@ -2,51 +2,36 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="qianmu.container">
<!--显示系统窗口 显示系统窗口-->
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<!--录音 录制声音通过手机或耳机的麦克-->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<!--开机自动允许 允许程序开机自动运行-->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<!--改变WiFi状态 改变WiFi状态-->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<!--获取WiFi状态 获取当前WiFi接入的状态以及WLAN热点的信息-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!--唤醒锁定 允许程序在手机屏幕关闭后后台进程仍然运行-->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!--写入外部存储 允许程序写入外部存储,如SD卡上写文件-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!--读取外部存储 允许程序读取外部存储,如SD卡上读文件-->
<!-- 显示系统窗口 显示系统窗口 -->
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <!-- 录音 录制声音通过手机或耳机的麦克 -->
<uses-permission android:name="android.permission.RECORD_AUDIO" /> <!-- 开机自动允许 允许程序开机自动运行 -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <!-- 改变WiFi状态 改变WiFi状态 -->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <!-- 获取WiFi状态 获取当前WiFi接入的状态以及WLAN热点的信息 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <!-- 唤醒锁定 允许程序在手机屏幕关闭后后台进程仍然运行 -->
<uses-permission android:name="android.permission.WAKE_LOCK" /> <!-- 写入外部存储 允许程序写入外部存储,如SD卡上写文件 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- 读取外部存储 允许程序读取外部存储,如SD卡上读文件 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INSTALL_PACKAGES"
<uses-permission
android:name="android.permission.INSTALL_PACKAGES"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<!--获取网络状态 获取网络信息状态,如当前的网络连接是否有效-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!--访问网络 访问网络连接,可能产生GPRS流量-->
<uses-permission android:name="android.permission.INTERNET" />
<!---->
<uses-permission android:name="android.hardware.camera.autofocus" />
<!--连续广播 允许一个程序收到广播后快速收到下一个广播-->
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
<!--拍照权限 允许访问摄像头进行拍照-->
<uses-permission android:name="android.permission.CAMERA" />
<!--读取电话状态 访问电话状态-->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!--读取外部存储 允许程序读取外部存储,如SD卡上读文件-->
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<!--获取任务信息 允许程序获取当前或最近运行的应用-->
<uses-permission android:name="android.permission.GET_TASKS" />
<!--对话框权限-->
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" /> <!-- 获取网络状态 获取网络信息状态,如当前的网络连接是否有效 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- 访问网络 访问网络连接,可能产生GPRS流量 -->
<uses-permission android:name="android.permission.INTERNET" /> <!-- -->
<uses-permission android:name="android.hardware.camera.autofocus" /> <!-- 连续广播 允许一个程序收到广播后快速收到下一个广播 -->
<uses-permission android:name="android.permission.BROADCAST_STICKY" /> <!-- 拍照权限 允许访问摄像头进行拍照 -->
<uses-permission android:name="android.permission.CAMERA" /> <!-- 读取电话状态 访问电话状态 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" /> <!-- 读取外部存储 允许程序读取外部存储,如SD卡上读文件 -->
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" /> <!-- 获取任务信息 允许程序获取当前或最近运行的应用 -->
<uses-permission android:name="android.permission.GET_TASKS" /> <!-- 对话框权限 -->
<uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW" />
<uses-permission android:name="android.permission.WRITE_SETTINGS"
<uses-permission
android:name="android.permission.WRITE_SETTINGS"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.SET_TIME_ZONE"
<uses-permission
android:name="android.permission.SET_TIME_ZONE"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.SET_TIME"
<uses-permission
android:name="android.permission.SET_TIME"
tools:ignore="ProtectedPermissions" />
<application
@ -55,10 +40,15 @@
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:largeHeap="true"
android:sharedUserId="android.uid.system"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:networkSecurityConfig="@xml/network_security_config"
android:usesCleartextTraffic="true"
android:theme="@style/AppTheme">
<!-- 测试页面 -->
<activity android:name=".activity.TestActivity">
</activity>
<provider
android:name="androidx.core.content.FileProvider"
@ -77,41 +67,32 @@
android:screenOrientation="nosensor">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".activity.program.ScreenSaverActivity"
android:configChanges="touchscreen|keyboard|keyboardHidden|navigation"
android:launchMode="singleTask"
android:screenOrientation="nosensor" />
<activity
android:name=".activity.device.DeviceInfoActivity"
android:launchMode="singleTask"
android:screenOrientation="nosensor"/>
android:screenOrientation="nosensor" />
<activity
android:name=".activity.H5.WebViewActivity"
android:launchMode="singleTask"
android:screenOrientation="nosensor"/>
android:screenOrientation="nosensor" />
<service android:name=".service.ContainerService" />
<service android:name=".activity.H5.CoreService" />
<service android:name=".service.MusicService"/>
<service android:name=".service.MusicService" />
<service
android:name=".mqtt.MQTTService"
android:enabled="true"
android:exported="true"></service>
android:exported="true" />
<service android:name="org.eclipse.paho.android.service.MqttService" />
<service
android:name=".service.MessengerService"
android:exported="true">
@ -124,7 +105,6 @@
<intent-filter android:priority="1000">
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MEDIA_MOUNTED" />
<action android:name="android.intent.action.MEDIA_UNMOUNTED" />
@ -132,7 +112,6 @@
<data android:scheme="file" />
</intent-filter>
</receiver>
</application>

498
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<TargetVo> targetList = (List<TargetVo>)o;
for(int x=0;x<targetList.size();x++){
if(targetList.get(x).getTargetName().equals(name)){
//调用机械
instance.moveArm("00:00:00:00:00:00", masterArm, targetList.get(x).getXmlName(),
Integer.parseInt(targetList.get(x).getAngele()), targetList.get(x).getArmOne(), targetList.get(x).getArmInfo(), targetList.get(x).getDistance()+"m", 30, new IHttp() {
@Override
public void onHttpResponse(int i, Object o) {
}
@Override
public void onHttpError(int i, String s) {
}
});
continue;
}
}
}
@Override
public void onHttpError(int i, String s) {
Log.e("TAG","极点:"+s);
}
});
}
@Override
public void onMessageEvent(MessageEvent message) {
super.onMessageEvent(message);
@ -667,4 +532,45 @@ public class WebViewActivity extends BaseActivity {
break;
}
}
private 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 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 void destroyLocalSocketClient() {
if (localSocketClient == null) return;
localSocketClient.close();
localSocketClient = null;
}
}

78
app/src/main/java/qianmu/container/activity/TestActivity.java

@ -0,0 +1,78 @@
package qianmu.container.activity;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import qianmu.container.R;
import qianmu.container.util.TTSUtil;
public class TestActivity extends AppCompatActivity implements View.OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
setPermission();
addEventListener();
TTSUtil.connectLocalSocket();
}
private void addEventListener(){
findViewById(R.id.button).setOnClickListener(this);
findViewById(R.id.button2).setOnClickListener(this);
findViewById(R.id.button3).setOnClickListener(this);
findViewById(R.id.button4).setOnClickListener(this);
}
/**
* 检测权限并授权
* */
private void setPermission(){
if(ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this,new String[]{
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.ACCESS_NETWORK_STATE,
Manifest.permission.CAMERA,
Manifest.permission.RECORD_AUDIO,
Manifest.permission.RECEIVE_BOOT_COMPLETED,
Manifest.permission.SYSTEM_ALERT_WINDOW,
Manifest.permission.READ_PHONE_STATE,
Manifest.permission.ACCESS_NETWORK_STATE},998);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(requestCode==998){
}
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.button :
TTSUtil.startAsr();
break;
case R.id.button2 :
TTSUtil.stopAsr();
break;
case R.id.button3 :
TTSUtil.startTts("天有不测风云,人有旦夕祸福。蜈蚣百足,行不及蛇;雄鸡两翼,飞不过鸦。");
break;
case R.id.button4 :
TTSUtil.stopTts();
break;
}
}
}

1
app/src/main/java/qianmu/container/activity/program/ViewScreenSaver.java

@ -45,7 +45,6 @@ import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import org.greenrobot.eventbus.EventBus;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.FileNotFoundException;

6
app/src/main/java/qianmu/container/app/Constant.java

@ -22,16 +22,16 @@ public class Constant {
public static String screenType = "HDMI"; // 欣威视通3399设备为假关机 HDMI连接:可以用来判断是否为关机状态 LVDS连接:只能用定时关机时间来判断
public static boolean newGuide = false; // 指路机类型,true:新版指路机 false:老板指路机(流花)
public static String mqttState = ""; // 屏幕连接方式
public static String androidBoardType = ""; //设备板子型号 无固定版
// public static String androidBoardType = ""; //设备板子型号 无固定版
// public static String androidBoardType = "ys"; // 设备板子型号 ys(亿晟) 北京颐堤港定制touch
// public static String androidBoardType = "xwst"; //设备板子型号 xwst(欣威视通3399)
// public static String androidBoardType = "xwst2"; //设备板子型号 xwst2(欣威视通3588、T982、3576)
// public static String androidBoardType = "zc"; //设备板子型号 zc(卓策主板——王府井喜悦、杨浦中心医院)
// public static String androidBoardType = "zc"; //设备板子型号 zc(卓策主板——王府井喜悦、杨浦中心医院)
// public static String androidBoardType = "sx"; //设备板子型号 sx(视想)
// public static String androidBoardType = "nova"; //设备板子型号 诺瓦盒子 华贸LED
// public static String androidBoardType = "huidu"; //设备板子型号 huidu(灰度主板) 罗湖寻车机
// public static String androidBoardType = "bv"; //设备板子型号 Bv-3588M
// public static String androidBoardType = "smt"; //设备板子型号 视美泰
public static String androidBoardType = "smt"; //设备板子型号 视美泰
public static String whoActivity = ""; // 哪个activity页面
// 本地缓存地址

50
app/src/main/java/qianmu/container/app/MyApplication.java

@ -16,6 +16,7 @@ import com.lzy.okgo.OkGo;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.security.KeyStore;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;
@ -117,20 +118,7 @@ public class MyApplication extends Application {
private void initOkGo() {
try {
int currentApiVersion = android.os.Build.VERSION.SDK_INT;
OkHttpClient client;
if (currentApiVersion <= 32) {
// 当前系统版本是Android 12
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.readTimeout(5, TimeUnit.SECONDS);
builder.writeTimeout(5, TimeUnit.SECONDS);
builder.connectTimeout(5, TimeUnit.SECONDS);
builder.sslSocketFactory(SSLSocketClient.getSSLSocketFactory());// 过滤https证书
builder.hostnameVerifier(SSLSocketClient.getHostnameVerifier());
client = builder.build();
} else {
// 当前系统版本是Android 14
client = createOkHttpClient(this);
}
OkHttpClient client = createOkHttpClient(this);
OkGo.getInstance().init(this).setOkHttpClient(client).setRetryCount(0);
} catch (Throwable t) {
LoggerUtil.e("initOkGo", StringUtil.getThrowableStr(t));
@ -139,30 +127,26 @@ public class MyApplication extends Application {
public OkHttpClient createOkHttpClient(Context context) {
try {
// 1. 创建信任管理器(这里示例为信任所有证书,生产环境需谨慎)
X509TrustManager trustManager = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
};
// 2. 初始化 SSLContext
// 获取系统默认信任管理器
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init((KeyStore) null);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
X509TrustManager trustManager = (X509TrustManager) trustManagers[0];
// 初始化 SSL 上下文
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[]{trustManager}, null);
// 3. 用自定义的 SSLContext 创建 SSLSocketFactory
javax.net.ssl.SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
// 4. 配置 OkHttpClient
// 构建 OkHttpClient(3.x 版本同样需要显式传入 trustManager)
return new OkHttpClient.Builder()
.sslSocketFactory(sslSocketFactory, trustManager) // 同时传入 TrustManager
.sslSocketFactory(sslContext.getSocketFactory(), trustManager) // 关键
.connectTimeout(15, TimeUnit.SECONDS)
.readTimeout(15, TimeUnit.SECONDS)
.writeTimeout(15, TimeUnit.SECONDS)
.build();
} catch (Exception e) {
throw new RuntimeException(e);
throw new RuntimeException("OkHttp 初始化失败", e);
}
}

52
app/src/main/java/qianmu/container/entity/TTSMessage.java

@ -0,0 +1,52 @@
package qianmu.container.entity;
public class TTSMessage {
String jsonrpc;
String method;
Params params;
public String getJsonrpc() {
return jsonrpc;
}
public void setJsonrpc(String jsonrpc) {
this.jsonrpc = jsonrpc;
}
public String getMethod() {
return method;
}
public void setMethod(String method) {
this.method = method;
}
public Params getParams() {
return params;
}
public void setParams(Params params) {
this.params = params;
}
public static class Params {
String text;
String speakUrl;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getSpeakUrl() {
return speakUrl;
}
public void setSpeakUrl(String speakUrl) {
this.speakUrl = speakUrl;
}
}
}

60
app/src/main/java/qianmu/container/util/AudioPlay.java

@ -0,0 +1,60 @@
package qianmu.container.util;
import android.media.AudioAttributes;
import android.media.MediaPlayer;
import java.io.IOException;
public class AudioPlay {
private static volatile MediaPlayer mediaPlayer;
public static void startPlay(String url){
if (mediaPlayer != null) {
mediaPlayer.release();
mediaPlayer = null;
}
try {
mediaPlayer = new MediaPlayer();
// 设置音频属性(需在 setDataSource 前调用)
AudioAttributes attributes = new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.setUsage(AudioAttributes.USAGE_MEDIA)
.build();
mediaPlayer.setAudioAttributes(attributes);
// 设置数据源(确保路径正确,且有读取权限)
mediaPlayer.setDataSource(url);
// 异步准备(避免阻塞主线程)
mediaPlayer.prepareAsync();
mediaPlayer.setVolume(1.0f, 1.0f);
mediaPlayer.setOnPreparedListener(mp -> {
// 准备完成后才能播放
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;
}
}
}

15
app/src/main/java/qianmu/container/util/FileUtil.java

@ -92,12 +92,6 @@ public class FileUtil {
@Override
public void onError(Response<File> 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<File> 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();

2
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);

117
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;
}
}

BIN
app/src/main/res/drawable/bg.mp4

Binary file not shown.

BIN
app/src/main/res/drawable/hello.mp4

Binary file not shown.

BIN
app/src/main/res/drawable/speek.mp4

Binary file not shown.

37
app/src/main/res/layout/activity_test.xml

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activity.TestActivity"
android:orientation="vertical">
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="@dimen/aspect_btn_height"
android:layout_weight="1"
android:text="开始语音识别" />
<Button
android:id="@+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="停止语音识别" />
<Button
android:id="@+id/button3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="播放语音合成" />
<Button
android:id="@+id/button4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="停止语音合成" />
</LinearLayout>

20
app/src/main/res/layout/activity_webview.xml

@ -6,11 +6,31 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout android:layout_height="match_parent"
android:layout_width="match_parent" >
<VideoView
android:id="@+id/bgVideo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="visible"
/>
<VideoView
android:id="@+id/helloVideo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"/>
<VideoView
android:id="@+id/speekVideo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"/>
</RelativeLayout>
<WebView
android:id="@+id/web"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent"
/>
<ImageView

BIN
app/src/main/res/raw/bg.mp4

Binary file not shown.

BIN
app/src/main/res/raw/hello.mp4

Binary file not shown.

BIN
app/src/main/res/raw/speek.mp4

Binary file not shown.
Loading…
Cancel
Save