package com.paul.drone.util; import android.util.Log; import com.paul.drone.keyvalue.DroneTypeEnum; import dji.sdk.keyvalue.key.CameraKey; import dji.sdk.keyvalue.key.DJIKey; import dji.sdk.keyvalue.key.DJIKeyInfo; import dji.sdk.keyvalue.key.FlightControllerKey; import dji.sdk.keyvalue.key.ProductKey; import dji.sdk.keyvalue.key.RemoteControllerKey; import dji.sdk.keyvalue.value.camera.CameraType; import dji.sdk.keyvalue.value.common.LocationCoordinate2D; import dji.sdk.keyvalue.value.product.ProductType; import dji.v5.manager.KeyManager; import dji.v5.et.*; /** * 设备信息集中管理工具类 * 统一获取 serialNumber、productType、cameraType,并带缓存和异常兜底 */ public class DeviceInfoManager { private static final String TAG = "DeviceInfoManager"; private static volatile DeviceInfoManager INSTANCE; // 缓存属性 private String cachedSerialNumber; private String cachedProductType; private DeviceInfoManager() { // 私有构造函数 } /** * 获取单例实例 * @return DeviceInfoManager实例 */ public static DeviceInfoManager getInstance() { if (INSTANCE == null) { synchronized (DeviceInfoManager.class) { if (INSTANCE == null) { INSTANCE = new DeviceInfoManager(); } } } return INSTANCE; } /** * 清理缓存 */ public void clearCache() { cachedSerialNumber = null; cachedProductType = null; } // 默认重试次数 private static final int DEFAULT_RETRY_COUNT = 5; // 重试间隔时间(ms) private static final long RETRY_INTERVAL_MS = 1000; /** * 获取设备序列号 * @return 序列号字符串 */ public String getFlySerialNumber() { if (cachedSerialNumber != null) { return cachedSerialNumber; } String serialNumber = retryOperation(this::getFlightSerialNumber, DEFAULT_RETRY_COUNT, RETRY_INTERVAL_MS); if (!serialNumber.isEmpty()) { cachedSerialNumber = serialNumber; return serialNumber; } cachedSerialNumber = "暂无"; return cachedSerialNumber; } /** * 通用重试操作方法 * @param operation 要执行的操作 * @param maxRetries 最大重试次数 * @param retryIntervalMs 重试间隔(毫秒) * @return 操作结果 */ private T retryOperation(RetryableOperation operation, int maxRetries, long retryIntervalMs) { int retryCount = 0; T result; while (true) { try { result = operation.execute(); if (result != null && !isDefaultValue(result)) { return result; } } catch (Exception e) { Log.e(TAG, "Operation failed, retry count: " + retryCount, e); } retryCount++; if (retryCount >= maxRetries) { break; } try { Thread.sleep(retryIntervalMs); } catch (InterruptedException e) { Thread.currentThread().interrupt(); Log.e(TAG, "Retry interrupted", e); break; } } return null; } /** * 检查结果是否为默认值 * @param result 结果 * @return 是否为默认值 */ private boolean isDefaultValue(Object result) { if (result instanceof String) { return ((String) result).isEmpty() || "UNKNOWN".equals(result); } return result == null; } /** * 可重试操作接口 */ private interface RetryableOperation { T execute() throws Exception; } public LocationCoordinate2D getFightLocation(){ LocationCoordinate2D value = KeyManager.getInstance().getValue(DJIKey.create(FlightControllerKey.KeyHomeLocation)); // 先检查value是否为null if (value == null) { // 如果是null,创建一个新的LocationCoordinate2D实例 value = new LocationCoordinate2D(0.0, 0.0); } // 然后安全地设置坐标值 value.setLatitude(28.228079); value.setLongitude(112.938975); return value; } /** * 获取固件版本 * @return 固件版本字符串 */ public String getFirmwareVersion() { // 实际应用中应该从设备获取 // 这里返回模拟数据 return "1.0.0"; } /** 获取设备序列号,优先多种方式,带缓存 */ private String getFlightSerialNumber() throws Exception { KeyManager keyManager = KeyManager.getInstance(); if (keyManager == null) { throw new Exception("KeyManager is null"); } //return "ADFD186ASDFLWIXUE"; // 1. ProductKey.KeySerialNumber String productSN = keyManager.getValue(DJIKey.create(ProductKey.KeySerialNumber)); if (productSN != null && !productSN.isEmpty()) { return productSN; } // // 2. FlightControllerKey.KeySerialNumber String fcSN = keyManager.getValue(DJIKey.create(FlightControllerKey.KeySerialNumber)); if (fcSN != null && !fcSN.isEmpty()) { return fcSN; } throw new Exception("Failed to get serial number from all sources"); } public String getRemoteSerialNumber() { KeyManager keyManager = KeyManager.getInstance(); if (keyManager == null) { return "UNKNOWN"; } // 1. RemoteControllerKey.KeyProductSerialNumber try { String productSN = keyManager.getValue(DJIKey.create(RemoteControllerKey.KeyProductSerialNumber)); if (productSN != null && !productSN.isEmpty()) { return productSN; } } catch (Exception e) { Log.e(TAG, "RemoteControllerKey.KeyProductSerialNumber error", e); } return "UNKNOWN"; } /** 获取产品类型,带缓存 */ public String getProductType() { if (cachedProductType != null) { return cachedProductType; } KeyManager keyManager = KeyManager.getInstance(); if (keyManager == null) { cachedProductType = "UNKNOWN"; return cachedProductType; } try { ProductType value = keyManager.getValue(DJIKey.create(ProductKey.KeyProductType)); String name = value.name(); cachedProductType = name; return name; } catch (Exception e) { Log.e(TAG, "ProductType error", e); cachedProductType = "UNKNOWN"; return cachedProductType; } } /** 获取相机类型 */ public String getCameraType(int cameraIndex) { KeyManager keyManager = KeyManager.getInstance(); if (keyManager == null) { return "UNKNOWN"; } try { CameraType value = keyManager.getValue(DJIKey.create(CameraKey.KeyCameraType)); String name = value.name(); return name; } catch (Exception e) { Log.e(TAG, "CameraType error", e); return "UNKNOWN"; } } /** * 获取产品型号或子型号(相机型号) * - 如果是 DJI_MATRICE_400、M300_RTK、M350_RTK,返回产品型号 name * - 否则,返回 CameraType 的 name(如果有),否则返回产品型号 name */ public String getProductOrCameraType(int cameraIndex) { KeyManager keyManager = KeyManager.getInstance(); if (keyManager == null) { return "UNKNOWN"; } ProductType productType = null; try { productType = keyManager.getValue(DJIKey.create(ProductKey.KeyProductType)); } catch (Exception e) { Log.e(TAG, "ProductType error", e); } String productTypeName = (productType != null) ? productType.name() : "UNKNOWN"; if (productType == ProductType.DJI_MATRICE_400 || productType == ProductType.M300_RTK || productType == ProductType.M350_RTK) { return productTypeName; } else { String cameraTypeName = null; try { CameraType value = keyManager.getValue(DJIKey.create(CameraKey.KeyCameraType)); cameraTypeName = value.name(); } catch (Exception e) { Log.e(TAG, "CameraType error", e); } if (cameraTypeName != null && !cameraTypeName.isEmpty() && !cameraTypeName.equals("UNKNOWN")) { return cameraTypeName; } else { return productTypeName; } } } public String getModelByDroneTypeEnum(int cameraIndex) { KeyManager keyManager = KeyManager.getInstance(); if (keyManager == null) { return "UNKNOWN"; } ProductType productType = null; try { productType = keyManager.getValue(DJIKey.create(ProductKey.KeyProductType)); } catch (Exception e) { Log.e(TAG, "ProductType error", e); } if (productType == ProductType.DJI_MATRICE_400 || productType == ProductType.M300_RTK || productType == ProductType.M350_RTK) { String productTypeName = productType.name(); for (DroneTypeEnum droneType : DroneTypeEnum.values()) { if (droneType.getDroneType().equals(productTypeName)) { return droneType.getModel(); } } return ""; } else { try { CameraType value = keyManager.getValue(DJIKey.create(CameraKey.KeyCameraType)); String cameraTypeName = value.name(); for (DroneTypeEnum droneType : DroneTypeEnum.values()) { if (droneType.getDroneType().equals(cameraTypeName)) { return droneType.getModel(); } } } catch (Exception e) { Log.e(TAG, "CameraType error", e); } return "UNKNOWN"; } } public String getTypeByDroneTypeEnum(int cameraIndex) { if (cachedProductType != null) { // 使用缓存的产品类型进行查找 for (DroneTypeEnum droneType : DroneTypeEnum.values()) { if (droneType.getDroneType().equals(cachedProductType)) { return droneType.getDroneType(); } } } // 没有缓存或缓存不匹配,进行重试获取 String result = retryOperation(() -> getTypeByDroneTypeEnumInternal(cameraIndex), DEFAULT_RETRY_COUNT, RETRY_INTERVAL_MS); return result != null ? result : "暂无"; } /** * getTypeByDroneTypeEnum的内部实现 */ private String getTypeByDroneTypeEnumInternal(int cameraIndex) throws Exception { KeyManager keyManager = KeyManager.getInstance(); if (keyManager == null) { throw new Exception("KeyManager is null"); } ProductType productType = keyManager.getValue(DJIKey.create(ProductKey.KeyProductType)); if (productType == null) { throw new Exception("ProductType is null"); } if (productType == ProductType.DJI_MATRICE_400 || productType == ProductType.M300_RTK || productType == ProductType.M350_RTK) { String productTypeName = productType.name(); for (DroneTypeEnum droneType : DroneTypeEnum.values()) { if (droneType.getDroneType().equals(productTypeName)) { cachedProductType = productTypeName; return droneType.getDroneType(); } } throw new Exception("No matching DroneTypeEnum for productType: " + productTypeName); } else { CameraType cameraType = keyManager.getValue(DJIKey.create(CameraKey.KeyCameraType)); if (cameraType == null) { throw new Exception("CameraType is null"); } String cameraTypeName = cameraType.name(); for (DroneTypeEnum droneType : DroneTypeEnum.values()) { if (droneType.getDroneType().equals(cameraTypeName)) { return droneType.getDroneType(); } } throw new Exception("No matching DroneTypeEnum for cameraType: " + cameraTypeName); } } }