TaskService.java 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. package xn.update.service;
  2. import android.app.Notification;
  3. import android.app.NotificationChannel;
  4. import android.app.NotificationManager;
  5. import android.app.Service;
  6. import android.content.Intent;
  7. import android.content.IntentFilter;
  8. import android.os.Build;
  9. import android.os.CountDownTimer;
  10. import android.os.IBinder;
  11. import android.text.TextUtils;
  12. import android.util.Log;
  13. import androidx.annotation.NonNull;
  14. import androidx.annotation.Nullable;
  15. import androidx.core.app.NotificationCompat;
  16. import androidx.core.util.Pair;
  17. import androidx.work.ExistingPeriodicWorkPolicy;
  18. import androidx.work.PeriodicWorkRequest;
  19. import androidx.work.WorkManager;
  20. import com.blankj.utilcode.util.ActivityUtils;
  21. import com.blankj.utilcode.util.AppUtils;
  22. import com.blankj.utilcode.util.FileUtils;
  23. import com.blankj.utilcode.util.LogUtils;
  24. import com.blankj.utilcode.util.NetworkUtils;
  25. import com.blankj.utilcode.util.SPUtils;
  26. import com.blankj.utilcode.util.ThreadUtils;
  27. import com.hikvision.dmb.EthernetConfig;
  28. import com.hikvision.dmb.LauncherInfo;
  29. import com.hikvision.dmb.MemoryInfo;
  30. import com.hikvision.dmb.TimeSwitchConfig;
  31. import com.hikvision.dmb.display.InfoDisplayApi;
  32. import com.hikvision.dmb.network.InfoNetworkApi;
  33. import com.hikvision.dmb.system.InfoSystemApi;
  34. import com.hikvision.dmb.time.InfoTimeApi;
  35. import com.hikvision.dmb.util.InfoUtilApi;
  36. import com.hjq.permissions.OnPermissionCallback;
  37. import com.hjq.permissions.Permission;
  38. import com.hjq.permissions.XXPermissions;
  39. import com.lxj.xpopup.XPopup;
  40. import org.greenrobot.eventbus.EventBus;
  41. import org.json.JSONObject;
  42. import java.io.File;
  43. import java.util.List;
  44. import java.util.concurrent.Executors;
  45. import java.util.concurrent.ScheduledExecutorService;
  46. import java.util.concurrent.ThreadLocalRandom;
  47. import java.util.concurrent.TimeUnit;
  48. import java.util.concurrent.atomic.AtomicBoolean;
  49. import okhttp3.Response;
  50. import xn.update.R;
  51. import xn.update.Tool;
  52. import xn.update.constant.AppConstant;
  53. import xn.update.evnet.UpdateUiEvent;
  54. import xn.update.http.HttpTool;
  55. import xn.update.receiver.TimeTickReceiver;
  56. import xn.update.works.TaskWork;
  57. public class TaskService extends Service {
  58. private TimeTickReceiver timeTickReceiver;
  59. private final AtomicBoolean isUploading = new AtomicBoolean(false);
  60. private ScheduledExecutorService scheduler;
  61. @Nullable
  62. @Override
  63. public IBinder onBind(Intent intent) {
  64. return null;
  65. }
  66. @Override
  67. public void onCreate() {
  68. super.onCreate();
  69. scheduler = Executors.newSingleThreadScheduledExecutor();
  70. scheduler.scheduleWithFixedDelay(new Runnable() {
  71. @Override
  72. public void run() {
  73. if (!isUploading.compareAndSet(false, true)) {
  74. return;
  75. }
  76. ThreadUtils.executeByCached(new ThreadUtils.SimpleTask<Object>() {
  77. @Override
  78. public Object doInBackground() throws Throwable {
  79. Response response = HttpTool.INSTANCE.heartbeat();
  80. LogUtils.d("发送心跳");
  81. return null;
  82. }
  83. @Override
  84. public void onSuccess(Object result) {
  85. isUploading.set(false);
  86. }
  87. });
  88. }
  89. }, 0, 2, TimeUnit.SECONDS);
  90. // 卸载老旧app
  91. Tool.INSTANCE.cmd("pm uninstall com.dlc.xn.eboard");
  92. // 启动保活worker
  93. PeriodicWorkRequest taskRequest = new PeriodicWorkRequest.Builder(TaskWork.class, 15, TimeUnit.MINUTES).build();
  94. WorkManager.getInstance(getApplicationContext()).enqueueUniquePeriodicWork("Task", ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE, taskRequest);
  95. // 自动更新应用
  96. SPUtils.getInstance().put(AppConstant.AUTO_UPDATE, true);
  97. // 自动拉起主应用
  98. SPUtils.getInstance().put(AppConstant.AUTO_MASTER, true);
  99. InfoSystemApi.openAdb();
  100. InfoDisplayApi.setStatusBarEnable(false);
  101. InfoDisplayApi.setNavigationBarEnable(false);
  102. SPUtils.getInstance().put("isRoot", 0 == InfoUtilApi.getRoot());
  103. SPUtils.getInstance().put("IP", InfoNetworkApi.getEthernetConfig().ipAddress);
  104. InfoUtilApi.enableProtection(AppUtils.getAppPackageName(), false);
  105. InfoSystemApi.setLauncherForced(AppUtils.getAppPackageName());
  106. createNotificationChannel();
  107. timeTickReceiver = new TimeTickReceiver();
  108. // 监听分钟广播
  109. registerReceiver(timeTickReceiver, new IntentFilter(Intent.ACTION_TIME_TICK));
  110. Tool.INSTANCE.cmd("pm grant " + AppUtils.getAppPackageName() + " android.permission.READ_EXTERNAL_STORAGE");
  111. Tool.INSTANCE.cmd("pm grant " + AppUtils.getAppPackageName() + " android.permission.WRITE_EXTERNAL_STORAGE");
  112. Tool.INSTANCE.cmd("pm grant " + AppUtils.getAppPackageName() + " android.permission.NOTIFICATION_SERVICE");
  113. ThreadUtils.executeByCachedAtFixRate(new ThreadUtils.SimpleTask<Boolean>() {
  114. @Override
  115. public Boolean doInBackground() throws Throwable {
  116. if (null == ActivityUtils.getTopActivity()) {
  117. Tool.INSTANCE.stopApp(AppUtils.getAppPackageName());
  118. Tool.INSTANCE.openApp(AppUtils.getAppPackageName());
  119. } else {
  120. if (!XXPermissions.isGranted(ActivityUtils.getTopActivity(), Permission.READ_EXTERNAL_STORAGE)
  121. || !XXPermissions.isGranted(ActivityUtils.getTopActivity(), Permission.WRITE_EXTERNAL_STORAGE)
  122. || !XXPermissions.isGranted(ActivityUtils.getTopActivity(), Permission.NOTIFICATION_SERVICE)
  123. ) {
  124. Tool.INSTANCE.cmd("pm grant " + AppUtils.getAppPackageName() + " android.permission.READ_EXTERNAL_STORAGE");
  125. Tool.INSTANCE.cmd("pm grant " + AppUtils.getAppPackageName() + " android.permission.WRITE_EXTERNAL_STORAGE");
  126. Tool.INSTANCE.cmd("pm grant " + AppUtils.getAppPackageName() + " android.permission.NOTIFICATION_SERVICE");
  127. } else {
  128. return true;
  129. }
  130. }
  131. return false;
  132. }
  133. @Override
  134. public void onSuccess(Boolean result) {
  135. requestPermission();
  136. cancel();
  137. }
  138. }, 1, 1, TimeUnit.SECONDS);
  139. }
  140. @Override
  141. public int onStartCommand(Intent intent, int flags, int startId) {
  142. LogUtils.d(getClass().getName(), "onStartCommand");
  143. Notification notification = createNotification();
  144. startForeground(1, notification);
  145. return START_REDELIVER_INTENT;
  146. }
  147. @Override
  148. public void onTaskRemoved(Intent rootIntent) {
  149. super.onTaskRemoved(rootIntent);
  150. LogUtils.d(getClass().getName(), "onTaskRemoved");
  151. stopSelf();
  152. }
  153. @Override
  154. public void onDestroy() {
  155. super.onDestroy();
  156. if (null != scheduler) {
  157. scheduler.shutdown();
  158. }
  159. if (null != timeTickReceiver) {
  160. unregisterReceiver(timeTickReceiver);
  161. timeTickReceiver = null;
  162. }
  163. LogUtils.d(getClass().getName(), "onDestroy");
  164. }
  165. private void createNotificationChannel() {
  166. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
  167. int importance = NotificationManager.IMPORTANCE_DEFAULT;
  168. NotificationChannel channel = new NotificationChannel("task", "task", importance);
  169. NotificationManager notificationManager = getSystemService(NotificationManager.class);
  170. notificationManager.createNotificationChannel(channel);
  171. }
  172. }
  173. private Notification createNotification() {
  174. NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "task")
  175. .setContentTitle("Task")
  176. .setContentText("Task is running")
  177. .setSmallIcon(R.mipmap.ic_launcher)
  178. .setContentIntent(null)
  179. .setSilent(true)
  180. .setPriority(NotificationCompat.PRIORITY_DEFAULT);
  181. return builder.build();
  182. }
  183. private void requestPermission() {
  184. // 全量权限申请
  185. XXPermissions.with(ActivityUtils.getTopActivity())
  186. .permission(Permission.READ_EXTERNAL_STORAGE)
  187. .permission(Permission.WRITE_EXTERNAL_STORAGE)
  188. .permission(Permission.NOTIFICATION_SERVICE)
  189. .request(new OnPermissionCallback() {
  190. @Override
  191. public void onGranted(@NonNull List<String> permissions, boolean allGranted) {
  192. if (allGranted) {
  193. terminalAuth();
  194. } else {
  195. new XPopup.Builder(TaskService.this)
  196. .dismissOnBackPressed(false)
  197. .dismissOnTouchOutside(false)
  198. .asConfirm("Tips", "您必须同意所有权限才可以继续使用", ()
  199. -> requestPermission())
  200. .show();
  201. }
  202. }
  203. @Override
  204. public void onDenied(@NonNull List<String> permissions, boolean doNotAskAgain) {
  205. OnPermissionCallback.super.onDenied(permissions, doNotAskAgain);
  206. if (doNotAskAgain) {
  207. new XPopup.Builder(TaskService.this)
  208. .dismissOnBackPressed(false)
  209. .dismissOnTouchOutside(false)
  210. .asConfirm("Tips", "您必须同意所有权限才可以继续使用", ()
  211. -> XXPermissions.startPermissionActivity(TaskService.this, permissions))
  212. .show();
  213. } else {
  214. new XPopup.Builder(TaskService.this)
  215. .dismissOnBackPressed(false)
  216. .dismissOnTouchOutside(false)
  217. .asConfirm("Tips", "您必须同意所有权限才可以继续使用", ()
  218. -> requestPermission())
  219. .show();
  220. }
  221. }
  222. });
  223. }
  224. ThreadUtils.SimpleTask<Boolean> simpleTask = new ThreadUtils.SimpleTask<Boolean>() {
  225. @Override
  226. public Boolean doInBackground() throws Throwable {
  227. return NetworkUtils.isAvailableByPing(Tool.INSTANCE.getBaseUrl().host());
  228. }
  229. @Override
  230. public void onSuccess(Boolean result) {
  231. if (result) {
  232. EventBus.getDefault().post(new UpdateUiEvent("鉴权中..."));
  233. ThreadUtils.executeByCached(new ThreadUtils.SimpleTask<Pair<Boolean, String>>() {
  234. @Override
  235. public Pair<Boolean, String> doInBackground() throws Throwable {
  236. try {
  237. SPUtils.getInstance().put("TerminalAuth", "");
  238. Response response = HttpTool.INSTANCE.terminalAuth();
  239. if (response.isSuccessful()) {
  240. String json = response.body().string();
  241. JSONObject jsonObject = new JSONObject(json);
  242. int code = jsonObject.getInt("code");
  243. if (200 == code) {
  244. String data = jsonObject.getString("data");
  245. SPUtils.getInstance().put("TerminalAuth", TextUtils.isEmpty(data) ? "" : data);
  246. return Pair.create(true, "");
  247. } else {
  248. return Pair.create(false, jsonObject.getString("message"));
  249. }
  250. }
  251. } catch (Exception e) {
  252. LogUtils.e(Log.getStackTraceString(e));
  253. }
  254. return Pair.create(false, "鉴权异常,请联系管理员!");
  255. }
  256. @Override
  257. public void onSuccess(Pair<Boolean, String> result) {
  258. if (result.first) {
  259. // // 状态栏是否开启
  260. // boolean isStatusBarEnable = InfoDisplayApi.getStatusBarEnable();
  261. // // 导航栏是否开启
  262. // boolean isNavBarEnable = InfoDisplayApi.getNavigationBarEnable();
  263. //
  264. // EthernetConfig ethernetConfig = InfoNetworkApi.getEthernetConfig();
  265. // // Ip
  266. // String ip = ethernetConfig.getIpAddress();
  267. // // dhcp
  268. // int dhcp = ethernetConfig.getDhcp();
  269. // // dns1
  270. // String dns1 = ethernetConfig.getDns1Address();
  271. // // dns2
  272. // String dns2 = ethernetConfig.getDns2Address();
  273. // // mac
  274. // String mac = ethernetConfig.getMacAddress();
  275. // // route
  276. // String route = ethernetConfig.getRouteAddress();
  277. // // subnetMask
  278. // String subnetMask = ethernetConfig.getSubnetMask();
  279. // // 最优Ip地址 以太网>无线网>3、4G
  280. // String optimalIp = InfoNetworkApi.getOptimalIp();
  281. // // 设备型号
  282. // String deviceType = InfoSystemApi.getDeviceType();
  283. // // 设备序列号
  284. // String sn = InfoSystemApi.getSerialNumber();
  285. // // adb状态
  286. // int adbStatus = InfoSystemApi.getAdbStatus();
  287. // // 设备箱体温度
  288. // String temperature = InfoSystemApi.getTemperature();
  289. // // 系统编译版本号 V2.0.0 build 171226
  290. // String buildDesc = InfoSystemApi.getBuildDesc();
  291. // // 系统MCU版本号 V1.0.0 build 171226
  292. // String mcuVersion = InfoSystemApi.getMcuVersion();
  293. // // CPU使用率 当前 Cpu 的使用率,百分比,获取失败时返回”-1.00”字符串
  294. // String cpuUsageRate = InfoSystemApi.getCpuUsageRate();
  295. // // GPU使用率 当前 Gpu 的使用率,百分比,获取失败时返回”-1.00”字符串
  296. // String gpuUsageRate = InfoSystemApi.getGpuUsageRate();
  297. // // 获取内存使用情况
  298. // MemoryInfo memoryInfo = InfoSystemApi.getMemoryUsage();
  299. // // MemoryInfo .used 已使用内存大小(单位 MB)
  300. // int used = memoryInfo.used;
  301. // // MemoryInfo.total 总内存大小(MB)
  302. // int total = memoryInfo.total;
  303. // // MemoryInfo.describe 583.00MB/1.96GB
  304. // String describe = memoryInfo.describe;
  305. // int describeContents = memoryInfo.describeContents();
  306. // // 获取SDK版本 返回 SDK 版本号,获取失败返回”none”字符串
  307. // String sdkVersion = InfoSystemApi.getSdkVersion();
  308. // // 如果系统不支持该接口,则 currentLauncherName 和 preferredLauncherName 的值均为空字符串(“”)。
  309. // // 关于“默认“一词,默认 Launcher 即多个 Launcher 应用中优先级最高的,默认启动的。
  310. // LauncherInfo launcherInfo = InfoSystemApi.getLauncherName();
  311. // // 为当前生效的默认 Launcher 应用包名,默认(始终)Launcher 应用修改后该值即时更新。如果当前系统未设置默认(始终)Launcher,则该值为空字符串(“”)。
  312. // String currentLauncherName = launcherInfo.getCurrentLauncherName();
  313. // // 为持久化文件中保存的默认 Launcher 应用包名,默认 Launcher 应用修改后约 10 秒后该值才会更新,该值仅当系统内存在 2 个及以上Launcher 应用时才会存在,否则为空字符串(“”)。
  314. // String preferredLauncherName = launcherInfo.getPreferredLauncherName();
  315. // // 获取定时开关机计划
  316. // TimeSwitchConfig timeSwitchConfig = InfoTimeApi.getTimeSwitch();
  317. // // 开机时间 默认-1
  318. // long onTime = timeSwitchConfig.setOnTime;
  319. // // 关机时间 默认-1
  320. // long offTime = timeSwitchConfig.setOffTime;
  321. // // 门禁点锁状态1 true-当前锁处于上电锁门状态
  322. // // false-当前锁处于断电开门状态或参数错误
  323. // boolean electricLock1 = InfoUtilApi.getElectricLock(1);
  324. // // 门禁点锁状态2
  325. // boolean electricLock2 = InfoUtilApi.getElectricLock(2);
  326. EventBus.getDefault().post(new UpdateUiEvent(result.second));
  327. ThreadUtils.cancel(simpleTask);
  328. } else {
  329. EventBus.getDefault().post(new UpdateUiEvent(result.second));
  330. }
  331. }
  332. });
  333. } else {
  334. EventBus.getDefault().post(new UpdateUiEvent("无法连接到服务器,请联系管理员!"));
  335. }
  336. }
  337. };
  338. private void terminalAuth() {
  339. ThreadUtils.executeByCachedAtFixRate(simpleTask, ThreadLocalRandom.current().nextInt(10, 20), TimeUnit.SECONDS);
  340. // 清理一个月前的log
  341. ThreadUtils.executeByCached(new ThreadUtils.SimpleTask<Object>() {
  342. @Override
  343. public Object doInBackground() throws Throwable {
  344. List<File> fileList = FileUtils.listFilesInDir("/sdcard/logs/");
  345. for (int i = 0; i < fileList.size(); i++) {
  346. File file = fileList.get(i);
  347. long oneMonth = 30 * 86400 * 1000L;
  348. if ((System.currentTimeMillis() - file.lastModified()) > oneMonth) {
  349. LogUtils.d("删除日志文件", file);
  350. FileUtils.delete(file);
  351. }
  352. }
  353. return null;
  354. }
  355. @Override
  356. public void onSuccess(Object result) {
  357. }
  358. });
  359. }
  360. }