Browse Source

fix: WebViewActivity 优化

master
高志龙 2 weeks ago
parent
commit
7b84118ee3
  1. 2
      app/build.gradle
  2. 4
      app/src/main/java/qianmu/container/activity/BaseActivity.java
  3. 309
      app/src/main/java/qianmu/container/activity/H5/WebViewActivity.java
  4. 2
      app/src/main/java/qianmu/container/app/Constant.java
  5. 11
      app/src/main/java/qianmu/container/data/PowerData.java
  6. 14
      app/src/main/java/qianmu/container/handler/ContainerHandler.java
  7. 14
      app/src/main/java/qianmu/container/mqtt/MQTTService.java
  8. 2
      app/src/main/java/qianmu/container/util/TTSUtil.java
  9. 4
      app/src/main/res/layout/activity_webview.xml

2
app/build.gradle

@ -12,7 +12,7 @@ android {
minSdkVersion 24 minSdkVersion 24
targetSdkVersion 30 targetSdkVersion 30
versionCode 6 versionCode 6
versionName "V2.0.8.28"
versionName "V2.0.8.27"
// 2.0.8.2 // 2.0.8.2
// 2.0.8.3 mac修改 // 2.0.8.3 mac修改
// V2.0.8.5 // V2.0.8.5

4
app/src/main/java/qianmu/container/activity/BaseActivity.java

@ -128,7 +128,7 @@ public abstract class BaseActivity extends AppCompatActivity {
if (Constant.ACTION_CAPTURE_SCREEN.equals(message.getCode())) { if (Constant.ACTION_CAPTURE_SCREEN.equals(message.getCode())) {
uploadScreenCapture(); uploadScreenCapture();
} else if (Constant.ACTION_SHOW_SPLASH.equals(message.getCode())) { } else if (Constant.ACTION_SHOW_SPLASH.equals(message.getCode())) {
if (currRoute == Constant.ROUTE_SCREEN_SAVER)
if (Constant.ROUTE_SCREEN_SAVER.equals(currRoute))
return; return;
ScreenSaverActivity.startAction(this); ScreenSaverActivity.startAction(this);
// ARouter.getInstance().build(Constant.ROUTE_SCREEN_SAVER).navigation(); // ARouter.getInstance().build(Constant.ROUTE_SCREEN_SAVER).navigation();
@ -142,7 +142,7 @@ public abstract class BaseActivity extends AppCompatActivity {
if (DeviceData.getDeviceInfo(DeviceData.HINT_DEVICE_TYPE).equals("信发") if (DeviceData.getDeviceInfo(DeviceData.HINT_DEVICE_TYPE).equals("信发")
|| DeviceData.getDeviceInfo(DeviceData.HINT_DEVICE_TYPE).equals("双面屏")) || DeviceData.getDeviceInfo(DeviceData.HINT_DEVICE_TYPE).equals("双面屏"))
return; return;
if (currRoute == Constant.ROUTE_WEB_VIEW || currRoute == Constant.ROUTE_UPDATE_FILE)
if (Constant.ROUTE_WEB_VIEW.equals(currRoute) || Constant.ROUTE_UPDATE_FILE.equals(currRoute))
return; return;
ARouter.getInstance().build(Constant.ROUTE_WEB_VIEW).withBoolean(Constant.KEY_LOAD_H5_URL, true) ARouter.getInstance().build(Constant.ROUTE_WEB_VIEW).withBoolean(Constant.KEY_LOAD_H5_URL, true)
.navigation(); .navigation();

309
app/src/main/java/qianmu/container/activity/H5/WebViewActivity.java

@ -28,12 +28,14 @@ import android.webkit.WebChromeClient;
import android.webkit.WebResourceRequest; import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse; import android.webkit.WebResourceResponse;
import android.webkit.WebSettings; import android.webkit.WebSettings;
import android.webkit.RenderProcessGoneDetail;
import android.webkit.WebView; import android.webkit.WebView;
import android.webkit.WebViewClient; import android.webkit.WebViewClient;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.VideoView; import android.widget.VideoView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.databinding.DataBindingUtil; import androidx.databinding.DataBindingUtil;
import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.GridLayoutManager;
import com.aispeech.AIError; import com.aispeech.AIError;
@ -49,6 +51,7 @@ import com.alibaba.android.arouter.launcher.ARouter;
import com.iflytek.sparkchain.core.asr.ASR; import com.iflytek.sparkchain.core.asr.ASR;
import com.iflytek.sparkchain.core.asr.AsrCallbacks; import com.iflytek.sparkchain.core.asr.AsrCallbacks;
import com.jakewharton.processphoenix.ProcessPhoenix;
import com.shockman.sm.vendor.IHttp; import com.shockman.sm.vendor.IHttp;
import com.shockman.sm.vendor.SmUtils; import com.shockman.sm.vendor.SmUtils;
import com.shockman.sm.vendor.TargetVo; import com.shockman.sm.vendor.TargetVo;
@ -74,6 +77,7 @@ import java.util.regex.Pattern;
import qianmu.container.R; import qianmu.container.R;
import qianmu.container.activity.BaseActivity; import qianmu.container.activity.BaseActivity;
import qianmu.container.activity.program.ScreenSaverActivity;
import qianmu.container.adapter.KeyAdapter; import qianmu.container.adapter.KeyAdapter;
import qianmu.container.app.Constant; import qianmu.container.app.Constant;
import qianmu.container.app.MyApplication; import qianmu.container.app.MyApplication;
@ -117,6 +121,9 @@ public class WebViewActivity extends BaseActivity {
//static String HtmlUrl = "https://iot.1000my.com/api/application-unzip-path/v1/static/77b853bf-a43a-47ba-bc0c-0160229b6ca2/index.html?projectCode=project-ce-k6xi8vq_deqrszdepga&code=Sn9tXh8jMLd4GjfiVdInl#/"; //static String HtmlUrl = "https://iot.1000my.com/api/application-unzip-path/v1/static/77b853bf-a43a-47ba-bc0c-0160229b6ca2/index.html?projectCode=project-ce-k6xi8vq_deqrszdepga&code=Sn9tXh8jMLd4GjfiVdInl#/";
int time = 0; int time = 0;
String interfaceRequestData=""; String interfaceRequestData="";
private long resumeTimeMs = 0;
private static final long GO_SCREEN_SAVE_MIN_INTERVAL = 10000; // 页面加载后至少10秒才允许进入屏保
private boolean webViewAlreadyDestroyed = false;
// 语音听写对象 // 语音听写对象
private AICloudASREngine mEngine; private AICloudASREngine mEngine;
private AICloudASRIntent aiCloudASRIntent; private AICloudASRIntent aiCloudASRIntent;
@ -130,6 +137,12 @@ public class WebViewActivity extends BaseActivity {
private final InnerHandler handler = new InnerHandler(this); private final InnerHandler handler = new InnerHandler(this);
// 当前 WebView 实例。刷新时会被销毁并替换为新实例,不能直接用 binding.web
private WebView webView;
// 节流:避免 CoreService 抖动反复触发 WebView 重建
private long lastRefurbishTime = 0;
private static final long REFURBISH_THROTTLE_MS = 30000L; // 30秒内只允许重建一次
private static class InnerHandler extends Handler { private static class InnerHandler extends Handler {
private final WeakReference<WebViewActivity> ref; private final WeakReference<WebViewActivity> ref;
@ -143,23 +156,18 @@ public class WebViewActivity extends BaseActivity {
if (activity == null) return; if (activity == null) return;
switch (msg.what) { switch (msg.what) {
case TYPE_REFURBISH_WEBVIEW: case TYPE_REFURBISH_WEBVIEW:
try {
activity.binding.web.clearCache(true);
activity.binding.web.loadUrl(HtmlUrl);
Constant.isCoreService = true;
} catch (Exception e) {
}
activity.refurbishWebView();
break; break;
case TYPE_GO_SAVESCREEN: case TYPE_GO_SAVESCREEN:
try { try {
if (System.currentTimeMillis() - activity.resumeTimeMs < GO_SCREEN_SAVE_MIN_INTERVAL) {
LoggerUtil.e("WebViewActivity", "goScreenSave 忽略:页面加载后触发过早");
return;
}
initFirstTime(); initFirstTime();
if (!ScreenSaverData.isProgramPlay()) return; if (!ScreenSaverData.isProgramPlay()) return;
if (AppData.getFrontApp().equals(DeviceUtil.getPackageName())) {
EventBus.getDefault().post(new MessageEvent(Constant.ACTION_SHOW_SPLASH));
} else {
ARouter.getInstance().build(Constant.ROUTE_SCREEN_SAVER).navigation();
}
ScreenSaverActivity.startAction(activity);
} catch (Throwable t) { } catch (Throwable t) {
LoggerUtil.e("WebViewActivity()", "导视通知跳转报错:" + StringUtil.getThrowableStr(t)); LoggerUtil.e("WebViewActivity()", "导视通知跳转报错:" + StringUtil.getThrowableStr(t));
} }
@ -175,10 +183,16 @@ public class WebViewActivity extends BaseActivity {
break; break;
case TYPE_START_SERVER: case TYPE_START_SERVER:
removeMessages(TYPE_REFURBISH_WEBVIEW);
sendEmptyMessageDelayed(TYPE_REFURBISH_WEBVIEW, 2000);
activity.startService(new Intent(activity, CoreService.class)); activity.startService(new Intent(activity, CoreService.class));
LoggerUtil.e("WebViewActivity", "CoreService重启"); LoggerUtil.e("WebViewActivity", "CoreService重启");
long nowMs = System.currentTimeMillis();
if (nowMs - activity.lastRefurbishTime < REFURBISH_THROTTLE_MS) {
LoggerUtil.e("WebViewActivity", "刷新节流:距上次重建不足 " + (REFURBISH_THROTTLE_MS / 1000) + "s,跳过本次");
break;
}
activity.lastRefurbishTime = nowMs;
removeMessages(TYPE_REFURBISH_WEBVIEW);
sendEmptyMessageDelayed(TYPE_REFURBISH_WEBVIEW, 2000);
break; break;
case TYPE_SHENG_HTML_MAG: case TYPE_SHENG_HTML_MAG:
@ -195,6 +209,7 @@ public class WebViewActivity extends BaseActivity {
DeviceUtil.screenType(this); DeviceUtil.screenType(this);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
binding = DataBindingUtil.setContentView(this, R.layout.activity_webview); binding = DataBindingUtil.setContentView(this, R.layout.activity_webview);
webView = binding.web;
//设置密码 //设置密码
initPass(); initPass();
try{ try{
@ -215,7 +230,33 @@ public class WebViewActivity extends BaseActivity {
@Override @Override
protected void setData() { protected void setData() {
Log.e("WebViewActivity", "setData"); Log.e("WebViewActivity", "setData");
WebSettings webSettings = binding.web.getSettings();
setupWebView(webView);
//加载web
currRoute = Constant.ROUTE_WEB_VIEW;
loadH5Url();
}
@Override
protected void setListener() {
binding.setting.setOnClickListener((view) -> {
if (!MyApplication.addClickTimes()) return;
binding.layoutPass.setVisibility(View.VISIBLE);
time = 0;
handler.removeMessages(TYPE_HINT_PASSWORD);
handler.sendEmptyMessage(TYPE_HINT_PASSWORD);
binding.tvPass.setText("");
// ARouter.getInstance().build(Constant.ROUTE_DEVICE_INFO).withBoolean(Constant.INPUT_PASSWORD, true).navigation();
});
}
/**
* 统一配置一个 WebViewsettingsClientJS interface长按等
* 初次创建和刷新重建时复用避免两边逻辑漂移
*/
@SuppressLint("SetJavaScriptEnabled")
private void setupWebView(WebView wv) {
if (wv == null) return;
WebSettings webSettings = wv.getSettings();
webSettings.setJavaScriptEnabled(true); webSettings.setJavaScriptEnabled(true);
webSettings.setUseWideViewPort(true); webSettings.setUseWideViewPort(true);
webSettings.setLoadWithOverviewMode(true); webSettings.setLoadWithOverviewMode(true);
@ -228,65 +269,133 @@ public class WebViewActivity extends BaseActivity {
webSettings.setDatabaseEnabled(true); webSettings.setDatabaseEnabled(true);
webSettings.setAllowContentAccess(true); webSettings.setAllowContentAccess(true);
webSettings.setAllowFileAccess(true); webSettings.setAllowFileAccess(true);
webSettings.setJavaScriptCanOpenWindowsAutomatically(true); webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
webSettings.setLoadsImagesAutomatically(true); webSettings.setLoadsImagesAutomatically(true);
webSettings.setDefaultTextEncodingName("utf-8"); webSettings.setDefaultTextEncodingName("utf-8");
webSettings.setUserAgentString(""); webSettings.setUserAgentString("");
webSettings.setMediaPlaybackRequiresUserGesture(false); // 允许自动播放 webSettings.setMediaPlaybackRequiresUserGesture(false); // 允许自动播放
wv.setBackgroundColor(android.graphics.Color.WHITE);
// 启用硬件加速 // 启用硬件加速
binding.web.setLayerType(View.LAYER_TYPE_HARDWARE, null);
wv.setLayerType(View.LAYER_TYPE_HARDWARE, null);
// 适配HTTPS/HTTP混合内容 // 适配HTTPS/HTTP混合内容
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW); webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
} }
//加载web
currRoute = Constant.ROUTE_WEB_VIEW;
loadH5Url(getIntent().getBooleanExtra(Constant.KEY_LOAD_H5_URL, false));
}
wv.setWebViewClient(new WebViewClient() {
@RequiresApi(api = Build.VERSION_CODES.O)
@Override @Override
protected void setListener() {
public boolean onRenderProcessGone(WebView view, RenderProcessGoneDetail detail) {
LoggerUtil.e("WebViewCrash", "WebView 渲染进程崩溃,OOM被杀: " + !detail.didCrash());
webViewAlreadyDestroyed = true;
try {
if (view != null) {
ViewGroup parent = (ViewGroup) view.getParent();
if (parent != null) parent.removeView(view);
view.stopLoading();
view.loadUrl("about:blank");
view.clearHistory();
view.clearCache(true);
view.removeAllViews();
view.destroy();
}
} catch (Exception e) {
LoggerUtil.e("WebViewCrash", e.toString());
}
ProcessPhoenix.triggerRebirth(WebViewActivity.this);
return true;
}
binding.web.setWebViewClient(new WebViewClient() {
@Override @Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) { public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
// 允许所有资源加载
return super.shouldInterceptRequest(view, request); return super.shouldInterceptRequest(view, request);
} }
@Override @Override
@TargetApi(Build.VERSION_CODES.N) @TargetApi(Build.VERSION_CODES.N)
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
String url = request.getUrl().toString();
view.loadUrl(url);
return true; // 表示已处理,WebView 不执行默认操作
return false;
} }
// 兼容旧版本的回调方法
@Override @Override
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public boolean shouldOverrideUrlLoading(WebView view, String url) { public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
return false;
} }
}); });
binding.web.setOnLongClickListener((View v) -> {
wv.setWebChromeClient(new WebChromeClient() {
public boolean onConsoleMessage(ConsoleMessage cm) {
if (cm.messageLevel() == ConsoleMessage.MessageLevel.ERROR) {
LoggerUtil.e("WebView_ConsoleError", "lineNumber: " + cm.lineNumber());
} else if (cm.message().contains("THREE.WebGLRenderer:") || cm.message().contains("Uncaught (in promise) AbortError")) {
LoggerUtil.e("WebView日志", cm.message());
}
return super.onConsoleMessage(cm);
}
});
wv.setOnLongClickListener((View v) -> {
LoggerUtil.e("OnLongClick", "用户长按了页面"); LoggerUtil.e("OnLongClick", "用户长按了页面");
return false; return false;
}); });
binding.setting.setOnClickListener((view) -> {
if (!MyApplication.addClickTimes()) return;
binding.layoutPass.setVisibility(View.VISIBLE);
time = 0;
handler.removeMessages(TYPE_HINT_PASSWORD);
handler.sendEmptyMessage(TYPE_HINT_PASSWORD);
binding.tvPass.setText("");
// ARouter.getInstance().build(Constant.ROUTE_DEVICE_INFO).withBoolean(Constant.INPUT_PASSWORD, true).navigation();
});
wv.addJavascriptInterface(new AndroidtoJs(), "android");
}
/**
* 真正销毁旧 WebView 并新建一个挂到同一位置释放 WebGL / GPU 资源
* 注意clearCache + loadUrl 不能释放 WebGL 上下文必须 destroy + new
*/
private void refurbishWebView() {
if (webView == null) {
LoggerUtil.e(TAG, "refurbishWebView: webView 为空,跳过");
return;
}
ViewGroup parent = (ViewGroup) webView.getParent();
if (parent == null) {
LoggerUtil.e(TAG, "refurbishWebView: parent 为空,跳过");
return;
}
// 任意路径触发的重建都更新时间戳,统一节流口径
lastRefurbishTime = System.currentTimeMillis();
int index = parent.indexOfChild(webView);
ViewGroup.LayoutParams lp = webView.getLayoutParams();
int viewId = webView.getId();
WebView old = webView;
webView = null;
try {
try { old.removeJavascriptInterface("android"); } catch (Exception ignore) {}
try { old.stopLoading(); } catch (Exception ignore) {}
try { old.loadUrl("about:blank"); } catch (Exception ignore) {}
try { old.clearHistory(); } catch (Exception ignore) {}
try { old.clearCache(true); } catch (Exception ignore) {}
parent.removeView(old);
try { old.removeAllViews(); } catch (Exception ignore) {}
old.destroy(); // ← 这一步才真正释放 GPU/native context
LoggerUtil.e(TAG, "refurbishWebView: 旧 WebView 已销毁");
} catch (Throwable t) {
LoggerUtil.e(TAG, "refurbishWebView: 销毁旧 WebView 失败: " + StringUtil.getThrowableStr(t));
}
try {
WebView fresh = new WebView(this);
if (viewId != View.NO_ID) fresh.setId(viewId);
if (lp != null) {
parent.addView(fresh, index, lp);
} else {
parent.addView(fresh, index);
}
setupWebView(fresh);
webView = fresh;
fresh.clearCache(true);
fresh.loadUrl(HtmlUrl);
Constant.isCoreService = true;
LoggerUtil.e(TAG, "refurbishWebView: 新 WebView 已挂载并加载 " + HtmlUrl);
} catch (Throwable t) {
LoggerUtil.e(TAG, "refurbishWebView: 创建新 WebView 失败: " + StringUtil.getThrowableStr(t));
}
} }
//密码输入框 //密码输入框
@ -335,6 +444,7 @@ public class WebViewActivity extends BaseActivity {
@Override @Override
protected void onResume() { protected void onResume() {
super.onResume(); super.onResume();
resumeTimeMs = System.currentTimeMillis();
leaveScreenSave(); leaveScreenSave();
binding.layoutPass.setVisibility(View.GONE); binding.layoutPass.setVisibility(View.GONE);
//判断web服务是否正常 //判断web服务是否正常
@ -367,38 +477,26 @@ public class WebViewActivity extends BaseActivity {
@Override @Override
protected void onDestroy() { protected void onDestroy() {
LoggerUtil.e(TAG, "onDestroy()"); LoggerUtil.e(TAG, "onDestroy()");
if (binding.web != null) {
binding.web.stopLoading();
binding.web.clearHistory();
binding.web.removeAllViews();
binding.web.destroy();
if (!webViewAlreadyDestroyed && webView != null) {
try { webView.removeJavascriptInterface("android"); } catch (Exception ignore) {}
try { webView.stopLoading(); } catch (Exception ignore) {}
try { webView.loadUrl("about:blank"); } catch (Exception ignore) {}
try { webView.clearHistory(); } catch (Exception ignore) {}
try { webView.clearCache(true); } catch (Exception ignore) {}
ViewGroup parent = (ViewGroup) webView.getParent();
if (parent != null) parent.removeView(webView);
try { webView.removeAllViews(); } catch (Exception ignore) {}
try { webView.destroy(); } catch (Exception ignore) {}
webView = null;
} }
if (handler != null) handler.removeCallbacksAndMessages(null); if (handler != null) handler.removeCallbacksAndMessages(null);
super.onDestroy(); super.onDestroy();
} }
private void loadH5Url(boolean loadUrl) {
if (!loadUrl) return;
String Url;
if(H5Data.getH5Url().isEmpty()){
Url = HtmlUrl;
}else {
Url = H5Data.getH5Url();
}
binding.web.clearCache(true);
binding.web.loadUrl(Url);
binding.web.setWebChromeClient(new WebChromeClient() {
public boolean onConsoleMessage(ConsoleMessage cm) {
if(!cm.message().contains("THREE.WebGLRenderer:") && !cm.message().contains("Uncaught (in promise) AbortError")){
LoggerUtil.e("WebView日志",cm.message());
}
return super.onConsoleMessage(cm);
}
});
binding.web.addJavascriptInterface(new AndroidtoJs(), "android");
private void loadH5Url() {
if (webView == null) return;
webView.clearCache(true);
webView.loadUrl(HtmlUrl);
} }
int count = 0; int count = 0;
public class AndroidtoJs extends Object { public class AndroidtoJs extends Object {
@ -455,6 +553,7 @@ public class WebViewActivity extends BaseActivity {
LoggerUtil.d(TAG, "未初始化"); LoggerUtil.d(TAG, "未初始化");
initASR(); initASR();
} }
if (mEngine == null || aiCloudASRIntent == null) return;
mEngine.start(aiCloudASRIntent); mEngine.start(aiCloudASRIntent);
}else if("kdxf".equals(Constant.TTSHome)){ }else if("kdxf".equals(Constant.TTSHome)){
if(mAsr == null){ if(mAsr == null){
@ -478,8 +577,10 @@ public class WebViewActivity extends BaseActivity {
public void startTTS(String content) { public void startTTS(String content) {
LoggerUtil.e(TAG,"JS调用了Android的方法:startTTS()"); LoggerUtil.e(TAG,"JS调用了Android的方法:startTTS()");
if("sbc".equals(Constant.TTSHome)){ if("sbc".equals(Constant.TTSHome)){
if (ttsUtil == null) return;
ttsUtil.startTTs(content.toLowerCase(Locale.ENGLISH)); ttsUtil.startTTs(content.toLowerCase(Locale.ENGLISH));
}else if("kdxf".equals(Constant.TTSHome)){ }else if("kdxf".equals(Constant.TTSHome)){
if (kxdfttsUtil == null) return;
kxdfttsUtil.startTTs(content); kxdfttsUtil.startTTs(content);
} }
} }
@ -488,8 +589,10 @@ public class WebViewActivity extends BaseActivity {
public void stopTTS() { public void stopTTS() {
LoggerUtil.e(TAG,"JS调用了Android的方法:stopTTS()"); LoggerUtil.e(TAG,"JS调用了Android的方法:stopTTS()");
if("sbc".equals(Constant.TTSHome)){ if("sbc".equals(Constant.TTSHome)){
if (ttsUtil == null) return;
ttsUtil.stopTTs(); ttsUtil.stopTTs();
}else if("kdxf".equals(Constant.TTSHome)){ }else if("kdxf".equals(Constant.TTSHome)){
if (kxdfttsUtil == null) return;
kxdfttsUtil.stopTTs(); kxdfttsUtil.stopTTs();
} }
} }
@ -561,8 +664,8 @@ public class WebViewActivity extends BaseActivity {
* 安卓调用h5方法通知进入导视 * 安卓调用h5方法通知进入导视
* */ * */
public void leaveScreenSave(){ public void leaveScreenSave(){
if(binding.web!=null){
binding.web.loadUrl(StringUtil.strSplice("javascript:leaveScreenSave();"));
if (webView != null) {
webView.loadUrl(StringUtil.strSplice("javascript:leaveScreenSave();"));
} }
} }
@ -570,13 +673,11 @@ public class WebViewActivity extends BaseActivity {
* android调用js传送识别语音内容 * android调用js传送识别语音内容
* */ * */
public void voiceContent(String msg) { public void voiceContent(String msg) {
if (binding.web != null) {
if (webView != null) {
LoggerUtil.e(TAG, "android调用js方法:giveAskText(),语音内容:" + msg); LoggerUtil.e(TAG, "android调用js方法:giveAskText(),语音内容:" + msg);
runOnUiThread(new Runnable() {
@Override
public void run() {
//binding.web.loadUrl(StringUtil.strSplice("javascript:window.voiceContent('{\"data\":\""+msg+"\",\"flag\":0}');"));
binding.web.loadUrl(StringUtil.strSplice("javascript:window.giveAskText('" + msg + "');"));
runOnUiThread(() -> {
if (webView != null) {
webView.loadUrl(StringUtil.strSplice("javascript:window.giveAskText('" + msg + "');"));
} }
}); });
} }
@ -586,8 +687,8 @@ public class WebViewActivity extends BaseActivity {
* android调用js 传送接口请求数据 * android调用js 传送接口请求数据
* */ * */
public void getHandWriting(String msg){ public void getHandWriting(String msg){
if(binding.web!=null){
binding.web.loadUrl(StringUtil.strSplice("javascript:handWriting("+ msg +");"));
if (webView != null) {
webView.loadUrl(StringUtil.strSplice("javascript:handWriting("+ msg +");"));
} }
} }
@ -642,9 +743,9 @@ public class WebViewActivity extends BaseActivity {
}else { }else {
Url = H5Data.getH5Url(); Url = H5Data.getH5Url();
} }
if(binding.web != null && !StringUtil.isEmpty(Url)){
binding.web.clearCache(true);
binding.web.loadUrl(Url);
if (webView != null && !StringUtil.isEmpty(Url)) {
webView.clearCache(true);
webView.loadUrl(Url);
} }
ToastUtils.showToast("应用更新成功"); ToastUtils.showToast("应用更新成功");
break; break;
@ -660,19 +761,13 @@ public class WebViewActivity extends BaseActivity {
} }
break; break;
case Constant.VOID_STOP: case Constant.VOID_STOP:
runOnUiThread(new Runnable() {
@Override
public void run() {
binding.web.evaluateJavascript("javascript: window.setState();", null);
}
runOnUiThread(() -> {
if (webView != null) webView.evaluateJavascript("javascript: window.setState();", null);
}); });
break; break;
case Constant.VOID_ERROR: case Constant.VOID_ERROR:
runOnUiThread(new Runnable() {
@Override
public void run() {
binding.web.evaluateJavascript("javascript: window.micphoneError('网络连接错误');", null);
}
runOnUiThread(() -> {
if (webView != null) webView.evaluateJavascript("javascript: window.micphoneError('网络连接错误');", null);
}); });
break; break;
case Constant.ACTION_UPDATE_PROG2://后台下发节目通知,重置导视倒计时。 case Constant.ACTION_UPDATE_PROG2://后台下发节目通知,重置导视倒计时。
@ -705,12 +800,10 @@ public class WebViewActivity extends BaseActivity {
public void onError(AIError error) { public void onError(AIError error) {
LoggerUtil.e("ASRError: ",error.getMessage()); LoggerUtil.e("ASRError: ",error.getMessage());
// 在非主线程中需要调用 WebView 方法时
runOnUiThread(new Runnable() {
@Override
public void run() {
binding.web.evaluateJavascript("javascript: window.youAskOver('');", null);
binding.web.evaluateJavascript("javascript: window.micphoneError("+error.getMessage()+");", null);
runOnUiThread(() -> {
if (webView != null) {
webView.evaluateJavascript("javascript: window.youAskOver('');", null);
webView.evaluateJavascript("javascript: window.micphoneError(" + error.getMessage() + ");", null);
} }
}); });
stopAsr(); stopAsr();
@ -754,11 +847,8 @@ public class WebViewActivity extends BaseActivity {
public void onEndOfSpeech() { public void onEndOfSpeech() {
//本地vad打开时,才会执行 //本地vad打开时,才会执行
stopAsr(); stopAsr();
runOnUiThread(new Runnable() {
@Override
public void run() {
binding.web.evaluateJavascript("javascript: window.youAskOver('');", null);
}
runOnUiThread(() -> {
if (webView != null) webView.evaluateJavascript("javascript: window.youAskOver('');", null);
}); });
LoggerUtil.e("ASRInit: ","onEndOfSpeech"); LoggerUtil.e("ASRInit: ","onEndOfSpeech");
} }
@ -834,12 +924,8 @@ public class WebViewActivity extends BaseActivity {
} }
@Override @Override
public void onError(ASR.ASRError asrError, Object o) { public void onError(ASR.ASRError asrError, Object o) {
// 在非主线程中需要调用 WebView 方法时
runOnUiThread(new Runnable() {
@Override
public void run() {
binding.web.evaluateJavascript("javascript: window.audioStop();", null);
}
runOnUiThread(() -> {
if (webView != null) webView.evaluateJavascript("javascript: window.audioStop();", null);
}); });
stopAsr(); stopAsr();
} }
@ -849,11 +935,8 @@ public class WebViewActivity extends BaseActivity {
@Override @Override
public void onEndOfSpeech() { public void onEndOfSpeech() {
Log.d(TAG, "结束说话"); Log.d(TAG, "结束说话");
runOnUiThread(new Runnable() {
@Override
public void run() {
binding.web.evaluateJavascript("javascript: window.audioStop();", null);
}
runOnUiThread(() -> {
if (webView != null) webView.evaluateJavascript("javascript: window.audioStop();", null);
}); });
} }
}; };

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

@ -17,7 +17,7 @@ public class Constant {
public static boolean isCoreService = false; // 是否启动 public static boolean isCoreService = false; // 是否启动
public static boolean isScreen4K = false; // 是否为4K屏 public static boolean isScreen4K = false; // 是否为4K屏
public static boolean networkState = false; // 是否有网络 public static boolean networkState = false; // 是否有网络
public static boolean tywx = false; // 是否为太原万象 mqtt密码修改
public static boolean tywx = false; // 是否为太原万象 mqtt密码修改 false
public static int rotate = 0; // T982截屏是否旋转角度 public static int rotate = 0; // T982截屏是否旋转角度
public static String screenType = "HDMI"; // 欣威视通3399设备为假关机 HDMI连接:可以用来判断是否为关机状态 LVDS连接:只能用定时关机时间来判断 public static String screenType = "HDMI"; // 欣威视通3399设备为假关机 HDMI连接:可以用来判断是否为关机状态 LVDS连接:只能用定时关机时间来判断
public static String mqttState = ""; // 屏幕连接方式 public static String mqttState = ""; // 屏幕连接方式

11
app/src/main/java/qianmu/container/data/PowerData.java

@ -56,15 +56,6 @@ public class PowerData extends BaseData {
} }
public static void updatePowerOnOrOffTime() { public static void updatePowerOnOrOffTime() {
//countTime++;
//Calendar cal= Calendar.getInstance();
//String format = new SimpleDateFormat("yyyy-MM-dd").format(cal.getTime());
//和义大道wifi 连接延时
// if(!DeviceData.getDeviceInfo(DeviceData.DEVICE_RESTART_TIME).equals(format) && countTime == 6){
// LoggerUtil.e("pingNet()", "第一次开机后5分钟,重启软件");
// DeviceData.saveDeviceInfo((DeviceData.DEVICE_RESTART_TIME),format);
// MyApplication.getInstance().restartApp();
// }
try { try {
String parameter = "";//关机 String parameter = "";//关机
String bootTime = "";//开机 String bootTime = "";//开机
@ -151,7 +142,7 @@ public class PowerData extends BaseData {
} }
String dataJson = getDataJson(NAME, POWER_INFO, "{}"); String dataJson = getDataJson(NAME, POWER_INFO, "{}");
//跳过开机的第一次设置
if(newTimeInfo.equals(dataJson)){ if(newTimeInfo.equals(dataJson)){
if(Constant.androidBoardType.equals("ys") && "".equals(isSetOver) && !StringUtil.isEmpty(parameter)){ // 亿盛有时候设置开机时间不成功 if(Constant.androidBoardType.equals("ys") && "".equals(isSetOver) && !StringUtil.isEmpty(parameter)){ // 亿盛有时候设置开机时间不成功
MyManager manager = MyManager.getInstance(MyApplication.getInstance()); MyManager manager = MyManager.getInstance(MyApplication.getInstance());

14
app/src/main/java/qianmu/container/handler/ContainerHandler.java

@ -63,13 +63,13 @@ import qianmu.container.util.ViplexCore;
public class ContainerHandler extends Handler { public class ContainerHandler extends Handler {
public static final int HEART_BEAT_DELAY_TIME = 70 * 1000; //心跳包时间间隔
public static final int HEART_BEAT_DELAY_TIME = 60 * 1000; //心跳包时间间隔
public static final int DELAY_TIME = 1000; //handler延时时间 public static final int DELAY_TIME = 1000; //handler延时时间
public static final int CONNECT_LOCAL_SOCKET = 3; //连接本地socket public static final int CONNECT_LOCAL_SOCKET = 3; //连接本地socket
public static final int CLOSE_LOCAL_SOCKET = 4; //关闭本地socket public static final int CLOSE_LOCAL_SOCKET = 4; //关闭本地socket
public static final int START_SOCKET_SERVER = 5; //启动socket服务 public static final int START_SOCKET_SERVER = 5; //启动socket服务
public static final int STOP_SOCKET_SERVER = 6; //停止socket服务 public static final int STOP_SOCKET_SERVER = 6; //停止socket服务
public static final int UPDATE_APP = 120 * 1000; //app更新包时间间隔
public static final int UPDATE_APP = 180 * 1000; //app更新包开机三分钟,以后半小
public static final int MQTT_ALIVE = 7; //app更新包时间间隔 public static final int MQTT_ALIVE = 7; //app更新包时间间隔
public static final int GET_TIME_TAMP = 8; //获取时间戳 public static final int GET_TIME_TAMP = 8; //获取时间戳
public static final int INIT_NOVA = 9; //获取时间戳 public static final int INIT_NOVA = 9; //获取时间戳
@ -86,7 +86,7 @@ public class ContainerHandler extends Handler {
sendEmptyMessageDelayed(DELAY_TIME, DELAY_TIME); sendEmptyMessageDelayed(DELAY_TIME, DELAY_TIME);
sendEmptyMessageDelayed(UPDATE_APP, UPDATE_APP);//app更新 sendEmptyMessageDelayed(UPDATE_APP, UPDATE_APP);//app更新
sendEmptyMessageDelayed(GET_TIME_TAMP, 100000);//获取时间戳 sendEmptyMessageDelayed(GET_TIME_TAMP, 100000);//获取时间戳
sendEmptyMessageDelayed(INIT_NOVA,1000);//获取时间戳
sendEmptyMessageDelayed(INIT_NOVA,60000);//获取时间戳
sendEmptyMessageDelayed(INIT_JXB,182000);//设置机械臂 sendEmptyMessageDelayed(INIT_JXB,182000);//设置机械臂
sendEmptyMessageDelayed(INIT_JXB2,186000);//设置机械臂 sendEmptyMessageDelayed(INIT_JXB2,186000);//设置机械臂
} }
@ -133,9 +133,8 @@ public class ContainerHandler extends Handler {
mqttState(); mqttState();
removeMessages(MQTT_ALIVE); removeMessages(MQTT_ALIVE);
printDisplayStatus(); printDisplayStatus();
sendEmptyMessageDelayed(MQTT_ALIVE,15000);
sendEmptyMessageDelayed(MQTT_ALIVE,35000);
sendEmptyMessageDelayed(MQTT_ALIVE,55000);
sendEmptyMessageDelayed(MQTT_ALIVE,20000);
sendEmptyMessageDelayed(MQTT_ALIVE,40000);
Constant.networkState=true; Constant.networkState=true;
} }
},new QueryErrorListener() { },new QueryErrorListener() {
@ -144,8 +143,7 @@ public class ContainerHandler extends Handler {
Constant.networkState = false; Constant.networkState = false;
} }
} ); } );
//getMemory();
getMemory();
// watchDog(); // watchDog();
getCoreServiceState(); getCoreServiceState();
// DeviceData.getPrimaryMachine(null, this::updateClientStateByIP); // DeviceData.getPrimaryMachine(null, this::updateClientStateByIP);

14
app/src/main/java/qianmu/container/mqtt/MQTTService.java

@ -195,7 +195,7 @@ public class MQTTService extends Service {
// 设置超时时间,单位:秒 // 设置超时时间,单位:秒
conOpt.setConnectionTimeout(10); conOpt.setConnectionTimeout(10);
// 心跳包发送间隔,单位:秒 // 心跳包发送间隔,单位:秒
conOpt.setKeepAliveInterval(20);
conOpt.setKeepAliveInterval(30);
// 用户名 // 用户名
conOpt.setUserName(userName); conOpt.setUserName(userName);
// 密码 // 密码
@ -477,7 +477,7 @@ public class MQTTService extends Service {
if(closeMqttBean.getType().equals("firmware-update")){ if(closeMqttBean.getType().equals("firmware-update")){
//固件升级 //固件升级
//systemUpdate(closeMqttBean);
systemUpdate(closeMqttBean);
}else if(closeMqttBean.getType().equals("app-update")){ }else if(closeMqttBean.getType().equals("app-update")){
//APP下发 //APP下发
appUpdate(closeMqttBean); appUpdate(closeMqttBean);
@ -566,8 +566,14 @@ public class MQTTService extends Service {
String url = closeMqttBean.getData().getUpdate().getUrl(); String url = closeMqttBean.getData().getUpdate().getUrl();
String version = closeMqttBean.getData().getUpdate().getFirmwareIssueVersion(); String version = closeMqttBean.getData().getUpdate().getFirmwareIssueVersion();
LoggerUtil.e("固件升级版本:", version); LoggerUtil.e("固件升级版本:", version);
if(!version.equals(SignWayUtil.getFirmwareVersion()) && !StringUtil.isEmpty(url)){
downloadImgFile(url,"update.zip");
String firmware = SignWayUtil.getFirmwareVersion();
LoggerUtil.e("固件版本:", firmware);
if (!StringUtil.isEmpty(firmware)
&& !StringUtil.isEmpty(version)
&& !firmware.toLowerCase().contains(version.toLowerCase())
&& !StringUtil.isEmpty(url)) {
downloadImgFile(url, "update.zip");
} }
} }

2
app/src/main/java/qianmu/container/util/TTSUtil.java

@ -104,12 +104,14 @@ public class TTSUtil {
LoggerUtil.d(TAG, "未初始化"); LoggerUtil.d(TAG, "未初始化");
initTts(); initTts();
} }
if (null == mEngine || null == intent) return;
mEngine.speak(intent, texts, "1024"); mEngine.speak(intent, texts, "1024");
} }
//停止听写 //停止听写
public void stopTTs(){ public void stopTTs(){
LoggerUtil.d(TAG, "手动暂停播放"); LoggerUtil.d(TAG, "手动暂停播放");
if (null == mEngine) return;
mEngine.stop(); mEngine.stop();
} }

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

@ -5,7 +5,8 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:background="#FFFFFF">
<RelativeLayout android:layout_height="match_parent" <RelativeLayout android:layout_height="match_parent"
android:layout_width="match_parent" android:layout_width="match_parent"
android:id="@+id/videoLayout"> android:id="@+id/videoLayout">
@ -16,6 +17,7 @@
android:id="@+id/web" android:id="@+id/web"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="#FFFFFF"
/> />
<ImageView <ImageView

Loading…
Cancel
Save