diff --git a/app/src/main/java/com/ttstd/dialer/bean/req/SnSystemInfoReq.java b/app/src/main/java/com/ttstd/dialer/bean/req/SnSystemInfoReq.java index f2571e1..e7a2841 100644 --- a/app/src/main/java/com/ttstd/dialer/bean/req/SnSystemInfoReq.java +++ b/app/src/main/java/com/ttstd/dialer/bean/req/SnSystemInfoReq.java @@ -3,118 +3,197 @@ package com.ttstd.dialer.bean.req; import com.google.gson.annotations.SerializedName; import java.io.Serializable; +import java.math.BigDecimal; /** * 设备基本信息上传请求。 *
* 对应后端 {@code POST /api/v1/sn/update_system_info}, - * 字段与后端 {@code SnSystemInfoReq} 一一对应。 - *
- * 注意:该类原名为 SnHardwareInfoReq,但其字段(sn_imei/sn_model/sn_brand 等)
- * 实际对应的是后端的「基本信息」而非「硬件信息」,故更名以避免与新增的
- * {@link SnHardwareInfoReq}(CPU/内存/电池/GPU)混淆。
+ * 字段与后端 {@code DeviceSystemInfoVO} / {@code SnDeviceSystemInfo} 一一对应。
*/
public class SnSystemInfoReq implements Serializable {
private static final long serialVersionUID = 2728925136862797858L;
- @SerializedName("sn_imei")
- private String imei;
+ @SerializedName("device_name")
+ private String deviceName;
- @SerializedName("sn_imsi")
- private String imsi;
+ @SerializedName("device_brand")
+ private String deviceBrand;
- @SerializedName("sn_wlan_mac")
- private String wlanMac;
+ @SerializedName("device_model")
+ private String deviceModel;
- @SerializedName("sn_device_mac")
- private String deviceMac;
+ @SerializedName("device_board")
+ private String deviceBoard;
- @SerializedName("sn_bluetooth_mac")
- private String bluetoothMac;
+ @SerializedName("device_manufacturer")
+ private String deviceManufacturer;
- @SerializedName("sn_model")
- private String model;
+ @SerializedName("hardware")
+ private String hardware;
- @SerializedName("sn_brand")
- private String brand;
+ @SerializedName("host")
+ private String host;
- @SerializedName("sn_board")
- private String board;
-
- @SerializedName("sn_android_version")
+ @SerializedName("android_version")
private String androidVersion;
- @SerializedName("sn_android_api")
- private int androidApi;
+ @SerializedName("android_api")
+ private Integer androidApi;
- @SerializedName("sn_build_id")
+ @SerializedName("android_id")
+ private String androidId;
+
+ @SerializedName("build_id")
private String buildId;
- @SerializedName("sn_build_display_id")
+ @SerializedName("build_display_id")
private String buildDisplayId;
- public String getImei() {
- return imei;
+ @SerializedName("build_fingerprint")
+ private String buildFingerprint;
+
+ @SerializedName("build_type")
+ private String buildType;
+
+ @SerializedName("build_user")
+ private String buildUser;
+
+ @SerializedName("build_host")
+ private String buildHost;
+
+ @SerializedName("build_tags")
+ private String buildTags;
+
+ @SerializedName("build_time")
+ private String buildTime;
+
+ @SerializedName("language")
+ private String language;
+
+ @SerializedName("timezone")
+ private String timezone;
+
+ @SerializedName("boot_time")
+ private String bootTime;
+
+ @SerializedName("screen_resolution")
+ private String screenResolution;
+
+ @SerializedName("screen_density")
+ private Integer screenDensity;
+
+ @SerializedName("kernel_version")
+ private String kernelVersion;
+
+ @SerializedName("rom_version")
+ private String romVersion;
+
+ @SerializedName("product_name")
+ private String productName;
+
+ @SerializedName("product_model")
+ private String productModel;
+
+ @SerializedName("product_device")
+ private String productDevice;
+
+ @SerializedName("board_platform")
+ private String boardPlatform;
+
+ @SerializedName("device_type")
+ private String deviceType;
+
+ @SerializedName("is_tablet")
+ private Integer isTablet;
+
+ @SerializedName("release_version")
+ private String releaseVersion;
+
+ @SerializedName("display_version")
+ private String displayVersion;
+
+ @SerializedName("bootloader")
+ private String bootloader;
+
+ @SerializedName("baseband_version")
+ private String basebandVersion;
+
+ @SerializedName("radio_version")
+ private String radioVersion;
+
+ @SerializedName("screen_size")
+ private String screenSize;
+
+ @SerializedName("screen_inch")
+ private BigDecimal screenInch;
+
+ @SerializedName("refresh_rate")
+ private Integer refreshRate;
+
+ @SerializedName("os_type")
+ private String osType;
+
+ @SerializedName("os_version")
+ private String osVersion;
+
+ @SerializedName("firmware_version")
+ private String firmwareVersion;
+
+ public String getDeviceName() {
+ return deviceName;
}
- public void setImei(String imei) {
- this.imei = imei;
+ public void setDeviceName(String deviceName) {
+ this.deviceName = deviceName;
}
- public String getImsi() {
- return imsi;
+ public String getDeviceBrand() {
+ return deviceBrand;
}
- public void setImsi(String imsi) {
- this.imsi = imsi;
+ public void setDeviceBrand(String deviceBrand) {
+ this.deviceBrand = deviceBrand;
}
- public String getWlanMac() {
- return wlanMac;
+ public String getDeviceModel() {
+ return deviceModel;
}
- public void setWlanMac(String wlanMac) {
- this.wlanMac = wlanMac;
+ public void setDeviceModel(String deviceModel) {
+ this.deviceModel = deviceModel;
}
- public String getDeviceMac() {
- return deviceMac;
+ public String getDeviceBoard() {
+ return deviceBoard;
}
- public void setDeviceMac(String deviceMac) {
- this.deviceMac = deviceMac;
+ public void setDeviceBoard(String deviceBoard) {
+ this.deviceBoard = deviceBoard;
}
- public String getBluetoothMac() {
- return bluetoothMac;
+ public String getDeviceManufacturer() {
+ return deviceManufacturer;
}
- public void setBluetoothMac(String bluetoothMac) {
- this.bluetoothMac = bluetoothMac;
+ public void setDeviceManufacturer(String deviceManufacturer) {
+ this.deviceManufacturer = deviceManufacturer;
}
- public String getModel() {
- return model;
+ public String getHardware() {
+ return hardware;
}
- public void setModel(String model) {
- this.model = model;
+ public void setHardware(String hardware) {
+ this.hardware = hardware;
}
- public String getBrand() {
- return brand;
+ public String getHost() {
+ return host;
}
- public void setBrand(String brand) {
- this.brand = brand;
- }
-
- public String getBoard() {
- return board;
- }
-
- public void setBoard(String board) {
- this.board = board;
+ public void setHost(String host) {
+ this.host = host;
}
public String getAndroidVersion() {
@@ -125,14 +204,22 @@ public class SnSystemInfoReq implements Serializable {
this.androidVersion = androidVersion;
}
- public int getAndroidApi() {
+ public Integer getAndroidApi() {
return androidApi;
}
- public void setAndroidApi(int androidApi) {
+ public void setAndroidApi(Integer androidApi) {
this.androidApi = androidApi;
}
+ public String getAndroidId() {
+ return androidId;
+ }
+
+ public void setAndroidId(String androidId) {
+ this.androidId = androidId;
+ }
+
public String getBuildId() {
return buildId;
}
@@ -148,4 +235,244 @@ public class SnSystemInfoReq implements Serializable {
public void setBuildDisplayId(String buildDisplayId) {
this.buildDisplayId = buildDisplayId;
}
+
+ public String getBuildFingerprint() {
+ return buildFingerprint;
+ }
+
+ public void setBuildFingerprint(String buildFingerprint) {
+ this.buildFingerprint = buildFingerprint;
+ }
+
+ public String getBuildType() {
+ return buildType;
+ }
+
+ public void setBuildType(String buildType) {
+ this.buildType = buildType;
+ }
+
+ public String getBuildUser() {
+ return buildUser;
+ }
+
+ public void setBuildUser(String buildUser) {
+ this.buildUser = buildUser;
+ }
+
+ public String getBuildHost() {
+ return buildHost;
+ }
+
+ public void setBuildHost(String buildHost) {
+ this.buildHost = buildHost;
+ }
+
+ public String getBuildTags() {
+ return buildTags;
+ }
+
+ public void setBuildTags(String buildTags) {
+ this.buildTags = buildTags;
+ }
+
+ public String getBuildTime() {
+ return buildTime;
+ }
+
+ public void setBuildTime(String buildTime) {
+ this.buildTime = buildTime;
+ }
+
+ public String getLanguage() {
+ return language;
+ }
+
+ public void setLanguage(String language) {
+ this.language = language;
+ }
+
+ public String getTimezone() {
+ return timezone;
+ }
+
+ public void setTimezone(String timezone) {
+ this.timezone = timezone;
+ }
+
+ public String getBootTime() {
+ return bootTime;
+ }
+
+ public void setBootTime(String bootTime) {
+ this.bootTime = bootTime;
+ }
+
+ public String getScreenResolution() {
+ return screenResolution;
+ }
+
+ public void setScreenResolution(String screenResolution) {
+ this.screenResolution = screenResolution;
+ }
+
+ public Integer getScreenDensity() {
+ return screenDensity;
+ }
+
+ public void setScreenDensity(Integer screenDensity) {
+ this.screenDensity = screenDensity;
+ }
+
+ public String getKernelVersion() {
+ return kernelVersion;
+ }
+
+ public void setKernelVersion(String kernelVersion) {
+ this.kernelVersion = kernelVersion;
+ }
+
+ public String getRomVersion() {
+ return romVersion;
+ }
+
+ public void setRomVersion(String romVersion) {
+ this.romVersion = romVersion;
+ }
+
+ public String getProductName() {
+ return productName;
+ }
+
+ public void setProductName(String productName) {
+ this.productName = productName;
+ }
+
+ public String getProductModel() {
+ return productModel;
+ }
+
+ public void setProductModel(String productModel) {
+ this.productModel = productModel;
+ }
+
+ public String getProductDevice() {
+ return productDevice;
+ }
+
+ public void setProductDevice(String productDevice) {
+ this.productDevice = productDevice;
+ }
+
+ public String getBoardPlatform() {
+ return boardPlatform;
+ }
+
+ public void setBoardPlatform(String boardPlatform) {
+ this.boardPlatform = boardPlatform;
+ }
+
+ public String getDeviceType() {
+ return deviceType;
+ }
+
+ public void setDeviceType(String deviceType) {
+ this.deviceType = deviceType;
+ }
+
+ public Integer getIsTablet() {
+ return isTablet;
+ }
+
+ public void setIsTablet(Integer isTablet) {
+ this.isTablet = isTablet;
+ }
+
+ public String getReleaseVersion() {
+ return releaseVersion;
+ }
+
+ public void setReleaseVersion(String releaseVersion) {
+ this.releaseVersion = releaseVersion;
+ }
+
+ public String getDisplayVersion() {
+ return displayVersion;
+ }
+
+ public void setDisplayVersion(String displayVersion) {
+ this.displayVersion = displayVersion;
+ }
+
+ public String getBootloader() {
+ return bootloader;
+ }
+
+ public void setBootloader(String bootloader) {
+ this.bootloader = bootloader;
+ }
+
+ public String getBasebandVersion() {
+ return basebandVersion;
+ }
+
+ public void setBasebandVersion(String basebandVersion) {
+ this.basebandVersion = basebandVersion;
+ }
+
+ public String getRadioVersion() {
+ return radioVersion;
+ }
+
+ public void setRadioVersion(String radioVersion) {
+ this.radioVersion = radioVersion;
+ }
+
+ public String getScreenSize() {
+ return screenSize;
+ }
+
+ public void setScreenSize(String screenSize) {
+ this.screenSize = screenSize;
+ }
+
+ public BigDecimal getScreenInch() {
+ return screenInch;
+ }
+
+ public void setScreenInch(BigDecimal screenInch) {
+ this.screenInch = screenInch;
+ }
+
+ public Integer getRefreshRate() {
+ return refreshRate;
+ }
+
+ public void setRefreshRate(Integer refreshRate) {
+ this.refreshRate = refreshRate;
+ }
+
+ public String getOsType() {
+ return osType;
+ }
+
+ public void setOsType(String osType) {
+ this.osType = osType;
+ }
+
+ public String getOsVersion() {
+ return osVersion;
+ }
+
+ public void setOsVersion(String osVersion) {
+ this.osVersion = osVersion;
+ }
+
+ public String getFirmwareVersion() {
+ return firmwareVersion;
+ }
+
+ public void setFirmwareVersion(String firmwareVersion) {
+ this.firmwareVersion = firmwareVersion;
+ }
}
diff --git a/app/src/main/java/com/ttstd/dialer/mdm/DeviceInfoCollector.java b/app/src/main/java/com/ttstd/dialer/mdm/DeviceInfoCollector.java
index 64cc502..5aac5f9 100644
--- a/app/src/main/java/com/ttstd/dialer/mdm/DeviceInfoCollector.java
+++ b/app/src/main/java/com/ttstd/dialer/mdm/DeviceInfoCollector.java
@@ -35,6 +35,7 @@ import com.ttstd.dialer.bean.req.SnOtherInfoReq;
import com.ttstd.dialer.bean.req.SnSecurityInfoReq;
import com.ttstd.dialer.bean.req.SnSystemInfoReq;
import com.ttstd.dialer.utils.Logger;
+import com.ttstd.dialer.utils.SystemUtils;
import java.io.BufferedReader;
import java.io.File;
@@ -112,25 +113,88 @@ public class DeviceInfoCollector {
// ==================================================================
/**
- * 采集设备基本信息。
+ * 采集设备基本信息(对齐后端 DeviceSystemInfoVO / SnDeviceSystemInfo)。
*/
public SnSystemInfoReq collectSystemInfo() {
SnSystemInfoReq req = new SnSystemInfoReq();
DeviceManagerService dms = DeviceManagerService.getInstance();
- req.setImei(safeString(dms::getImei));
- req.setImsi(safeString(dms::getImsi));
- req.setWlanMac(safeString(dms::getWlanMac));
- req.setDeviceMac(safeString(dms::getDeviceMac));
- req.setBluetoothMac(safeString(dms::getBluetoothMac));
-
- req.setModel(Build.MODEL);
- req.setBrand(Build.BRAND);
- req.setBoard(Build.BOARD);
+ // ---- 基本信息 ----
+ req.setDeviceName(safeString(() -> SystemUtils.getDeviceName(mContext)));
+ req.setDeviceBrand(Build.BRAND);
+ req.setDeviceModel(Build.MODEL);
+ req.setDeviceBoard(Build.BOARD);
+ req.setDeviceManufacturer(Build.MANUFACTURER);
+ req.setHardware(safeString(() -> SystemUtils.getHardware()));
+ req.setHost(safeString(() -> SystemUtils.getHost()));
req.setAndroidVersion(Build.VERSION.RELEASE);
req.setAndroidApi(Build.VERSION.SDK_INT);
- req.setBuildId(Build.ID);
- req.setBuildDisplayId(Build.DISPLAY);
+ req.setAndroidId(safeString(() -> SystemUtils.getAndroidId(mContext)));
+
+ // ---- Build 信息 ----
+ req.setBuildId(safeString(() -> SystemUtils.getBuildId()));
+ req.setBuildDisplayId(safeString(() -> SystemUtils.getBuildDisplayId()));
+ req.setBuildFingerprint(safeString(() -> SystemUtils.getBuildFingerprint()));
+ req.setBuildType(safeString(() -> SystemUtils.getBuildType()));
+ req.setBuildUser(safeString(() -> SystemUtils.getBuildUser()));
+ req.setBuildHost(safeString(() -> SystemUtils.getBuildHost()));
+ req.setBuildTags(safeString(() -> SystemUtils.getBuildTags()));
+ try {
+ long buildTime = SystemUtils.getBuildTime();
+ if (buildTime > 0) {
+ req.setBuildTime(formatDateTime(buildTime));
+ }
+ } catch (Throwable t) {
+ Logger.e(TAG, "collect buildTime failed: " + t.getMessage());
+ }
+
+ // ---- 语言 / 时区 / 开机时间 ----
+ req.setLanguage(safeString(() -> SystemUtils.getLanguage()));
+ req.setTimezone(safeString(() -> SystemUtils.getTimezone()));
+ try {
+ long bootTime = SystemUtils.getBootTime();
+ if (bootTime > 0) {
+ req.setBootTime(formatDateTime(bootTime));
+ }
+ } catch (Throwable t) {
+ Logger.e(TAG, "collect bootTime failed: " + t.getMessage());
+ }
+
+ // ---- 屏幕信息 ----
+ req.setScreenResolution(safeString(() -> SystemUtils.getScreenResolution(mContext)));
+ req.setScreenDensity(SystemUtils.getScreenDensity(mContext));
+ req.setScreenSize(safeString(() -> SystemUtils.getScreenSize(mContext)));
+ req.setScreenInch(java.math.BigDecimal.valueOf(SystemUtils.getScreenInch(mContext)));
+ req.setRefreshRate(SystemUtils.getRefreshRate(mContext));
+
+ // ---- 内核 / ROM ----
+ req.setKernelVersion(safeString(() -> SystemUtils.getKernelVersion()));
+ req.setRomVersion(safeString(() -> SystemUtils.getRomVersion()));
+
+ // ---- 产品 / 主板平台 ----
+ req.setProductName(safeString(() -> SystemUtils.getProductName()));
+ req.setProductModel(safeString(() -> SystemUtils.getProductModel()));
+ req.setProductDevice(safeString(() -> SystemUtils.getProductDevice()));
+ req.setBoardPlatform(safeString(() -> SystemUtils.getBoardPlatform()));
+
+ // ---- 设备类型 / 平板标识 ----
+ req.setDeviceType(safeString(() -> SystemUtils.getDeviceType(mContext)));
+ req.setIsTablet(SystemUtils.getIsTablet(mContext));
+
+ // ---- 发布 / 显示版本 ----
+ req.setReleaseVersion(safeString(() -> SystemUtils.getReleaseVersion()));
+ req.setDisplayVersion(safeString(() -> SystemUtils.getDisplayVersion()));
+
+ // ---- Bootloader / 基带 / Radio ----
+ req.setBootloader(safeString(() -> SystemUtils.getBootloader()));
+ req.setBasebandVersion(safeString(() -> SystemUtils.getBasebandVersion()));
+ req.setRadioVersion(safeString(() -> SystemUtils.getRadioVersion()));
+
+ // ---- 操作系统 ----
+ req.setOsType(safeString(() -> SystemUtils.getOsType()));
+ req.setOsVersion(safeString(() -> SystemUtils.getOsVersion()));
+ req.setFirmwareVersion(safeString(() -> SystemUtils.getFirmwareVersion()));
+
return req;
}
@@ -354,6 +418,12 @@ public class DeviceInfoCollector {
if (tm != null) {
req.setMobileOperator(tm.getNetworkOperatorName());
req.setMobileNetworkType(networkTypeName(tm));
+ // 移动数据网络子类型(LTE/HSPA/EDGE 等)
+ req.setNetworkSubtype(safeString(() -> SystemUtils.getNetworkSubtype(tm)));
+ // 移动数据网络 IP(接入数据网络时才有值)
+ req.setMobileIp(safeString(() -> SystemUtils.getMobileIp(mContext)));
+ // 移动数据网络 MAC(Android 6+ 受隐私限制多为空,尽力而为)
+ req.setMobileMac(safeString(() -> SystemUtils.getMobileMac()));
if (hasPermission(Manifest.permission.READ_PHONE_STATE)) {
req.setMobileSimSerial(safeString(tm::getSimSerialNumber));
}
@@ -622,6 +692,26 @@ public class DeviceInfoCollector {
Logger.e(TAG, "collect ram snapshot failed: " + t.getMessage());
}
+ // ---- 运营 / 广告标识(无对应系统 API 时留空,由打包/渠道/广告 SDK 注入)----
+ try {
+ // 发布渠道:通常由构建脚本 / 渠道包注入,采集器无系统来源,默认空串。
+ req.setChannel("");
+ // GAID(Google Advertising ID):需 Google Play Services AdvertisingIdClient,
+ // 本项目未依赖 GMS,默认空串;接入后可在此补全。
+ req.setGaid("");
+ // OAID(国内移动广告标识):需移动安全联盟(MSA)SDK,本项目未集成,默认空串。
+ req.setOaid("");
+ } catch (Throwable t) {
+ Logger.e(TAG, "collect channel/gaid/oaid failed: " + t.getMessage());
+ }
+
+ // ---- 应用列表 MD5(与 SnSecurityInfoReq.mobileAppList 口径一致)----
+ try {
+ req.setAppListMd5(SystemUtils.getAppListMd5(mContext.getPackageManager()));
+ } catch (Throwable t) {
+ Logger.e(TAG, "collect appListMd5 failed: " + t.getMessage());
+ }
+
return req;
}
diff --git a/app/src/main/java/com/ttstd/dialer/utils/SystemUtils.java b/app/src/main/java/com/ttstd/dialer/utils/SystemUtils.java
index 2e91cb9..0114c2d 100644
--- a/app/src/main/java/com/ttstd/dialer/utils/SystemUtils.java
+++ b/app/src/main/java/com/ttstd/dialer/utils/SystemUtils.java
@@ -11,6 +11,8 @@ import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.UserInfo;
@@ -51,6 +53,7 @@ import java.util.Locale;
import java.util.Optional;
import java.util.concurrent.Callable;
import java.util.concurrent.Executor;
+import java.security.MessageDigest;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
@@ -278,6 +281,182 @@ public class SystemUtils {
return "未获取到设备Mac地址";
}
+ /**
+ * 获取当前移动网络(数据网络)的 IP 地址
+ *
+ * @return 形如 "10.x.x.x" 的 IPv4 地址,未连接数据网络或获取失败返回空串
+ */
+ @SuppressLint("MissingPermission")
+ public static String getMobileIp(Context context) {
+ try {
+ // 优先通过 TrafficStats / 网络接口遍历移动网络接口(rmnet0 / ccmni0 等)
+ List