Browse Source

1.新增看门狗

JaycePC 4 months ago
parent
commit
c985e8a2d8

+ 2 - 1
app/build.gradle

@@ -13,7 +13,7 @@ android {
         //noinspection ExpiredTargetSdkVersion
         targetSdk 28
         versionCode 1
-        versionName "1.2"
+        versionName "1.3"
 
         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
     }
@@ -73,4 +73,5 @@ dependencies {
     implementation "androidx.work:work-runtime:2.9.1"
     //noinspection UseTomlInstead
     implementation("org.greenrobot:eventbus:3.3.1")
+    implementation 'com.github.anrwatchdog:anrwatchdog:1.4.0'
 }

+ 1 - 0
app/src/main/java/xn/update/MainActivity.java

@@ -33,6 +33,7 @@ public class MainActivity extends AppCompatActivity {
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+
         if (!EventBus.getDefault().isRegistered(this)) {
             EventBus.getDefault().register(this);
         }

+ 17 - 4
app/src/main/java/xn/update/Tool.java

@@ -22,18 +22,27 @@ public enum Tool {
         InfoSystemApi.execCommand("monkey -p " + AppUtils.getAppPackageName() + " -c android.intent.category.LAUNCHER 1");
     }
 
-    public void openFileBrowser() {
-        openApp("display.interactive.filebrowser");
-    }
-
     public void exitApp() {
         InfoSystemApi.execCommand("am force-stop " + AppUtils.getAppPackageName());
     }
 
+    public void reStartApp(String packageName) {
+        exitApp(packageName);
+        InfoSystemApi.execCommand("monkey -p " + packageName + " -c android.intent.category.LAUNCHER 1");
+    }
+
+    public void exitApp(String packageName) {
+        InfoSystemApi.execCommand("am force-stop " + packageName);
+    }
+
     public void openSetting() {
         openApp("display.interactive.hsetting");
     }
 
+    public void openFileBrowser() {
+        openApp("display.interactive.filebrowser");
+    }
+
     public void openApp(String packageName) {
         InfoSystemApi.execCommand("monkey -p " + packageName + " -c android.intent.category.LAUNCHER 1");
     }
@@ -47,6 +56,7 @@ public enum Tool {
     }
 
     public void startTaskService() {
+
         cmd("am startservice -n xn.update/xn.update.service.TaskService");
     }
 
@@ -77,4 +87,7 @@ public enum Tool {
         }
     }
 
+    public void reboot() {
+        InfoSystemApi.reboot();
+    }
 }

+ 26 - 0
app/src/main/java/xn/update/app/App.java

@@ -2,11 +2,17 @@ package xn.update.app;
 
 import android.annotation.SuppressLint;
 import android.app.Application;
+import android.widget.Toast;
 
+import com.blankj.utilcode.util.ActivityUtils;
 import com.blankj.utilcode.util.AppUtils;
 import com.blankj.utilcode.util.CrashUtils;
 import com.blankj.utilcode.util.FileUtils;
 import com.blankj.utilcode.util.LogUtils;
+import com.blankj.utilcode.util.SPUtils;
+import com.blankj.utilcode.util.ThreadUtils;
+import com.github.anrwatchdog.ANRError;
+import com.github.anrwatchdog.ANRWatchDog;
 
 import xn.update.Tool;
 
@@ -15,6 +21,26 @@ public class App extends Application {
     @SuppressLint("SdCardPath")
     public void onCreate() {
         super.onCreate();
+        new ANRWatchDog(5000).setANRListener(new ANRWatchDog.ANRListener() {
+            @Override
+            public void onAppNotResponding(ANRError error) {
+                ThreadUtils.runOnUiThread(new Runnable() {
+                    @Override
+                    public void run() {
+                        Toast.makeText(ActivityUtils.getTopActivity(), "检测到应用卡顿,重启应用恢复!", Toast.LENGTH_LONG).show();
+                        int anrSize = SPUtils.getInstance().getInt("ANR_size", 0);
+                        if (anrSize > 5) {
+                            SPUtils.getInstance().put("ANR_size", 0);
+                            Tool.INSTANCE.reboot();
+                        } else {
+                            SPUtils.getInstance().put("ANR_size", ++anrSize);
+                            Tool.INSTANCE.reStartApp();
+                        }
+                    }
+                });
+                LogUtils.e(error.getMessage(), error);
+            }
+        }).start();
         String logPath = "/sdcard/logs/";
         String crashPath = "/sdcard/logs/crash/";
         // log文件存储地址

+ 9 - 0
app/src/main/java/xn/update/constant/AppConstant.java

@@ -4,6 +4,15 @@ public final class AppConstant {
     private AppConstant() {
     }
 
+    public static final class KeySP {
+        // 主应用包名
+        public static final String MASTER_PACKAGE_NAME = "masterPackageName";
+        // MASTER ANR 重启次数
+        public static final String MASTER_ANR_COUNT = "masterAnrCount";
+        // App ANR 重启次数
+        public static final String APP_ANR_COUNT = "appAnrCount";
+    }
+
     /**
      * 自动更新应用
      */

+ 17 - 0
app/src/main/java/xn/update/http/bean/response/UpdateTask.java

@@ -56,6 +56,23 @@ public class UpdateTask {
         private String versionName;
         private String startLaunchPackage;
         private boolean isForceUpdate;
+        private String appPackageName;
+
+        public boolean isForceUpdate() {
+            return isForceUpdate;
+        }
+
+        public void setForceUpdate(boolean forceUpdate) {
+            isForceUpdate = forceUpdate;
+        }
+
+        public String getAppPackageName() {
+            return appPackageName;
+        }
+
+        public void setAppPackageName(String appPackageName) {
+            this.appPackageName = appPackageName;
+        }
 
         public String getTaskId() {
             return taskId;

+ 15 - 3
app/src/main/java/xn/update/receiver/TimeTickReceiver.java

@@ -20,6 +20,7 @@ import com.blankj.utilcode.util.SPUtils;
 import com.blankj.utilcode.util.ShellUtils;
 import com.blankj.utilcode.util.ThreadUtils;
 import com.blankj.utilcode.util.ToastUtils;
+import com.blankj.utilcode.util.Utils;
 
 import org.json.JSONException;
 
@@ -74,8 +75,19 @@ public class TimeTickReceiver extends BroadcastReceiver {
                                     AsyncTask.execute(() -> {
                                         try {
                                             HttpTool.INSTANCE.updateCallBack(task.getTaskId(), task.getDeviceCode(), true, true);
-                                            Tool.INSTANCE.cmd("pm install -d -g " + apkPath + apkName);
-                                            Tool.INSTANCE.openApp(task.getStartLaunchPackage());
+                                            if (AppUtils.getAppPackageName().equals(task.getAppPackageName())) {
+                                                Tool.INSTANCE.cmd("pm install -d -g " + apkPath + apkName);
+                                                Tool.INSTANCE.openApp(task.getStartLaunchPackage());
+                                            } else {
+                                                ShellUtils.execCmdAsync("pm uninstall " + task.getAppPackageName(), true, new Utils.Consumer<ShellUtils.CommandResult>() {
+                                                    @Override
+                                                    public void accept(ShellUtils.CommandResult commandResult) {
+                                                        LogUtils.d(commandResult);
+                                                        Tool.INSTANCE.cmd("pm install -d -g " + apkPath + apkName);
+                                                        Tool.INSTANCE.openApp(task.getStartLaunchPackage());
+                                                    }
+                                                });
+                                            }
                                         } catch (IOException | JSONException e) {
                                             LogUtils.e(Log.getStackTraceString(e));
                                         }
@@ -119,7 +131,7 @@ public class TimeTickReceiver extends BroadcastReceiver {
                                     FileUtils.createOrExistsDir(apkPath);
                                     FileUtils.deleteAllInDir(apkPath);
                                     if (!AppUtils.getAppPackageName().equals(task.getStartLaunchPackage())) {
-                                        SPUtils.getInstance().put("masterApp", task.getStartLaunchPackage());
+                                        SPUtils.getInstance().put(AppConstant.KeySP.MASTER_PACKAGE_NAME, task.getStartLaunchPackage());
                                     }
                                     DownloadManager.Request request = new DownloadManager.Request(Uri.parse(Tool.INSTANCE.checkUrl(task.getApkUrl())));
                                     request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "apk/" + apkName);

+ 59 - 2
app/src/main/java/xn/update/service/TaskService.java

@@ -7,6 +7,7 @@ import android.app.Service;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.os.Build;
+import android.os.CountDownTimer;
 import android.os.IBinder;
 import android.text.TextUtils;
 import android.util.Log;
@@ -21,10 +22,12 @@ import androidx.work.WorkManager;
 
 import com.blankj.utilcode.util.ActivityUtils;
 import com.blankj.utilcode.util.AppUtils;
+import com.blankj.utilcode.util.FileUtils;
 import com.blankj.utilcode.util.LogUtils;
 import com.blankj.utilcode.util.NetworkUtils;
 import com.blankj.utilcode.util.SPUtils;
 import com.blankj.utilcode.util.ThreadUtils;
+import com.blankj.utilcode.util.TimeUtils;
 import com.hikvision.dmb.display.InfoDisplayApi;
 import com.hikvision.dmb.network.InfoNetworkApi;
 import com.hikvision.dmb.system.InfoSystemApi;
@@ -37,12 +40,14 @@ import com.lxj.xpopup.XPopup;
 import org.greenrobot.eventbus.EventBus;
 import org.json.JSONObject;
 
+import java.io.File;
+import java.text.SimpleDateFormat;
 import java.util.List;
+import java.util.Locale;
 import java.util.concurrent.ThreadLocalRandom;
 import java.util.concurrent.TimeUnit;
 
 import okhttp3.Response;
-import xn.update.MainActivity;
 import xn.update.R;
 import xn.update.Tool;
 import xn.update.constant.AppConstant;
@@ -54,6 +59,7 @@ import xn.update.works.TaskWork;
 public class TaskService extends Service {
 
     private TimeTickReceiver timeTickReceiver;
+    private CountDownTimer permissionCdt;
 
     @Nullable
     @Override
@@ -87,7 +93,33 @@ public class TaskService extends Service {
         // 监听分钟广播
         registerReceiver(timeTickReceiver, new IntentFilter(Intent.ACTION_TIME_TICK));
 
-        requestPermission();
+        Tool.INSTANCE.cmd("pm grant " + AppUtils.getAppPackageName() + " android.permission.READ_EXTERNAL_STORAGE");
+        Tool.INSTANCE.cmd("pm grant " + AppUtils.getAppPackageName() + " android.permission.WRITE_EXTERNAL_STORAGE");
+        Tool.INSTANCE.cmd("pm grant " + AppUtils.getAppPackageName() + " android.permission.NOTIFICATION_SERVICE");
+        permissionCdt = new CountDownTimer(1000, 1000) {
+            @Override
+            public void onTick(long millisUntilFinished) {
+
+            }
+
+            @Override
+            public void onFinish() {
+                if (!XXPermissions.isGranted(ActivityUtils.getTopActivity(), Permission.READ_EXTERNAL_STORAGE)
+                        || !XXPermissions.isGranted(ActivityUtils.getTopActivity(), Permission.WRITE_EXTERNAL_STORAGE)
+                        || !XXPermissions.isGranted(ActivityUtils.getTopActivity(), Permission.NOTIFICATION_SERVICE)) {
+                    Tool.INSTANCE.cmd("pm grant " + AppUtils.getAppPackageName() + " android.permission.READ_EXTERNAL_STORAGE");
+                    Tool.INSTANCE.cmd("pm grant " + AppUtils.getAppPackageName() + " android.permission.WRITE_EXTERNAL_STORAGE");
+                    Tool.INSTANCE.cmd("pm grant " + AppUtils.getAppPackageName() + " android.permission.NOTIFICATION_SERVICE");
+                    permissionCdt.start();
+                }else {
+                    requestPermission();
+                    permissionCdt.cancel();
+                    permissionCdt=null;
+                }
+
+            }
+        };
+        permissionCdt.start();
     }
 
     @Override
@@ -230,5 +262,30 @@ public class TaskService extends Service {
 
     private void terminalAuth() {
         ThreadUtils.executeByCachedAtFixRate(simpleTask, ThreadLocalRandom.current().nextInt(10, 20), TimeUnit.SECONDS);
+        // 清理一个月前的log
+        ThreadUtils.executeByCached(new ThreadUtils.SimpleTask<Object>() {
+            @Override
+            public Object doInBackground() throws Throwable {
+                List<File> fileList = FileUtils.listFilesInDir("/sdcard/logs/");
+                for (int i = 0; i < fileList.size(); i++) {
+                    File file = fileList.get(i);
+                    String fileName = file.getName();
+                    fileName = fileName.replace(AppUtils.getAppName() + "_", "");
+                    fileName = fileName.replace("_" + AppUtils.getAppPackageName(), "");
+                    fileName = fileName.replace(".txt", "");
+                    long fileTime = TimeUtils.string2Millis(fileName, new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()));
+                    long oneMonth = 30 * 86400 * 1000L;
+                    if ((System.currentTimeMillis() - fileTime) > oneMonth) {
+                        FileUtils.delete(file);
+                    }
+                }
+                return null;
+            }
+
+            @Override
+            public void onSuccess(Object result) {
+
+            }
+        });
     }
 }