package com.xypower.mpremote; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.recyclerview.widget.GridLayoutManager; import android.annotation.SuppressLint; import android.app.AlertDialog; import android.content.Intent; import android.database.Cursor; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.text.Html; import android.text.TextUtils; import android.util.Base64; import android.util.Log; import android.view.View; import android.widget.Toast; import com.xypower.common.FilesUtils; import com.xypower.common.JSONUtils; import com.xypower.common.MicroPhotoContext; import com.xypower.mpremote.adapter.ItemAdapter; import com.xypower.mpremote.bean.ChannelBean; import com.xypower.mpremote.databinding.ActivityDeviceBinding; import com.xypower.mpremote.interfaces.OnItemClickListener; import com.xypower.mpremote.utils.AdbUtils; import com.xypower.mpremote.utils.AlertDialogUtils; import com.xypower.mpremote.utils.AppUtils; import com.xypower.mpremote.utils.FileUtils; import org.json.JSONObject; import java.io.File; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import dadb.AdbShellResponse; import dadb.Dadb; public class DeviceActivity extends AppCompatActivity implements View.OnClickListener, OnItemClickListener { private static final String TAG = "ADB"; public static final int RSSI_LEVELS = 5; private ActivityDeviceBinding binding; private Handler mHandler; private String mCmdId; private Map mProps = new HashMap<>();//存储从设备端获取的设备信息 private Map mChannelCfgs = new HashMap(); private String mSerialNo = ""; private MicroPhotoContext.AppConfig mAppConfig = new MicroPhotoContext.AppConfig(); private int mBatteryVoltage = -1; private int mBatteryChargingVoltage = -1; private String mDeviceIp; private String localIp; private String localtmpfilePath;//存放临时配置文件的目录 private String localphotofilePath;//存放照片配置文件的目录 private AlertDialog alertDialog; private ItemAdapter photoitemAdapter; private ArrayList channelList = new ArrayList<>();//用于存放通道信息 private ItemAdapter videoitemAdapter; private static final int photoAdapter = 1; private static final int videoAdapter = 2; private AlertDialog photoDialog; private String localAppPath; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = ActivityDeviceBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); initData(); initView(); initHandler(); initEvent(); } private void initHandler() { mHandler = new Handler(Looper.getMainLooper()) { @Override public void handleMessage(@NonNull Message msg) { switch (msg.what) { case 1: AlertDialogUtils.dismiss(alertDialog); showAppInfo(); break; case 2: Toast.makeText(DeviceActivity.this, R.string.err_dev_failed_to_connect, Toast.LENGTH_LONG).show(); break; case 3: updateRecycleView(channelList); break; case 4: AlertDialogUtils.dismiss(photoDialog); break; } } }; } private void initEvent() { //加载设备信息 loadDeviceInfo(true); } private void initView() { String versionName = AppUtils.getAppNameWithVersion(this); binding.toolbar.title.setText(versionName); photoitemAdapter = new ItemAdapter(); photoitemAdapter.setAdapterType(photoAdapter); photoitemAdapter.setOnClickListener(this); binding.recyclerViewPhoto.setAdapter(photoitemAdapter); binding.recyclerViewPhoto.setLayoutManager(new GridLayoutManager(this, 3)); videoitemAdapter = new ItemAdapter(); videoitemAdapter.setAdapterType(videoAdapter); videoitemAdapter.setOnClickListener(this); binding.recyclerViewVideo.setAdapter(videoitemAdapter); binding.recyclerViewVideo.setLayoutManager(new GridLayoutManager(this, 3)); binding.ytControl.setOnClickListener(this); binding.toolbar.back.setOnClickListener(this); binding.toolbar.refresh.setVisibility(View.VISIBLE); binding.toolbar.refresh.setOnClickListener(this); } private void initData() { Intent intent = getIntent(); mDeviceIp = intent.getStringExtra("deviceIp");// localIp = intent.getStringExtra("localIp");// //获取配置文件在本机的存储路径 localtmpfilePath = getFilesDir() + "/tmp/"; localphotofilePath = getFilesDir() + "/Photos/"; localAppPath = localtmpfilePath + "App.json"; FileUtils.createDir(localtmpfilePath); FileUtils.createDir(localphotofilePath); } @Override protected void onDestroy() { super.onDestroy(); AdbManager.releaseAdb(mDeviceIp); } protected void loadDeviceInfo(boolean firstConnect) { binding.deviceInfo.setText(""); String msg = firstConnect ? "连接" + mDeviceIp + "中" : "刷新数据中"; alertDialog = AlertDialogUtils.show(this, msg); new Thread(new Runnable() { @Override public void run() { try { runImpl(); } catch (Exception ex) { ex.printStackTrace(); } mHandler.sendMessage(mHandler.obtainMessage(1)); } }).start(); } private void runImpl() { Dadb adb = AdbManager.getAdb(mDeviceIp, AdbUtils.DEFAULT_ADB_PORT); if (adb == null) { mHandler.sendMessage(mHandler.obtainMessage(2)); return; } boolean res = false; File file = FileUtils.getFile(localAppPath); if (file != null) { //将远程文件/sdcard/com.xypower.mpapp/data/App.json下载到本地 res = pullFile(adb, Constants.REMOTE_PATH_APP, file); } if (res) { final MicroPhotoContext.AppConfig appConfig = MicroPhotoContext.getMpAppConfig(getApplicationContext(), localAppPath); if (appConfig != null) { mAppConfig = appConfig; } } mChannelCfgs.clear(); channelList.clear(); if (mAppConfig != null && mAppConfig.channels > 0) { for (int channel = 1; channel <= mAppConfig.channels; channel++) { ChannelBean channelBean = new ChannelBean(); channelBean.setChannel(channel); channelBean.setChannelname("通道" + channel); String remoteFilePath = Constants.REMOTE_PATH_DATA_CHANNELS + Integer.toString(channel) + ".json"; File channelfile = FileUtils.getFile(localtmpfilePath + Integer.toString(channel) + ".json"); res = pullFile(adb, remoteFilePath, channelfile); if (res) { JSONObject channelJson = JSONUtils.loadJson(channelfile.getAbsolutePath()); if (channelJson != null) { mChannelCfgs.put(new Integer(channel), channelJson); channelBean.setJsonObject(channelJson); } channelfile.delete(); } channelList.add(channelBean); } mHandler.sendMessage(mHandler.obtainMessage(3)); } AdbShellResponse adbShellResponse = null; try { adbShellResponse = adb.shell("settings list global"); } catch (Exception ex) { ex.printStackTrace(); } if (adbShellResponse.getExitCode() == 0) { String[] lines = FilesUtils.splitLines(adbShellResponse.getAllOutput()); for (String line : lines) { int pos = line.indexOf("="); if (pos != -1) { String key = line.substring(0, pos); String val = line.substring(pos + 1); mProps.put(Constants.KEY_PREFIX_GLOBAL_SETTING + key, val); } } } adbShellResponse = null; try { adbShellResponse = adb.shell("getprop"); } catch (Exception ex) { ex.printStackTrace(); } if (adbShellResponse.getExitCode() == 0) { String[] lines = FilesUtils.splitLines(adbShellResponse.getAllOutput()); for (String line : lines) { int pos = line.indexOf("]: ["); if (pos != -1) { String key = line.substring(1, pos); String val = line.substring(pos + 4, line.length() - 1); mProps.put(key, val); } } } if (mProps.containsKey(Constants.KEY_RO_SERIALNO)) { mSerialNo = (String) mProps.get(Constants.KEY_RO_SERIALNO); } // adb shell pm dump com.xypower.mpremote | grep "versionName" adbShellResponse = null; try { adbShellResponse = adb.shell("pm dump " + Constants.PACKAGE_NAME_MP + " | grep \"versionName\""); } catch (Exception ex) { ex.printStackTrace(); } if (adbShellResponse.getExitCode() == 0) { String[] lines = FilesUtils.splitLines(adbShellResponse.getAllOutput()); for (String line : lines) { int pos = line.indexOf("versionName="); if (pos != -1) { String val = line.substring(pos + 12); mProps.put(Constants.KEY_APP_MP_VERSION, val); break; } } } adbShellResponse = null; try { adbShellResponse = adb.shell("pm dump " + Constants.PACKAGE_NAME_MPMASTER + " | grep \"versionName\""); } catch (Exception ex) { ex.printStackTrace(); } if (adbShellResponse.getExitCode() == 0) { String[] lines = FilesUtils.splitLines(adbShellResponse.getAllOutput()); for (String line : lines) { int pos = line.indexOf("versionName="); if (pos != -1) { String val = line.substring(pos + 12); mProps.put(Constants.KEY_APP_MPMASTER_VERSION, val); break; } } } String cmd = "content query --uri content://com.xypower.mpapp.provider/queryBatVol"; adbShellResponse = null; try { adbShellResponse = adb.shell(cmd); } catch (Exception ex) { ex.printStackTrace(); } if (adbShellResponse.getExitCode() == 0) { Cursor cursor = AdbUtils.parseContentResponse(adbShellResponse.getAllOutput()); if (cursor != null && cursor.getCount() > 0) { cursor.moveToFirst(); @SuppressLint("Range") String bv = cursor.getString(cursor.getColumnIndex("bv")); @SuppressLint("Range") String bcv = cursor.getString(cursor.getColumnIndex("bcv")); if (!TextUtils.isEmpty(bv)) { mBatteryVoltage = Integer.parseInt(bv); } if (!TextUtils.isEmpty(bcv)) { mBatteryChargingVoltage = Integer.parseInt(bcv); } } } } private void updateRecycleView(ArrayList mChannelCfgs) { photoitemAdapter.setItemList(mChannelCfgs); videoitemAdapter.setItemList(mChannelCfgs); } protected boolean pullFile(Dadb adb, String remoteFilePath, File localFilePath) { if (localFilePath.exists()) { localFilePath.delete(); } boolean res = false; try { adb.pull(localFilePath, remoteFilePath); res = true; } catch (Exception ex) { ex.printStackTrace(); } return res && localFilePath.exists(); } protected void takePhotoImpl(final String cmd, final String localFileName, final String remoteFilePath, final boolean photoOrVideo, long sleepTime) { Thread th = new Thread(new Runnable() { @Override public void run() { Dadb adb = null; try { Log.i(TAG, "Start connecting " + mDeviceIp); adb = AdbManager.getAdb(mDeviceIp, AdbUtils.DEFAULT_ADB_PORT); Log.i(TAG, "Finish connecting " + mDeviceIp); if (adb == null) { mHandler.sendMessage(mHandler.obtainMessage(2)); return; } AdbShellResponse adbShellResponse = null; try { adbShellResponse = adb.shell(cmd); } catch (Exception ex) { ex.printStackTrace(); } if (adbShellResponse != null) { if (adbShellResponse.getExitCode() == 0) { if (sleepTime > 0) { try { Thread.sleep(sleepTime); } catch (Exception ex) { } } //按照装置编号创建文件夹 String dirPath = localphotofilePath + mSerialNo; boolean dir = FileUtils.createDir(dirPath); if (dir) { File file = FileUtils.getFile(dirPath + File.separator + localFileName); for (int idx = 0; idx < 10; idx++) { boolean res = pullFile(adb, remoteFilePath, file); if (res) { mHandler.sendMessage(mHandler.obtainMessage(4)); mHandler.post(new Runnable() { @Override public void run() { if (photoOrVideo) { showPhoto(file.getAbsolutePath(), dirPath); } else { showVideo(file.getAbsolutePath()); } } }); break; } try { Thread.sleep(1000); } catch (Exception ex) { ex.printStackTrace(); } } try { // mAdb.shell("rm " + remoteFilePath); } catch (Exception ex) { ex.printStackTrace(); } } } } } catch (Exception ex) { ex.printStackTrace(); } } }); th.start(); } protected long takePhoto(int channel, int preset, final boolean photoOrVideo) { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddhhmmss"); Date dt = new Date(); int cameraId = channel - 1; final String fileName = "IMG-" + Integer.toString(channel) + "-" + simpleDateFormat.format(dt) + (photoOrVideo ? ".jpg" : ".mp4"); final String remoteFilePath = Constants.REMOTE_PATH_TMP + fileName; String leftTopOsd = ""; if (mAppConfig != null) { leftTopOsd += mAppConfig.cmdid + " "; } SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); leftTopOsd += simpleDateFormat2.format(dt) + " "; leftTopOsd += "CH:" + Integer.toString(channel) + " "; // leftTopOsd = leftTopOsd.replaceAll("\\\\", "\\\\\\\\"); // leftTopOsd = leftTopOsd.replaceAll(" ", "\\\\ "); byte[] leftTopOsdBytes = leftTopOsd.getBytes(StandardCharsets.UTF_8); String usb = (channel == 4) ? "true" : "false"; JSONObject channelJson = (JSONObject) mChannelCfgs.get(Integer.valueOf(channel)); if (channelJson != null) { int usbCamera = channelJson.optInt("usbCamera", 0); usb = (usbCamera != 0) ? "true" : "false"; cameraId = channelJson.optInt("cameraId", cameraId); } // content update --uri content://com.xypower.mpapp.provider/importPriKey final String cmd = "content update --uri content://" + Constants.PACKAGE_NAME_MP + ".provider/takePhoto --bind path:s:\"" + remoteFilePath + "\" --bind usb:b:" + usb + " --bind cameraId:i:" + Integer.toString(cameraId) + " --bind channel:i:" + Integer.toString(channel) + " --bind preset:i:" + Integer.toString(preset) + " --bind leftTopOsd:s:" + Base64.encodeToString(leftTopOsdBytes, Base64.DEFAULT | Base64.NO_WRAP) + ""; // adbShellResponse = null; photoDialog = AlertDialogUtils.show(this, "照片或视频获取中"); takePhotoImpl(cmd, fileName, remoteFilePath, photoOrVideo, 0); return 0; } protected long takeVideo(int channel, int preset, final boolean photoOrVideo) { // int cameraId = channel - 1; // // String leftTopOsd = ""; // if (mAppConfig != null) { // leftTopOsd += mAppConfig.cmdid + " "; // } // // // leftTopOsd = leftTopOsd.replaceAll("\\\\", "\\\\\\\\"); // // leftTopOsd = leftTopOsd.replaceAll(" ", "\\\\ "); // byte[] leftTopOsdBytes = leftTopOsd.getBytes(StandardCharsets.UTF_8); // // String usb = (channel == 4) ? "true" : "false"; // JSONObject channelJson = (JSONObject) mChannelCfgs.get(Integer.valueOf(channel)); // if (channelJson != null) { // int usbCamera = channelJson.optInt("usbCamera", 0); // usb = (usbCamera != 0) ? "true" : "false"; // cameraId = channelJson.optInt("cameraId", cameraId); // } // // content update --uri content://com.xypower.mpapp.provider/importPriKey // final String cmd = "content update --uri content://" + Constants.PACKAGE_NAME_MP + ".provider/takePhoto " +" --bind usb:b:" + usb + " --bind cameraId:i:" + Integer.toString(cameraId) + " --bind channel:i:" + Integer.toString(channel) + " --bind preset:i:" + Integer.toString(preset) + " --bind leftTopOsd:s:" + Base64.encodeToString(leftTopOsdBytes, Base64.DEFAULT | Base64.NO_WRAP) + ""; // // adbShellResponse = null; // // photoDialog = AlertDialogUtils.show(this, "照片或视频获取中"); showStreaming(channel, channel - 1, "rtmp://" + mDeviceIp + "/live/0", localIp); // showStreaming(channel, channel - 1, "rtsp://61.169.135.146:1554/live/11", localIp); return 0; /* SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddhhmmss"); Date dt = new Date(); int cameraId = channel - 1; int duration = 5; String leftTopOsd = ""; if (mAppConfig != null) { leftTopOsd += mAppConfig.cmdid + " "; } SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); leftTopOsd += simpleDateFormat2.format(dt) + " "; leftTopOsd += "CH:" + Integer.toString(channel) + " "; byte[] leftTopOsdBytes = leftTopOsd.getBytes(StandardCharsets.UTF_8); final String fileName = "IMG-" + Integer.toString(channel) + "-" + simpleDateFormat.format(dt) + (photoOrVideo ? ".jpg" : ".mp4"); final String remoteFilePath = REMOTE_PATH_TMP + fileName; // int quality = intent.getIntExtra("quality", 0); // int width = intent.getIntExtra("width", 1280); // int height = intent.getIntExtra("height", 720); // int duration = intent.getIntExtra("duration", 15); // int orientation = intent.getIntExtra("orientation", 0); // long videoId = System.currentTimeMillis() / 1000; // // String leftTopOsd = intent.getStringExtra("leftTopOsd"); // String rightTopOsd = intent.getStringExtra("rightTopOsd"); // String rightBottomOsd = intent.getStringExtra("rightBottomOsd"); // String leftBottomOsd = intent.getStringExtra("leftBottomOsd"); int width = 1280; int height = 720; String usb = (channel == 4) ? "true" : "false"; JSONObject channelJson = (JSONObject) mChannelCfgs.get(Integer.valueOf(channel)); if (channelJson != null) { int usbCamera = channelJson.optInt("usbCamera", 0); usb = (usbCamera != 0) ? "true" : "false"; cameraId = channelJson.optInt("cameraId", cameraId); width = channelJson.optInt("videoCX", width); height = channelJson.optInt("videoCY", height); } //final String cmd = "am start -n " + PACKAGE_NAME_MP + "/" + PACKAGE_NAME_MP + ".BridgeActivity --es action \"recording\" --es path \"" // + remoteFilePath + "\" --ez usb " + usb + " --ei cameraId " + Integer.toString(cameraId) + " --ei channel " // + Integer.toString(channel) + " --ei preset " + Integer.toString(preset) + " --ei duration " + Integer.toString(duration) // + " --el videoId " + Long.toString(dt.getTime() / 1000) + " --ei width " + Integer.toString(height) + " --ei height " // + Integer.toString(height) + " --es leftTopOsd \"" + leftTopOsd + "\""; final String cmd = "content update --uri content://" + PACKAGE_NAME_MP + ".provider/takeVideo --bind path:s:\"" + remoteFilePath + "\" --bind usb:b:" + usb + " --bind cameraId:i:" + Integer.toString(cameraId) + " --bind channel:i:" + Integer.toString(channel) + " --bind preset:i:" + Integer.toString(preset) + " --bind duration:i:" + Integer.toString(duration) + " --bind videoId:l:" + Long.toString(dt.getTime() / 1000) + " --bind width:i:" + Integer.toString(width) + " --bind height:i:" + Integer.toString(height) + " --bind leftTopOsd:s:" + Base64.encodeToString(leftTopOsdBytes, Base64.DEFAULT | Base64.NO_WRAP) + ""; // adbShellResponse = null; Log.d(TAG, cmd); takePhotoImpl(cmd, channel, preset, fileName, remoteFilePath, photoOrVideo, duration * 1000); return 0; */ } private void showPhoto(final String filePath, String path) { Intent intent = new Intent(this, ImageActivity.class); intent.putExtra("path", filePath); intent.putExtra("cmdid", TextUtils.isEmpty(mAppConfig.cmdid) ? "" : mAppConfig.cmdid); intent.putExtra("photodirpath", path); // intent.putExtra("info", info); startActivity(intent); } private void showVideo(final String filePath) { Intent intent = new Intent(DeviceActivity.this, VideoActivity.class); intent.putExtra("path", filePath); // intent.putExtra("info", info); startActivity(intent); } private void showStreaming(int channel, int cameraId, final String url, String localIp) { int rotation = -1; int usb = 0; int netCamera = 0; int vendor = 0; int selfTestingTime = 0; Integer chVal = Integer.valueOf(channel); if (mChannelCfgs.containsKey(chVal)) { JSONObject jsonChannel = mChannelCfgs.get(chVal); if (jsonChannel != null) { int orientation = jsonChannel.optInt("orientation", 0); if (orientation > 0) { rotation = (orientation - 1) * 90; } else if (orientation == 0) { rotation = 90; } int cameraType = jsonChannel.optInt("cameraType", 0); usb = (cameraType == 1) ? 1 : 0; netCamera = (cameraType == 2 || cameraType == 4) ? 1 : 0; vendor = jsonChannel.optInt("vendor", 0); selfTestingTime = jsonChannel.optInt("selfTestingTime", 0); } } Intent intent = new Intent(this, StreamActivity.class); intent.putExtra("url", url); intent.putExtra("localIp", localIp); intent.putExtra("deviceIp", mDeviceIp); intent.putExtra("cameraId", cameraId); intent.putExtra("channel", channel); intent.putExtra("rotation", rotation); intent.putExtra("netCamera", netCamera); intent.putExtra("vendor", vendor); intent.putExtra("usb", usb); intent.putExtra("cmdid", TextUtils.isEmpty(mAppConfig.cmdid) ? "" : mAppConfig.cmdid); intent.putExtra("selfTestingTime", selfTestingTime); startActivity(intent); } public static int calculateSignalLevel(int rsrp, int numLevels) { int signalLevel = 0; if (rsrp >= -97) { signalLevel = 4; } else if (rsrp >= -107) { signalLevel = 3; } else if (rsrp >= -117) { signalLevel = 2; } else if (rsrp >= -125) { signalLevel = 1; } else if (rsrp >= -140) { signalLevel = 0; } return signalLevel; } private void showAppInfo() { // 视频浏览,拍照,设备信息及状态查询(编号,版本,双SIM卡状态,电池及太阳能电压等),可以参考东视 StringBuilder stringBuilder = new StringBuilder(); if (mProps.containsKey(Constants.KEY_RO_SERIALNO)) { String val = (String) mProps.get(Constants.KEY_RO_SERIALNO); appendKeyValue(stringBuilder, "序列号", val, true); } if (mProps.containsKey(Constants.KEY_RO_CUSTOM_OTA_VERSION)) { String val = (String) mProps.get(Constants.KEY_RO_CUSTOM_OTA_VERSION); appendKeyValue(stringBuilder, "系统版本", val, true); } appendKeyValue(stringBuilder, "CMDID", mAppConfig.cmdid, true); appendKeyValue(stringBuilder, "主站", (TextUtils.isEmpty(mAppConfig.server) ? "" : mAppConfig.server) + ":" + Integer.toString(mAppConfig.port)); appendKeyValue(stringBuilder, "通道数", Integer.toString(mAppConfig.channels)); if (mProps.containsKey(Constants.KEY_APP_MP_VERSION)) { String val = (String) mProps.get(Constants.KEY_APP_MP_VERSION); appendKeyValue(stringBuilder, "MpAPP版本", val); } if (mProps.containsKey(Constants.KEY_APP_MPMASTER_VERSION)) { String val = (String) mProps.get(Constants.KEY_APP_MPMASTER_VERSION); appendKeyValue(stringBuilder, "MpMaster版本", val); } String vendorName = ""; if (mProps.containsKey(Constants.KEY_GSM_VENDOR_NAME)) { vendorName = mProps.get(Constants.KEY_GSM_VENDOR_NAME); } appendKeyValue(stringBuilder, "移动运营商", vendorName); int numberOfSimcard = 0; if (mProps.containsKey(Constants.KEY_RO_MODEMS_MAX_COUNT)) { String val = (String) mProps.get(Constants.KEY_RO_MODEMS_MAX_COUNT); numberOfSimcard = Integer.parseInt(val); } String signalLevel = ""; List iccids = new ArrayList<>(); for (int idx = 1; idx <= numberOfSimcard; idx++) { String key = Constants.KEY_RO_SIGNAL_STRNGTH_PREFIX + Integer.toString(idx); if (mProps.containsKey(key)) { String val = (String) mProps.get(key); int pos = val.indexOf(","); if (pos != -1) { String ss = val.substring(0, pos); int signalStrength = Integer.parseInt(ss); int sl = calculateSignalLevel(signalStrength, RSSI_LEVELS); if (!TextUtils.isEmpty(signalLevel)) { signalLevel += "/"; } signalLevel += ss + "," + Integer.toString(sl); } } key = Constants.KEY_RO_ICCID_PREFIX + Integer.toString(idx - 1); if (mProps.containsKey(key)) { String val = (String) mProps.get(key); byte[] bytes = Base64.decode(val, Base64.DEFAULT); String str = new String(bytes, Charset.defaultCharset()); iccids.add(str); } } appendKeyValue(stringBuilder, "移动信号", signalLevel); for (String iccid : iccids) { appendKeyValue(stringBuilder, "ICCID", iccid); } if (mProps.containsKey(Constants.KEY_IMEI)) { String val = (String) mProps.get(Constants.KEY_IMEI); appendKeyValue(stringBuilder, "IMEI1", val); } if (mProps.containsKey(Constants.KEY_IMEI2)) { String val = (String) mProps.get(Constants.KEY_IMEI2); appendKeyValue(stringBuilder, "IMEI2", val); } if (mBatteryVoltage != -1) { appendKeyValue(stringBuilder, "电池电压", Integer.toString(mBatteryVoltage / 1000) + "." + Integer.toString((mBatteryVoltage % 1000) / 100)); } if (mBatteryChargingVoltage != -1) { appendKeyValue(stringBuilder, "充电电压", Integer.toString(mBatteryChargingVoltage / 1000) + "." + Integer.toString((mBatteryChargingVoltage % 1000) / 100)); } binding.deviceInfo.setText(Html.fromHtml(stringBuilder.toString())); } private void appendKeyValue(StringBuilder stringBuilder, String key, String val) { appendKeyValue(stringBuilder, key, val, false); } private void appendKeyValue(StringBuilder stringBuilder, String key, String val, boolean highlignt) { if (highlignt) { stringBuilder.append(key + ":" + (TextUtils.isEmpty(val) ? "" : val) + ""); } else { stringBuilder.append(key + ":" + (TextUtils.isEmpty(val) ? "" : val)); } stringBuilder.append("
"); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.back: finish(); break; case R.id.refresh: loadDeviceInfo(false); break; } } @Override public void onItemClick(View v, ChannelBean bean, int adapterType) { if (adapterType == photoAdapter) { takePhoto(bean.getChannel(), 255, true); } else if (adapterType == videoAdapter) { takeVideo(bean.getChannel(), 255, false); } } }