package com.emato.ich; import android.os.Bundle; import com.cherry.sdk.controller.utils.ScanGunKeyEventHelper; import com.emato.ich.api.ICSPClient; import com.emato.ich.api.ICSPResponseCodeEnum; import com.emato.ich.api.SystemConfigConstant; import com.emato.ich.crash.CrashApplication; import com.emato.ich.device.DeviceControl; import com.emato.ich.entity.Cabinet; import com.emato.ich.entity.Message; import com.emato.ich.entity.vo.ResponseData; import com.emato.ich.entity.vo.ShellVo; import com.emato.ich.message.ICHPublishClient; import com.emato.ich.message.ICHTopic; import com.emato.ich.update.APKUpdateDownload; import com.emato.ich.update.OnDownloadListener; import com.emato.ich.utils.BaseUtils; import com.emato.ich.utils.JacksonUtils; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import androidx.appcompat.app.AppCompatActivity; import android.util.Log; import android.view.KeyEvent; import androidx.navigation.NavController; import androidx.navigation.Navigation; import androidx.navigation.ui.AppBarConfiguration; import androidx.navigation.ui.NavigationUI; import com.emato.ich.databinding.ActivityMainBinding; import com.xuexiang.xupdate.XUpdate; import android.view.Menu; import android.view.MenuItem; import android.view.WindowManager; import org.eclipse.paho.client.mqttv3.MqttMessage; import org.jetbrains.annotations.NotNull; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.Arrays; import java.util.Collections; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CountDownLatch; import okhttp3.Call; import okhttp3.Callback; import okhttp3.Response; public class MainActivity extends AppCompatActivity { private AppBarConfiguration appBarConfiguration; private ActivityMainBinding binding; public ScanGunKeyEventHelper scanGunKeyEventHelper; private final Map bundleMap = new ConcurrentHashMap<>(); private final Map configMap = new ConcurrentHashMap<>(); private static final String TAG = MainActivity.class.getName(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = ActivityMainBinding.inflate(getLayoutInflater()); // 强制关闭输入法 getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN); // setSupportActionBar(binding.toolbar); setContentView(binding.getRoot()); // NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main); // appBarConfiguration = new AppBarConfiguration.Builder(navController.getGraph()).build(); // NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration); // 自动重启 ((CrashApplication) getApplication()).addActivity(MainActivity.this); // DeviceControl.unlockLocker(4, 2, new CmdCallback() { // @Override // public void onMessage(int i, String... strings) { // Log.i(TAG, "onMessage: ===============================>" + i + Arrays.asList(strings)); // } // }); // 获取系统配置 ICSPClient.getSystemConfig("", BaseUtils.getClientId(), new Callback() { @Override public void onFailure(@NotNull Call call, @NotNull IOException e) { Log.e(TAG, "onFailure: 获取系统配置错误! 网络错误! ", e); } @Override public void onResponse (@NotNull Call call, @NotNull Response response) throws IOException { try { OnDownloadListener listener = new OnDownloadListener() { @Override public void onDownloadSuccess(File file) { } @Override public void onDownloading(int progress) { } @Override public void onDownloadFailed(Exception e) { } }; String parseResponse = ICSPClient.isSuccessfulAndParseResponse(response); ObjectMapper objectMapper = JacksonUtils.objectmapper; ResponseData> readValue = objectMapper.readValue(parseResponse, new TypeReference>>() { }); if (null != readValue && readValue.getCode().equals(ICSPResponseCodeEnum.OK.getCode())) { configMap.putAll(readValue.getData()); String qrcode_url = configMap.get(SystemConfigConstant.cabinet_take_object_qrcode_url); try { ICSPClient.download(qrcode_url, new Callback() { @Override public void onFailure(@NotNull Call call, @NotNull IOException e) { } @Override public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException { InputStream is = null; byte[] buf = new byte[2048]; int len = 0; FileOutputStream fos = null; final String destFileDir = "res/drawable/"; String destFileName = "e_mp_qrcode_8x8.jpg"; //储存下载文件的目录 File dir = new File(getApplication().getFilesDir().getAbsolutePath() + "/" +destFileDir); if (!dir.exists()) { dir.mkdirs(); } // destFileName = apk_url.substring(apk_url.lastIndexOf('/'), apk_url.length() - 1); File file = new File(dir, destFileName); try { is = response.body().byteStream(); long total = response.body().contentLength(); fos = new FileOutputStream(file); long sum = 0; while ((len = is.read(buf)) != -1) { fos.write(buf, 0, len); sum += len; int progress = (int) (sum * 1.0f / total * 100); //下载中更新进度条 listener.onDownloading(progress); } fos.flush(); //下载完成 listener.onDownloadSuccess(file); } catch (Exception e) { listener.onDownloadFailed(e); }finally { try { if (is != null) { is.close(); } if (fos != null) { fos.close(); } } catch (IOException e) { } } } }, listener); } catch (Exception e) { } Log.i(TAG, "onResponse: 获取系统配置成功! "); } else { Log.w(TAG, "onResponse: code==>" + readValue.getCode() + ", msg==>" + readValue.getMsg()); } } catch (RuntimeException e) { Log.e(TAG, "onResponse: 获取系统配置错误! 未知错误! ", e); } } }); ICHPublishClient ichPublishClient = ICHPublishClient.getInstance(); String clientId = BaseUtils.getClientId(); ICHTopic.CLIENT_ID = clientId; // 订阅主题 // ICHSubscribeClient ichSubscribeClient = ICHSubscribeClient.getInstance(); ichPublishClient.subscribe(ICHTopic.LOCK + clientId, (s, msg) -> { String payload = new String(msg.getPayload()); ObjectMapper objectMapper = JacksonUtils.objectmapper; Message message = objectMapper.readValue(payload, Message.class); Log.i(TAG, "onCreate: message id: " + s + "--------------消息体: " + message); DeviceControl.unlockLocker(message.getSection(), message.getPort(), (var1, var2) -> { Log.i(TAG, "onCreate: 开锁返回码: " + var1 + "--------------返回消息: " + Arrays.asList(var2)); MqttMessage mqttMessage; if (var1 != 0) { try { mqttMessage = wrapMessage(message, objectMapper); ichPublishClient.publish(String.format(ICHTopic.CALLBACK_FAILED, BaseUtils.getClientId()), mqttMessage); } catch (JsonProcessingException e) { Log.e(TAG, "onCreate: ---------------------序列化开锁错误消息失败! ", e); } catch (Exception e) { Log.e(TAG, "onCreate: ---------------------未知错误! ", e); } } else { // TODO 暂时不做 成功需要不断去请求查询锁是否关闭, 关闭后推送成功消息 Log.i(TAG, "onCreate: -------------------------开锁成功"); // AtomicBoolean atomicBoolean = new AtomicBoolean(true); // AtomicInteger atomicInteger = new AtomicInteger(5); // do { // try { // TimeUnit.SECONDS.sleep(30); // } catch (InterruptedException e) { // Log.e(TAG, "onCreate: 等待查询锁状态时线程中断! ", e); // } // DeviceControl.queryLocker(message.getSection(), message.getPort(), (var3, var4) -> { // List strings = Arrays.asList(var4); // if (var3 == 0 && strings.size() > 0 && !strings.get(0).equals("locked")) { // atomicBoolean.set(false); // } // atomicInteger.decrementAndGet(); // }); // if (atomicInteger.get() <= 0) { // atomicBoolean.set(false); // } // } while(atomicBoolean.get()); try { mqttMessage = wrapMessage(message, objectMapper); // if (atomicInteger.get() <= 0) { // message.setCause("长时间未关闭柜门!"); // mqttMessage.setPayload(objectMapper.writeValueAsBytes(message)); // ichPublishClient.publish(String.format(ICHTopic.CALLBACK_FAILED, BaseUtils.getClientId()), mqttMessage); // } ichPublishClient.publish(String.format(ICHTopic.CALLBACK_SUCCESS, BaseUtils.getClientId()), mqttMessage); } catch (JsonProcessingException e) { Log.e(TAG, "onCreate: ---------------------序列化开锁成功消息失败! ", e); } catch (RuntimeException e) { Log.e(TAG, "onCreate: ---------------------未知错误! ", e); } } }); }); // 注册柜子信息 // String appVersion = BaseUtils.getAppVersion(getApplicationContext()); // String androidVersion = BaseUtils.getVersionName(); // CountDownLatch countDownLatch = new CountDownLatch(10); // Cabinet cabinet = DeviceControl.queryCabinetInfo(countDownLatch); // try { // countDownLatch.await(); // } catch (InterruptedException e) { // e.printStackTrace(); // } // // cabinet.setClientId(clientId); // cabinet.setSoftwareVersion(appVersion); // cabinet.setAndroidVersion(androidVersion); // cabinet.setSoftwareType("android"); // cabinet.setImei(BaseUtils.getIMEI(getApplicationContext())); // cabinet.setMacIpv4("111"); // cabinet.setMacIpv6("unknown"); // cabinet.setNetType("111"); // cabinet.setPlatType("S905"); // cabinet.setSim("111"); // cabinet.setWifiSSid("111"); // // ObjectMapper objectMapper = JacksonUtils.objectmapper; // // try { // String jsonData = objectMapper.writeValueAsString(cabinet); // Log.i(TAG, "onCreate: jsonData===============>" + jsonData); // // MqttMessage message = new MqttMessage(); // message.setQos(1); // message.setPayload(jsonData.getBytes()); // ichPublishClient.publish(String.format(ICHTopic.CABINET_INFO_REPORT, clientId), message); // } catch (JsonProcessingException e) { // Log.e(TAG, "onCreate: 解析成JSON失败!", e); // } // TODO 更新版本监听 ichPublishClient.subscribe(String.format(ICHTopic.APK_UPDATE_PATH, BaseUtils.getClientId()), (msgId, msg) -> { try { String path = new String(msg.getPayload()); // 发起请求下载APK XUpdate.newBuild(this) .updateUrl(path) .isAutoMode(true) //如果需要完全无人干预,自动更新,需要root权限【静默安装需要】 .update(); // APKUpdateDownload.getInstance().downloadAPK(MainActivity.this, getApplication(), path); } catch (Exception e) { Log.e(TAG, "onCreate: 更新版本监听失败! ", e); } }); // TODO 监听shell命令脚本 ichPublishClient.subscribe(String.format(ICHTopic.EXECUTE_SHELL_SCRIPT, BaseUtils.getClientId()), (msgId, msg) -> { if (msg != null) { try { ShellVo shellVo = JacksonUtils.objectmapper.readValue(msg.getPayload(), ShellVo.class); ShellVo result = shellVo; if (shellVo != null && shellVo.getScript() != null && "".equals(shellVo.getScript()) && shellVo.getScript().length() > 0) { BaseUtils.executeShell(shellVo); } else { result = new ShellVo(); result.setResult("命令为空, 不可执行!"); } MqttMessage mqttMessage = new MqttMessage(); mqttMessage.setQos(1); mqttMessage.setPayload(JacksonUtils.objectmapper.writeValueAsString(result).getBytes()); ichPublishClient.publish(String.format(ICHTopic.EXECUTE_SHELL_SCRIPT_RESPONSE, BaseUtils.getClientId()), mqttMessage); } catch (Exception e) { Log.e(TAG, "onCreate: 发送执行脚本结果失败! ", e); } } }); } @Override public boolean dispatchKeyEvent(KeyEvent event) { if (null != scanGunKeyEventHelper) { scanGunKeyEventHelper.analysisKeyEvent(event); } return true; } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. // getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. // int id = item.getItemId(); // //noinspection SimplifiableIfStatement // if (id == R.id.action_settings) { // return true; // } return super.onOptionsItemSelected(item); } @Override public boolean onSupportNavigateUp() { NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main); return NavigationUI.navigateUp(navController, appBarConfiguration) || super.onSupportNavigateUp(); } private MqttMessage wrapMessage(Message message, ObjectMapper objectMapper) throws JsonProcessingException { MqttMessage mqttMessage = new MqttMessage(); Message failedMsg = new Message(); // TODO 失败原因枚举 failedMsg.setCause("失败原因枚举"); failedMsg.setMessageId(message.getMessageId()); failedMsg.setClientId(message.getClientId()); failedMsg.setCmd(message.getCmd()); failedMsg.setDatetime(message.getDatetime()); failedMsg.setPort(message.getPort()); failedMsg.setScene(message.getScene()); failedMsg.setSection(message.getSection()); mqttMessage.setQos(1); mqttMessage.setPayload(objectMapper.writeValueAsBytes(failedMsg)); return mqttMessage; } public Map getBundleMap() { return bundleMap; } public Map getConfigMap() { return configMap; } }