feat(dialer): 扩展系统信息采集字段,对齐后端 DeviceSystemInfoVO
移除旧的 IMEI/IMSI/MAC 等字段,新增设备名称、品牌、型号、制造商、硬件、Host、Android ID、Build 信息、语言、时区、启动时间、屏幕信息、内核/ROM 版本、产品信息、主板平台、设备类型、平板标识、发布/显示版本、Bootloader/基带/Radio 版本、操作系统类型/版本/固件版本等字段,并新增移动网络 IP/MAC/子类型、渠道/广告标识、应用列表 MD5 等采集逻辑
This commit is contained in:
@@ -3,118 +3,197 @@ package com.ttstd.dialer.bean.req;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 设备基本信息上传请求。
|
||||
* <p>
|
||||
* 对应后端 {@code POST /api/v1/sn/update_system_info},
|
||||
* 字段与后端 {@code SnSystemInfoReq} 一一对应。
|
||||
* <p>
|
||||
* 注意:该类原名为 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<NetworkInterface> interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
|
||||
for (NetworkInterface nif : interfaces) {
|
||||
String name = nif.getName();
|
||||
if (name == null) {
|
||||
continue;
|
||||
}
|
||||
// 移动数据网络接口通常以 rmnet / ccmni / mnet 开头
|
||||
if (name.startsWith("rmnet") || name.startsWith("ccmni") || name.startsWith("mnet")) {
|
||||
for (java.net.InterfaceAddress addr : nif.getInterfaceAddresses()) {
|
||||
java.net.InetAddress inet = addr.getAddress();
|
||||
if (inet instanceof java.net.Inet4Address && !inet.isLoopbackAddress()) {
|
||||
return inet.getHostAddress();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取移动数据网络的 MAC 地址
|
||||
* 注意:Android 6.0+ 出于隐私限制,通过 API 只能拿到 02:00:00:00:00:00,
|
||||
* 系统签名应用可尝试读取 /sys/class/net/rmnet0/address(多数情况下为空)。
|
||||
*
|
||||
* @return MAC 地址字符串,无法获取时返回空串
|
||||
*/
|
||||
@SuppressLint("MissingPermission")
|
||||
public static String getMobileMac() {
|
||||
// 移动网络接口通常没有独立 MAC,部分设备通过 rmnet 暴露
|
||||
String[] candidates = {"rmnet0", "rmnet_data0", "ccmni0"};
|
||||
for (String ifName : candidates) {
|
||||
try {
|
||||
NetworkInterface nif = NetworkInterface.getByName(ifName);
|
||||
if (nif != null) {
|
||||
byte[] mac = nif.getHardwareAddress();
|
||||
if (mac != null && mac.length > 0) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (byte b : mac) {
|
||||
sb.append(String.format("%02X:", b));
|
||||
}
|
||||
if (sb.length() > 0) {
|
||||
sb.deleteCharAt(sb.length() - 1);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取移动网络子类型名称(如 LTE / HSPA / EDGE 等)
|
||||
*
|
||||
* @param tm TelephonyManager
|
||||
* @return 网络子类型描述,未接入数据网络返回空串
|
||||
*/
|
||||
@SuppressLint("MissingPermission")
|
||||
public static String getNetworkSubtype(TelephonyManager tm) {
|
||||
try {
|
||||
if (tm != null) {
|
||||
int subtype = tm.getNetworkType();
|
||||
return getNetworkTypeName(subtype);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private static String getNetworkTypeName(int networkType) {
|
||||
switch (networkType) {
|
||||
case TelephonyManager.NETWORK_TYPE_GPRS:
|
||||
return "GPRS";
|
||||
case TelephonyManager.NETWORK_TYPE_EDGE:
|
||||
return "EDGE";
|
||||
case TelephonyManager.NETWORK_TYPE_UMTS:
|
||||
return "UMTS";
|
||||
case TelephonyManager.NETWORK_TYPE_HSDPA:
|
||||
return "HSDPA";
|
||||
case TelephonyManager.NETWORK_TYPE_HSUPA:
|
||||
return "HSUPA";
|
||||
case TelephonyManager.NETWORK_TYPE_HSPA:
|
||||
return "HSPA";
|
||||
case TelephonyManager.NETWORK_TYPE_CDMA:
|
||||
return "CDMA";
|
||||
case TelephonyManager.NETWORK_TYPE_EVDO_0:
|
||||
return "EVDO_0";
|
||||
case TelephonyManager.NETWORK_TYPE_EVDO_A:
|
||||
return "EVDO_A";
|
||||
case TelephonyManager.NETWORK_TYPE_1xRTT:
|
||||
return "1xRTT";
|
||||
case TelephonyManager.NETWORK_TYPE_EHRPD:
|
||||
return "eHRPD";
|
||||
case TelephonyManager.NETWORK_TYPE_LTE:
|
||||
return "LTE";
|
||||
case TelephonyManager.NETWORK_TYPE_HSPAP:
|
||||
return "HSPA+";
|
||||
case TelephonyManager.NETWORK_TYPE_GSM:
|
||||
return "GSM";
|
||||
case TelephonyManager.NETWORK_TYPE_TD_SCDMA:
|
||||
return "TD_SCDMA";
|
||||
case TelephonyManager.NETWORK_TYPE_IWLAN:
|
||||
return "IWLAN";
|
||||
case TelephonyManager.NETWORK_TYPE_NR:
|
||||
return "NR";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算已安装应用包名列表的 MD5(与 SnSecurityInfoReq.mobileAppList 口径保持一致:
|
||||
* 取所有非系统应用包名,按字母排序后用逗号拼接再取 MD5)。
|
||||
*
|
||||
* @param pm PackageManager
|
||||
* @return 32 位小写 MD5 字符串;无应用或异常时返回空串
|
||||
*/
|
||||
public static String getAppListMd5(PackageManager pm) {
|
||||
try {
|
||||
if (pm == null) {
|
||||
return "";
|
||||
}
|
||||
List<PackageInfo> installedApps = pm.getInstalledPackages(0);
|
||||
List<String> pkgNames = new ArrayList<>();
|
||||
for (PackageInfo info : installedApps) {
|
||||
// 仅统计第三方(非系统)应用,与常规应用列表统计口径一致
|
||||
if ((info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
|
||||
&& info.packageName != null) {
|
||||
pkgNames.add(info.packageName);
|
||||
}
|
||||
}
|
||||
Collections.sort(pkgNames);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (String name : pkgNames) {
|
||||
if (sb.length() > 0) {
|
||||
sb.append(",");
|
||||
}
|
||||
sb.append(name);
|
||||
}
|
||||
return md5(sb.toString());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private static String md5(String input) {
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
byte[] digest = md.digest(input.getBytes());
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (byte b : digest) {
|
||||
sb.append(String.format("%02x", b & 0xff));
|
||||
}
|
||||
return sb.toString();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public static String getFactoryMacAddresses(Context context) {
|
||||
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
|
||||
String[] factoryMacAddresses = wifiManager.getFactoryMacAddresses();
|
||||
@@ -331,6 +510,236 @@ public class SystemUtils {
|
||||
return getProperty(Build.DISPLAY, Build.UNKNOWN);
|
||||
}
|
||||
|
||||
// ==================================================================
|
||||
// 设备基本信息(对齐后端 DeviceSystemInfoVO)
|
||||
// ==================================================================
|
||||
|
||||
public static String getDeviceName(Context context) {
|
||||
try {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
|
||||
return Settings.Global.getString(context.getContentResolver(), Settings.Global.DEVICE_NAME);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
// ignore
|
||||
}
|
||||
return Build.UNKNOWN;
|
||||
}
|
||||
|
||||
public static String getDeviceManufacturer() {
|
||||
return getProperty(Build.MANUFACTURER, Build.UNKNOWN);
|
||||
}
|
||||
|
||||
public static String getHardware() {
|
||||
return getProperty("ro.hardware", Build.UNKNOWN);
|
||||
}
|
||||
|
||||
public static String getHost() {
|
||||
return getProperty(Build.HOST, Build.UNKNOWN);
|
||||
}
|
||||
|
||||
public static String getAndroidId(Context context) {
|
||||
try {
|
||||
return Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
|
||||
} catch (Throwable t) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public static String getBuildFingerprint() {
|
||||
return getProperty(Build.FINGERPRINT, Build.UNKNOWN);
|
||||
}
|
||||
|
||||
public static String getBuildType() {
|
||||
return getProperty(Build.TYPE, Build.UNKNOWN);
|
||||
}
|
||||
|
||||
public static String getBuildUser() {
|
||||
return getProperty(Build.USER, Build.UNKNOWN);
|
||||
}
|
||||
|
||||
public static String getBuildHost() {
|
||||
return getProperty(Build.HOST, Build.UNKNOWN);
|
||||
}
|
||||
|
||||
public static String getBuildTags() {
|
||||
return getProperty(Build.TAGS, Build.UNKNOWN);
|
||||
}
|
||||
|
||||
public static long getBuildTime() {
|
||||
try {
|
||||
return Build.TIME;
|
||||
} catch (Throwable t) {
|
||||
return 0L;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getLanguage() {
|
||||
try {
|
||||
return Locale.getDefault().getLanguage();
|
||||
} catch (Throwable t) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public static String getTimezone() {
|
||||
try {
|
||||
return java.util.TimeZone.getDefault().getID();
|
||||
} catch (Throwable t) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public static long getBootTime() {
|
||||
try {
|
||||
return System.currentTimeMillis() - android.os.SystemClock.elapsedRealtime();
|
||||
} catch (Throwable t) {
|
||||
return 0L;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getScreenResolution(Context context) {
|
||||
try {
|
||||
android.util.DisplayMetrics dm = context.getResources().getDisplayMetrics();
|
||||
return dm.widthPixels + "x" + dm.heightPixels;
|
||||
} catch (Throwable t) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public static int getScreenDensity(Context context) {
|
||||
try {
|
||||
return (int) Math.round(context.getResources().getDisplayMetrics().density);
|
||||
} catch (Throwable t) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static int getScreenDensityDpi(Context context) {
|
||||
try {
|
||||
return context.getResources().getDisplayMetrics().densityDpi;
|
||||
} catch (Throwable t) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getKernelVersion() {
|
||||
return getProperty("sys.kernel.version", "");
|
||||
}
|
||||
|
||||
public static String getRomVersion() {
|
||||
return getProperty("ro.build.version.emui",
|
||||
getProperty("ro.build.version.miui",
|
||||
getProperty("ro.build.version.opporom",
|
||||
getProperty("ro.vivo.os.version", ""))));
|
||||
}
|
||||
|
||||
public static String getProductName() {
|
||||
return getProperty(Build.PRODUCT, Build.UNKNOWN);
|
||||
}
|
||||
|
||||
public static String getProductModel() {
|
||||
return getProperty("ro.product.model", Build.UNKNOWN);
|
||||
}
|
||||
|
||||
public static String getProductDevice() {
|
||||
return getProperty("ro.product.device", Build.UNKNOWN);
|
||||
}
|
||||
|
||||
public static String getBoardPlatform() {
|
||||
return getProperty("ro.board.platform", Build.UNKNOWN);
|
||||
}
|
||||
|
||||
public static String getDeviceType(Context context) {
|
||||
try {
|
||||
int layout = context.getResources().getConfiguration().screenLayout
|
||||
& android.content.res.Configuration.SCREENLAYOUT_SIZE_MASK;
|
||||
if (layout >= android.content.res.Configuration.SCREENLAYOUT_SIZE_LARGE) {
|
||||
return "tablet";
|
||||
}
|
||||
return "phone";
|
||||
} catch (Throwable t) {
|
||||
return "phone";
|
||||
}
|
||||
}
|
||||
|
||||
public static int getIsTablet(Context context) {
|
||||
try {
|
||||
int layout = context.getResources().getConfiguration().screenLayout
|
||||
& android.content.res.Configuration.SCREENLAYOUT_SIZE_MASK;
|
||||
return layout >= android.content.res.Configuration.SCREENLAYOUT_SIZE_LARGE ? 1 : 0;
|
||||
} catch (Throwable t) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getReleaseVersion() {
|
||||
return getProperty("ro.build.version.release", Build.VERSION.RELEASE);
|
||||
}
|
||||
|
||||
public static String getDisplayVersion() {
|
||||
return getProperty("ro.build.display.id", Build.DISPLAY);
|
||||
}
|
||||
|
||||
public static String getBootloader() {
|
||||
return getProperty(Build.BOOTLOADER, Build.UNKNOWN);
|
||||
}
|
||||
|
||||
public static String getBasebandVersion() {
|
||||
return getProperty("gsm.version.baseband", Build.UNKNOWN);
|
||||
}
|
||||
|
||||
public static String getRadioVersion() {
|
||||
try {
|
||||
return Build.getRadioVersion() != null ? Build.getRadioVersion() : Build.UNKNOWN;
|
||||
} catch (Throwable t) {
|
||||
return Build.UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getScreenSize(Context context) {
|
||||
try {
|
||||
android.util.DisplayMetrics dm = context.getResources().getDisplayMetrics();
|
||||
double diagonal = Math.sqrt(Math.pow(dm.widthPixels / dm.xdpi, 2)
|
||||
+ Math.pow(dm.heightPixels / dm.ydpi, 2));
|
||||
return String.format(Locale.US, "%.1f", diagonal);
|
||||
} catch (Throwable t) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public static double getScreenInch(Context context) {
|
||||
try {
|
||||
android.util.DisplayMetrics dm = context.getResources().getDisplayMetrics();
|
||||
double diagonal = Math.sqrt(Math.pow(dm.widthPixels / dm.xdpi, 2)
|
||||
+ Math.pow(dm.heightPixels / dm.ydpi, 2));
|
||||
return Math.round(diagonal * 10.0) / 10.0;
|
||||
} catch (Throwable t) {
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
public static int getRefreshRate(Context context) {
|
||||
try {
|
||||
android.view.Display display = ((android.view.WindowManager)
|
||||
context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
|
||||
return Math.round(display.getRefreshRate());
|
||||
} catch (Throwable t) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getOsType() {
|
||||
return "Android";
|
||||
}
|
||||
|
||||
public static String getOsVersion() {
|
||||
return Build.VERSION.RELEASE;
|
||||
}
|
||||
|
||||
public static String getFirmwareVersion() {
|
||||
return getProperty("ro.build.version.incremental", Build.UNKNOWN);
|
||||
}
|
||||
|
||||
public static boolean isMainProcessName(Context cxt, int pid) {
|
||||
String packageName = cxt.getPackageName();
|
||||
ActivityManager am = (ActivityManager) cxt.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
|
||||
Reference in New Issue
Block a user