feat: 统一 deviceId 来源,所有 SDK 模块使用 XuqmSDK.deviceId
- DeviceUtils.getDeviceId() 统一委托 XuqmSDK.deviceId - sdk-license: DeviceInfoProvider 改用 DeviceUtils - sdk-push: 所有 getDeviceId(context) 改为 getDeviceId() - sdk-update: checkUpdate 增加 deviceId/model/osVersion/vendor 参数 - DeviceUtils 新增 getDeviceInfo() 返回完整设备信息 Map
这个提交包含在:
父节点
fd37f57fbf
当前提交
e3d03c0ea7
@ -1,14 +1,15 @@
|
||||
package com.xuqm.sdk.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import android.provider.Settings
|
||||
import com.xuqm.sdk.XuqmSDK
|
||||
|
||||
object DeviceUtils {
|
||||
|
||||
fun getDeviceId(context: Context): String =
|
||||
Settings.Secure.getString(context.contentResolver, Settings.Secure.ANDROID_ID)
|
||||
?: Build.FINGERPRINT
|
||||
/**
|
||||
* 获取统一设备 ID(来源:XuqmSDK.deviceId)。
|
||||
* 所有 SDK 模块应使用此方法获取 deviceId,确保同一设备在所有服务中标识一致。
|
||||
*/
|
||||
fun getDeviceId(): String = XuqmSDK.deviceId
|
||||
|
||||
fun getDeviceModel(): String = "${Build.MANUFACTURER} ${Build.MODEL}"
|
||||
|
||||
@ -21,4 +22,13 @@ object DeviceUtils {
|
||||
"vivo", "iqoo" -> "VIVO"
|
||||
else -> "FCM"
|
||||
}
|
||||
|
||||
/** 获取完整设备信息 Map,用于 API 上报。 */
|
||||
fun getDeviceInfo(): Map<String, String> = mapOf(
|
||||
"deviceId" to getDeviceId(),
|
||||
"model" to getDeviceModel(),
|
||||
"osVersion" to getOsVersion(),
|
||||
"vendor" to getVendor(),
|
||||
"platform" to "ANDROID",
|
||||
)
|
||||
}
|
||||
|
||||
@ -226,7 +226,7 @@ object LicenseSDK {
|
||||
|
||||
private fun getOrCreateDeviceId(): String {
|
||||
store.deviceId?.let { return it }
|
||||
val newId = DeviceInfoProvider.getDeviceId(appContext)
|
||||
val newId = DeviceInfoProvider.getDeviceId()
|
||||
store.deviceId = newId
|
||||
return newId
|
||||
}
|
||||
|
||||
@ -1,50 +1,22 @@
|
||||
package com.xuqm.sdk.license.internal
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import android.provider.Settings
|
||||
import java.util.UUID
|
||||
import com.xuqm.sdk.utils.DeviceUtils
|
||||
|
||||
/**
|
||||
* Provides stable device information for license checks.
|
||||
* deviceId 统一使用 XuqmSDK.deviceId(通过 DeviceUtils)。
|
||||
*/
|
||||
internal object DeviceInfoProvider {
|
||||
|
||||
private const val FALLBACK_PREFS = "xuqm_license_device_fallback"
|
||||
private const val KEY_FALLBACK_ID = "fallback_device_id"
|
||||
/** 统一设备 ID,来源:XuqmSDK.deviceId */
|
||||
fun getDeviceId(): String = DeviceUtils.getDeviceId()
|
||||
|
||||
/**
|
||||
* Get stable device ID.
|
||||
* Priority:
|
||||
* 1. ANDROID_ID (stable per app signing key + device + user, survives reinstall with same signer)
|
||||
* 2. Persisted fallback UUID
|
||||
*
|
||||
* Note: ANDROID_ID changes on factory reset or if app is reinstalled with different signing key.
|
||||
*/
|
||||
fun getDeviceId(context: Context): String {
|
||||
val androidId = try {
|
||||
Settings.Secure.getString(context.contentResolver, Settings.Secure.ANDROID_ID)
|
||||
} catch (_: Exception) { null }
|
||||
|
||||
if (!androidId.isNullOrBlank() && androidId != "9774d56d682e549c") {
|
||||
return androidId
|
||||
}
|
||||
|
||||
// Fallback to persisted UUID
|
||||
val prefs = context.getSharedPreferences(FALLBACK_PREFS, Context.MODE_PRIVATE)
|
||||
var fallbackId = prefs.getString(KEY_FALLBACK_ID, null)
|
||||
if (fallbackId == null) {
|
||||
fallbackId = UUID.randomUUID().toString()
|
||||
prefs.edit().putString(KEY_FALLBACK_ID, fallbackId).apply()
|
||||
}
|
||||
return fallbackId
|
||||
}
|
||||
|
||||
fun getDeviceModel(): String = "${Build.MANUFACTURER} ${Build.MODEL}"
|
||||
fun getDeviceModel(): String = DeviceUtils.getDeviceModel()
|
||||
|
||||
fun getDeviceVendor(): String = Build.MANUFACTURER
|
||||
|
||||
fun getOsVersion(): String = "Android ${Build.VERSION.RELEASE}"
|
||||
fun getOsVersion(): String = DeviceUtils.getOsVersion()
|
||||
|
||||
fun getDeviceName(): String = getDeviceModel()
|
||||
}
|
||||
|
||||
@ -54,7 +54,7 @@ object PushSDK {
|
||||
api.setReceivePush(
|
||||
appKey = XuqmSDK.appKey,
|
||||
userId = userId,
|
||||
deviceId = DeviceUtils.getDeviceId(context),
|
||||
deviceId = DeviceUtils.getDeviceId(),
|
||||
enabled = enabled,
|
||||
)
|
||||
if (enabled) {
|
||||
@ -127,7 +127,7 @@ object PushSDK {
|
||||
|
||||
fun currentRegistration(context: Context): PushRegistrationSnapshot? {
|
||||
XuqmSDK.requireInit()
|
||||
val deviceId = DeviceUtils.getDeviceId(context)
|
||||
val deviceId = DeviceUtils.getDeviceId()
|
||||
val detectedVendor = detectVendor()
|
||||
val registration = store(context).load(deviceId = deviceId, fallbackVendor = detectedVendor)
|
||||
?: return null
|
||||
@ -190,7 +190,7 @@ object PushSDK {
|
||||
val registration = currentRegistration(context)
|
||||
val vendor = registration?.vendor ?: detectVendor()
|
||||
val pushToken = registration?.pushToken?.takeIf { it.isNotBlank() }
|
||||
val deviceId = DeviceUtils.getDeviceId(context)
|
||||
val deviceId = DeviceUtils.getDeviceId()
|
||||
if (pushToken.isNullOrBlank()) {
|
||||
Log.w("XuqmPushSDK", "Native push token not ready yet, waiting for onNewToken()")
|
||||
ensureNativePushTokenInternal(context)
|
||||
@ -215,8 +215,8 @@ object PushSDK {
|
||||
vendor = vendor.name,
|
||||
token = pushToken,
|
||||
deviceId = deviceId,
|
||||
brand = Build.MANUFACTURER.orEmpty(),
|
||||
model = Build.MODEL.orEmpty(),
|
||||
brand = DeviceUtils.getVendor(),
|
||||
model = DeviceUtils.getDeviceModel(),
|
||||
osVersion = DeviceUtils.getOsVersion(),
|
||||
appVersion = appVersion(context),
|
||||
)
|
||||
@ -235,14 +235,14 @@ object PushSDK {
|
||||
scope.launch {
|
||||
runCatching {
|
||||
val reg = store(XuqmSDK.appContext).load(
|
||||
deviceId = DeviceUtils.getDeviceId(XuqmSDK.appContext),
|
||||
deviceId = DeviceUtils.getDeviceId(),
|
||||
fallbackVendor = detectVendor(),
|
||||
)
|
||||
api.unregisterDevice(
|
||||
XuqmSDK.appKey,
|
||||
userId,
|
||||
reg?.vendor?.name ?: detectVendor().name,
|
||||
DeviceUtils.getDeviceId(XuqmSDK.appContext),
|
||||
DeviceUtils.getDeviceId(),
|
||||
)
|
||||
registeredUserId.compareAndSet(userId, null)
|
||||
store(XuqmSDK.appContext).updateLastUserId(null)
|
||||
@ -272,7 +272,7 @@ object PushSDK {
|
||||
|
||||
private fun isReceivePushEnabled(context: Context): Boolean =
|
||||
store(context).load(
|
||||
deviceId = DeviceUtils.getDeviceId(context),
|
||||
deviceId = DeviceUtils.getDeviceId(),
|
||||
fallbackVendor = detectVendor(),
|
||||
)?.receivePush ?: true
|
||||
|
||||
|
||||
@ -184,7 +184,17 @@ object UpdateSDK {
|
||||
}
|
||||
|
||||
runCatching {
|
||||
val response = api.checkUpdate(XuqmSDK.appKey, "ANDROID", versionCode, userId)
|
||||
val deviceInfo = com.xuqm.sdk.utils.DeviceUtils.getDeviceInfo()
|
||||
val response = api.checkUpdate(
|
||||
appKey = XuqmSDK.appKey,
|
||||
platform = "ANDROID",
|
||||
currentVersionCode = versionCode,
|
||||
userId = userId,
|
||||
deviceId = deviceInfo["deviceId"],
|
||||
model = deviceInfo["model"],
|
||||
osVersion = deviceInfo["osVersion"],
|
||||
vendor = deviceInfo["vendor"],
|
||||
)
|
||||
if (response.code == 40404) {
|
||||
throw IllegalStateException("更新服务未开通 (code=40404) [appKey=${XuqmSDK.appKey}]")
|
||||
}
|
||||
|
||||
@ -40,5 +40,9 @@ internal interface UpdateApi {
|
||||
@Query("platform") platform: String,
|
||||
@Query("currentVersionCode") currentVersionCode: Int,
|
||||
@Query("userId") userId: String? = null,
|
||||
@Query("deviceId") deviceId: String? = null,
|
||||
@Query("model") model: String? = null,
|
||||
@Query("osVersion") osVersion: String? = null,
|
||||
@Query("vendor") vendor: String? = null,
|
||||
): ApiResponse<UpdateInfoDto>
|
||||
}
|
||||
|
||||
正在加载...
在新工单中引用
屏蔽一个用户