You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

759 lines
30 KiB
Java

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package com.xypower.mpremote;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import android.annotation.SuppressLint;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.database.Cursor;
import android.net.ConnectivityManager;
import android.os.Bundle;
import android.os.Handler;
import android.text.Html;
import android.text.TextUtils;
import android.text.format.Formatter;
import android.util.Base64;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
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.databinding.ActivityDeviceBinding;
import com.xypower.mpremote.databinding.ActivityMainBinding;
import com.xypower.mpremote.utils.AdbUtils;
import org.json.JSONObject;
import java.io.File;
import java.net.Socket;
import java.nio.charset.Charset;
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.AdbKeyPair;
import dadb.AdbShellResponse;
import dadb.Dadb;
public class DeviceActivity extends AppCompatActivity {
private static final String TAG = "ADB";
private static final boolean DEBUG = false;
public static final int RSSI_LEVELS = 5;
private static final String PACKAGE_NAME_MP = "com.xypower.mpapp";
private static final String REMOTE_PATH_ROOT = "/sdcard/" + PACKAGE_NAME_MP + "/";
private static final String REMOTE_PATH_DATA = REMOTE_PATH_ROOT + "data/";
private static final String REMOTE_PATH_DATA_CHANNELS = REMOTE_PATH_ROOT + "data/channels/";
private static final String REMOTE_PATH_PHOTOS = REMOTE_PATH_ROOT + "photos/";
private static final String REMOTE_PATH_TMP = REMOTE_PATH_ROOT + "tmp/";
private static final String KEY_APP_BV = "app.bv";
private static final String KEY_APP_BCV = "app.bcv";
private static final String KEY_RO_SERIALNO = "ro.serialno";
private static final String KEY_RO_CUSTOM_OTA_VERSION = "ro.custom.ota.version";
private static final String KEY_RO_MODEMS_MAX_COUNT = "telephony.active_modems.max_count";
// ro.telephony.sim.count
private static final String KEY_RO_SIGNAL_STRNGTH_PREFIX = "vendor.ril.nw.signalstrength.lte.";
private static final String KEY_RO_ICCID_PREFIX = "persist.vendor.radio.cfu.iccid.";
private static final String KEY_GSM_VENDOR_NAME = "gsm.operator.alpha";
// private static final String KEY_RO_MODEMS_MAX_COUNT = "telephony.active_modems.max_count";
// // [ro.bootimage.build.date.utc]: [1716880263]
// // [ro.build.date.utc]: [1716880263]
// // [ro.product.model]: [MSRDT-1-WP]
// // [ro.serialno]: [XYV12WPC202406215]
// // [telephony.active_modems.max_count]: [2]
// // [vendor.ril.nw.signalstrength.lte.1]: [-93,-2]
// //[vendor.ril.nw.signalstrength.lte.2]: [-103,21]
private static final String KEY_APP_MP_VERSION = "mpapp.version";
private static final String KEY_PREFIX_GLOBAL_SETTING = "settings.global.";
private static final String KEY_IMEI = KEY_PREFIX_GLOBAL_SETTING + "dev_imei";
private static final String KEY_IMEI2 = KEY_PREFIX_GLOBAL_SETTING + "dev_imei2";
private static final int ADB_SERVER_PORT = 5555;
// [vendor.ril.nw.signalstrength.lte.1]: [-85,27]
//[vendor.ril.nw.signalstrength.lte.2]: [-86,27]
private ActivityDeviceBinding binding;
private ProgressDialog mProgressDialog;
private Handler mHandler;
private String mDeviceIp;
private AdbKeyPair mAdbKeyPair;
private Map<String, String> mProps = new HashMap<>();
private Map<Integer, JSONObject> mChannelCfgs = new HashMap();
private String mSerialNo = "";
private MicroPhotoContext.AppConfig mAppConfig;
private int mBatteryVoltage = -1;
private int mBatteryChargingVoltage = -1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityDeviceBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
// actionBar.setTitle(R.string.title_activity_device);
Intent intent = getIntent();
mDeviceIp = intent.getStringExtra("deviceIp");
mHandler = new Handler();
File file = new File(getFilesDir(), ".keypair");
if (!file.exists()) {
file.mkdirs();
}
final File pubKeyFile = new File(file, "pub.key");
final File priKeyFile = new File(file, "pri.key");
if (!priKeyFile.exists() || !pubKeyFile.exists()) {
AdbKeyPair.generate(priKeyFile, pubKeyFile);
}
mAdbKeyPair = AdbKeyPair.read(priKeyFile, pubKeyFile);
final Context context = getApplicationContext();
binding.takePhoto1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
takePhoto(1, 255, true);
}
});
binding.takeVideo1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
takeVideo(1, 255, false);
}
});
loadDeviceInfo(context, true);
}
protected void loadDeviceInfo(final Context context, boolean firstConnect) {
binding.deviceInfo.setText("");
String msg = firstConnect ? "连接" + mDeviceIp + "中" : "刷新数据中";
mProgressDialog = ProgressDialog.show(this, "", msg, true, true);
mProgressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialogInterface) {
DeviceActivity.this.finish();
}
});
final File fileTmp = new File(getFilesDir(), "tmp");
if (!fileTmp.exists()) {
fileTmp.mkdirs();
}
(new Thread(new Runnable() {
@Override
public void run() {
try {
runImpl();
} catch (Exception ex) {
ex.printStackTrace();
}
mHandler.post(new Runnable() {
@Override
public void run() {
mProgressDialog.dismiss();
showAppInfo();
}
});
}
private void runImpl() {
Log.d(TAG, "Adb discovering " + mDeviceIp);
// Dadb adb = Dadb.discover(mDeviceIp, mAdbKeyPair);
Dadb adb = Dadb.create(mDeviceIp, AdbUtils.DEFAULT_ADB_PORT, mAdbKeyPair);
Log.d(TAG, "Adb Connected");
if (adb == null) {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
Toast.makeText(DeviceActivity.this, R.string.err_dev_failed_to_connect, Toast.LENGTH_LONG).show();
}
}, 100);
return;
}
Log.d(TAG, mDeviceIp + " Connected");
boolean res = false;
File appConfigFile = new File(fileTmp, "App.json");
res = pullFile(adb, REMOTE_PATH_DATA + "App.json", appConfigFile);
if (res) {
final MicroPhotoContext.AppConfig appConfig = MicroPhotoContext.getMpAppConfig(context, appConfigFile.getAbsolutePath());
mAppConfig = appConfig;
DeviceActivity.this.mHandler.post(new Runnable() {
@Override
public void run() {
DeviceActivity.this.showAppInfo();
}
});
}
Log.d(TAG, "App.json Pulled");
final int numberOfChannels = (mAppConfig != null) ? mAppConfig.channels : 0;
mHandler.post(new Runnable() {
@Override
public void run() {
updateButtons(numberOfChannels);
}
});
mChannelCfgs.clear();
if (mAppConfig != null && mAppConfig.channels > 0) {
for (int channel = 1; channel <= mAppConfig.channels; channel++) {
String remoteFilePath = REMOTE_PATH_DATA_CHANNELS + Integer.toString(channel) + ".json";
File localFilePath = new File(fileTmp, Integer.toString(channel) + ".json");
if (localFilePath.exists()) {
localFilePath.delete();
}
res = pullFile(adb, remoteFilePath, localFilePath);
if (res) {
JSONObject channelJson = JSONUtils.loadJson(localFilePath.getAbsolutePath());
if (channelJson != null) {
mChannelCfgs.put(new Integer(channel), channelJson);
}
localFilePath.delete();
}
}
}
Log.d(TAG, "Channel config Pulled");
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(KEY_PREFIX_GLOBAL_SETTING + key, val);
}
}
}
Log.d(TAG, "Global settings Pulled");
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);
}
}
}
Log.d(TAG, "getprop Finished");
if (mProps.containsKey(KEY_RO_SERIALNO)) {
mSerialNo = (String)mProps.get(KEY_RO_SERIALNO);
}
// adb shell pm dump com.xypower.mpremote | grep "versionName"
adbShellResponse = null;
try {
adbShellResponse = adb.shell("pm dump " + 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(KEY_APP_MP_VERSION, val);
break;
}
}
}
Log.d(TAG, "Dump App version Finished");
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);
}
}
}
Log.d(TAG, "queryBatVol Finished");
}
})).start();
}
protected boolean pullFile(Dadb adb, String remoteFilePath, File localFilePath) {
if (localFilePath.exists()) {
localFilePath.delete();
}
Log.i(TAG, "PULL: " + remoteFilePath);
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 int channel, final int preset, 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 = Dadb.create(mDeviceIp, AdbUtils.DEFAULT_ADB_PORT, mAdbKeyPair);
Log.i(TAG, "Finish connecting " + mDeviceIp);
if (adb == null) {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
Toast.makeText(DeviceActivity.this, R.string.err_dev_failed_to_connect, Toast.LENGTH_LONG).show();
}
}, 100);
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) {
}
}
File localDevicePath = new File(getFilesDir(), "Photos" + File.separator + mSerialNo);
if (!localDevicePath.exists()) {
localDevicePath.mkdirs();
}
final File localFilePath = new File(localDevicePath, localFileName);
for (int idx = 0; idx < 10; idx++) {
boolean res = pullFile(adb, remoteFilePath, localFilePath);
if (res) {
mHandler.post(new Runnable() {
@Override
public void run() {
if (photoOrVideo) {
showPhoto(localFilePath.getAbsolutePath());
} else {
showVideo(localFilePath.getAbsolutePath());
}
}
});
break;
}
try {
Thread.sleep(1000);
} catch (Exception ex) {
ex.printStackTrace();
}
}
try {
// mAdb.shell("rm " + remoteFilePath);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
} finally {
try {
if (adb != null) {
adb.close();
}
} 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 = 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(" ", "\\\\ ");
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);
}
final String cmd = "am start -n " + PACKAGE_NAME_MP + "/" + PACKAGE_NAME_MP + ".BridgeActivity --es action \"take_photo\" --es path \""
+ remoteFilePath + "\" --ez usb " + usb + " --ei cameraId " + Integer.toString(cameraId) + " --ei channel "
+ Integer.toString(channel) + " --ei preset " + Integer.toString(preset) + " --es leftTopOsd \"" + leftTopOsd + "\"";
// adbShellResponse = null;
takePhotoImpl(cmd, channel, preset, fileName, remoteFilePath, photoOrVideo, 0);
return 0;
}
protected long takeVideo(int channel, int preset, final boolean photoOrVideo) {
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) + " ";
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 + "\"";
// adbShellResponse = null;
Log.d(TAG, cmd);
takePhotoImpl(cmd, channel, preset, fileName, remoteFilePath, photoOrVideo, duration * 1000);
return 0;
}
private void showPhoto(final String filePath) {
Intent intent = new Intent(this, ImageActivity.class);
intent.putExtra("path", filePath);
intent.putExtra("cmdid", TextUtils.isEmpty(mAppConfig.cmdid) ? "" : mAppConfig.cmdid);
// 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 updateButtons(int numberOfChannels) {
if (numberOfChannels > 0) {
binding.takePhoto1.setVisibility(View.VISIBLE);
binding.takeVideo1.setVisibility(View.VISIBLE);
}
if (numberOfChannels > 1) {
binding.takePhoto2.setVisibility(View.VISIBLE);
binding.takeVideo2.setVisibility(View.VISIBLE);
}
if (numberOfChannels > 2) {
binding.takePhoto3.setVisibility(View.VISIBLE);
binding.takeVideo3.setVisibility(View.VISIBLE);
}
if (numberOfChannels > 3) {
binding.takePhoto4.setVisibility(View.VISIBLE);
binding.takeVideo4.setVisibility(View.VISIBLE);
}
}
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() {
ActionBar actionBar = getSupportActionBar();
// 视频浏览,拍照,设备信息及状态查询(编号版本双SIM卡状态电池及太阳能电压等),可以参考东视
Resources resources = getResources();
// String buildTime = BuildConfig.BUILD_
// Date date = new Date(BuildConfig.BUILD_TIMESTAMP);
// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
String title = resources.getString(R.string.app_name);
if (!TextUtils.isEmpty(mAppConfig.cmdid)) {
title = mAppConfig.cmdid;
}
actionBar.setTitle(title);
StringBuilder stringBuilder = new StringBuilder();
ConnectivityManager mConnectivityManager;
if (mProps.containsKey(KEY_RO_SERIALNO)) {
String val = (String)mProps.get(KEY_RO_SERIALNO);
appendKeyValue(stringBuilder, "序列号", val, true);
}
if (mProps.containsKey(KEY_RO_CUSTOM_OTA_VERSION)) {
String val = (String)mProps.get(KEY_RO_CUSTOM_OTA_VERSION);
appendKeyValue(stringBuilder, "系统版本", val, true);
}
int numberOfSimcard = 0;
if (mProps.containsKey(KEY_RO_MODEMS_MAX_COUNT)) {
String val = (String)mProps.get(KEY_RO_MODEMS_MAX_COUNT);
numberOfSimcard = Integer.parseInt(val);
}
String signalLevel = "";
List<String> iccids = new ArrayList<>();
for (int idx = 1; idx <= numberOfSimcard; idx++) {
String key = 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 = 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, "CMDID", mAppConfig.cmdid, true);
appendKeyValue(stringBuilder, "主站", mAppConfig.server + ":" + Integer.toString(mAppConfig.port));
appendKeyValue(stringBuilder, "通道数", Integer.toString(mAppConfig.channels));
if (mProps.containsKey(KEY_APP_MP_VERSION)) {
String val = (String)mProps.get(KEY_APP_MP_VERSION);
appendKeyValue(stringBuilder, "APP版本", val);
}
String vendorName = "";
if (mProps.containsKey(KEY_GSM_VENDOR_NAME)) {
vendorName = mProps.get(KEY_GSM_VENDOR_NAME);
}
appendKeyValue(stringBuilder, "移动运营商", vendorName);
appendKeyValue(stringBuilder, "移动信号", signalLevel);
for (String iccid : iccids) {
appendKeyValue(stringBuilder, "ICCID", iccid);
}
if (mProps.containsKey(KEY_IMEI)) {
String val = (String)mProps.get(KEY_IMEI);
appendKeyValue(stringBuilder, "IMEI1", val);
}
if (mProps.containsKey(KEY_IMEI2)) {
String val = (String)mProps.get(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 + "<font color=\"red\"><b>" + val + "</b></font>");
} else {
stringBuilder.append(key + "" + val);
}
stringBuilder.append("<br>");
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.device_activity_actions, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
return false;
case R.id.action_refresh:
loadDeviceInfo(getApplicationContext(), false);
return false;
default:
return super.onOptionsItemSelected(item);
}
}
}