diff --git a/app/build.gradle b/app/build.gradle index df5898d..328fc60 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -10,7 +10,7 @@ android { minSdkVersion 26 targetSdkVersion 30 versionCode 6 - versionName "V2.0.7.54" + versionName "V2.0.7.55" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles 'consumer-rules.pro' 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 f1fde29..bdb30e4 100644 --- a/app/src/main/java/qianmu/container/activity/H5/WebViewActivity.java +++ b/app/src/main/java/qianmu/container/activity/H5/WebViewActivity.java @@ -1033,11 +1033,11 @@ public class WebViewActivity extends BaseActivity { }); localSocketClient.setOnCloseListener((code, reason, remote) -> { - LoggerUtil.e("LocSocCliManager", "onClose:code="+code); + LoggerUtil.e("LocSocCliManager", "onClose:"+countConect); scheduleReconnect(); }); localSocketClient.setOnErrorListener((ex) -> { - LoggerUtil.e("LocSocCliManager", ex.getMessage()); + LoggerUtil.e("LocSocCliManager", "Error:"+countConect); }); } private void scheduleReconnect() { diff --git a/app/src/main/java/qianmu/container/app/Constant.java b/app/src/main/java/qianmu/container/app/Constant.java index 7e3e796..8fece7e 100644 --- a/app/src/main/java/qianmu/container/app/Constant.java +++ b/app/src/main/java/qianmu/container/app/Constant.java @@ -29,9 +29,9 @@ public class Constant { // 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 = "huidu"; //设备板子型号 huidu(灰度主板) 罗湖寻车机 // public static String androidBoardType = "bv"; //设备板子型号 Bv-3588M - // public static String androidBoardType = "smt"; //设备板子型号 视美泰 + public static String androidBoardType = "smt"; //设备板子型号 视美泰 public static String TTSFac = "sbc"; // 语音识别厂家 kdxf--科大讯飞 sbc-思必驰 public static final String VOID_STOP = "void_stop";// diff --git a/app/src/main/java/qianmu/container/app/MyApplication.java b/app/src/main/java/qianmu/container/app/MyApplication.java index 53fe4dc..e28036e 100644 --- a/app/src/main/java/qianmu/container/app/MyApplication.java +++ b/app/src/main/java/qianmu/container/app/MyApplication.java @@ -175,30 +175,38 @@ public class MyApplication extends Application { String errorLog = StringUtil.strSplice( MyApplication.getInstance().dateTimeFormat.format(new Date(timeMillis)), ":\n", throwable.getMessage(), "\n", sw.toString()); - LoggerUtil.e("errorLog", errorLog); - //上传日志 - String deviceCode = DeviceData.getDeviceInfo(DeviceData.HINT_DEVICE_CODE); - String fileName = new SimpleDateFormat("yyyy-MM-dd").format(System.currentTimeMillis()); - String path= StringUtil.strSplice(SAVE_LOG_DIR_PATH, "/", fileName, ".txt"); - LoggerUtil.uploadLogFile(path,deviceCode,"","1"); - - restartApp(); - Intent intent = new Intent(Constant.ACTION_APP_CRASH); - intent.putExtra(Constant.PACKAGE_NAME, DeviceUtil.getPackageName()); - sendStickyBroadcast(intent); - sendBroadcast(new Intent(Constant.ACTION_EXIT)); - try { - PackageManager packageManager = getPackageManager(); - Intent appIntent = packageManager.getLaunchIntentForPackage(Constant.APP_CRASH_PACKAGE_NAME); - startActivity(appIntent); - } catch (Throwable t) { - LoggerUtil.e("崩溃自启失败", StringUtil.getThrowableStr(t)); - restartApp(); + LoggerUtil.e("APP崩溃", errorLog); + if (isSystemExceptionInternal(throwable)) { + try { + Thread.sleep(5000); + SignWayUtil.reboot(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return; } - + restartApp(); }); } + private boolean isSystemExceptionInternal(Throwable throwable) { + String className = throwable.getClass().getName(); + String message = throwable.getMessage(); + + // 检查常见的系统异常 + return className.contains("DeadSystemException") || + className.contains("DeadObjectException") || + className.contains("RemoteException") || + className.contains("TransactionTooLargeException") || + className.contains("NetworkOnMainThreadException") || + className.contains("BadParcelableException") || + className.contains("NullPointerException") && + (message != null && message.contains("on a null object reference")) || + className.contains("IllegalStateException") && + (message != null && (message.contains("Fragment not attached") || + message.contains("Activity has been destroyed"))); + } + /** * 重启软件 */ @@ -213,12 +221,7 @@ public class MyApplication extends Application { // 开启背景音乐 stopService(new Intent(this, MusicService.class));// 背景音乐 } - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - SignWayUtil.reboot(); //重启设备 + ProcessPhoenix.triggerRebirth(this); } // 点击进入配置界面 diff --git a/app/src/main/java/qianmu/container/mqtt/MQTTService.java b/app/src/main/java/qianmu/container/mqtt/MQTTService.java index 52081cc..76124f1 100644 --- a/app/src/main/java/qianmu/container/mqtt/MQTTService.java +++ b/app/src/main/java/qianmu/container/mqtt/MQTTService.java @@ -62,6 +62,7 @@ import java.util.List; import java.util.Map; import java.util.Timer; import java.util.TimerTask; +import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; @@ -92,6 +93,7 @@ import qianmu.container.util.BitmapUtil; import qianmu.container.util.DeviceUtil; import qianmu.container.util.FileUtil; import qianmu.container.util.LoggerUtil; +import qianmu.container.util.RootCmdUtil; import qianmu.container.util.SignWayUtil; import qianmu.container.util.StringUtil; import retrofit2.Call; @@ -634,66 +636,87 @@ public class MQTTService extends Service { /** * 截屏 * */ - public static void screenShot(long time) { + private static final ExecutorService SCREEN_SHOT_EXECUTOR = Executors.newSingleThreadExecutor(); - if(Constant.androidBoardType.equals("nova")){ - MessageEvent messageEvent = new MessageEvent(Constant.NOVA_SCREEN_SHOT); - messageEvent.setData(""+time); - EventBus.getDefault().post(messageEvent); - return; - } - String path = StringUtil.strSplice(BitmapUtil.SAVE_SCREEN_SHOT_PATH, "/screenShot.png"); - File file = new File(path); - File parent = file.getParentFile(); - if (!parent.exists()) parent.mkdirs(); - - if(SignWayUtil.getgetAndroidModle().equals("t982")){ - //亿晟主板t982特殊处理上传 - boolean b = SignWayUtil.ysTakeScreenshot(path); - if(!b){ - return; - } - Executors.newSingleThreadExecutor().execute(() -> { - try { - - uploadScreenShot(path,DeviceData.getDeviceInfo(DeviceData.HINT_DEVICE_CODE),String.valueOf(time)); - - } catch (Exception e) { - e.printStackTrace(); - } - }); - return; - } - - String cmd = "screencap -p " + path; - Executors.newSingleThreadExecutor().execute(() -> { + public static void screenShot(long time) { + SCREEN_SHOT_EXECUTOR.submit(() -> { try { - Process process = Runtime.getRuntime().exec("su");//不同的设备权限不一样 - PrintWriter pw = new PrintWriter(process.getOutputStream()); - pw.println(cmd); - pw.flush(); - pw.println("exit"); - pw.flush(); - try { - process.waitFor(2500, TimeUnit.MILLISECONDS);; - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - pw.close(); - process.destroy(); - - if(!new File(path).exists()){ - LoggerUtil.e("screenShot","截屏失败"); + if (Constant.androidBoardType.equals("nova")) { + MessageEvent messageEvent = new MessageEvent(Constant.NOVA_SCREEN_SHOT); + messageEvent.setData("" + time); + EventBus.getDefault().post(messageEvent); return; } - uploadScreenShot(path,DeviceData.getDeviceInfo(DeviceData.HINT_DEVICE_CODE),String.valueOf(time)); - } catch (IOException e) { - e.printStackTrace(); + String path = StringUtil.strSplice(BitmapUtil.SAVE_SCREEN_SHOT_PATH, "/screenShot.png"); + // ====================== 修复点3:子线程内安全创建file ====================== + File file = new File(path); + File parent = file.getParentFile(); + if (!parent.exists()) parent.mkdirs(); + if (file.exists()) file.delete(); + + boolean shotSuccess = false; + + // 亿晟主板 + if (SignWayUtil.getgetAndroidModle().equals("t982")) { + shotSuccess = SignWayUtil.ysTakeScreenshot(path); + + } else if (!"".equals(Constant.androidBoardType)) { + SignWayUtil.takeScreenshot(path); + int retryCount = 0; + final int MAX_RETRY = 15; + final long SLEEP_MS = 300; + long lastSize = 0; + + while (retryCount < MAX_RETRY) { + File f = new File(path); + if (f.exists()) { + long currentSize = f.length(); + if (currentSize > 1024) { + if (currentSize == lastSize) { + LoggerUtil.e("screenShot", "截屏完成"); + shotSuccess = true; + break; + } + } + lastSize = currentSize; + } + + try { + Thread.sleep(SLEEP_MS); + } catch (InterruptedException e) { + break; + } + retryCount++; + } + + } else { + LoggerUtil.e("screenShot", "root截屏"); + String[] cmd = {"su", "-c", "screencap -p " + path}; + Process process = Runtime.getRuntime().exec(cmd); + BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream())); + String line; + while ((line = errorReader.readLine()) != null) { + LoggerUtil.e("screenShot", "error: " + line); + } + boolean finished = process.waitFor(3, TimeUnit.SECONDS); + if (!finished) { + process.destroyForcibly(); + } + shotSuccess = new File(path).exists(); + } + // 上传 + if (shotSuccess) { + LoggerUtil.e("screenShot", "开始上传"); + uploadScreenShot(path, DeviceData.getDeviceInfo(DeviceData.HINT_DEVICE_CODE), String.valueOf(time)); + } else { + LoggerUtil.e("screenShot", "截屏失败"); + } + } catch (Exception e) { + // ====================== 修复点6:全局捕获所有异常,绝不崩溃 ====================== + LoggerUtil.e("screenShot", "截屏异常:" + e.getMessage()); } }); - } //上传截屏 diff --git a/app/src/main/java/qianmu/container/util/SignWayUtil.java b/app/src/main/java/qianmu/container/util/SignWayUtil.java index 768a17d..2164caf 100644 --- a/app/src/main/java/qianmu/container/util/SignWayUtil.java +++ b/app/src/main/java/qianmu/container/util/SignWayUtil.java @@ -322,6 +322,8 @@ public class SignWayUtil { if(Constant.androidBoardType.equals("xwst")){ SignwayManager signwayManager = SignwayManager.getInstance(MyApplication.getInstance()); signwayManager.takeScreenshot(path, 0); + }else if(Constant.androidBoardType.equals("smt")){ + MyApplication.getInstance().getSmdt().disp_getScreenShot(path); }else if(Constant.androidBoardType.equals("ys")){ Log.e("TAG","开始截屏"); MyManager manager = MyManager.getInstance(MyApplication.getInstance());