You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose开发:无需登录凭证如何存储Android设备唯一标识?

用Android设备唯一标识实现贪吃蛇游戏用户分数区分方案(Jetpack Compose)

一、获取合规的设备唯一标识

Android不同版本对设备标识的权限限制不同,推荐两种稳定且符合规范的方式:

1. Android ID(首选,无需额外权限)

Android ID是系统首次启动时生成的64位字符串,除非恢复出厂设置或刷机,否则不会改变;卸载应用后重装依然保留,完全满足你的需求。

代码实现(Compose中调用):

import android.content.Context
import android.provider.Settings

fun getAndroidId(context: Context): String {
    return Settings.Secure.getString(
        context.contentResolver,
        Settings.Secure.ANDROID_ID
    ) ?: ""
}

在Compose组件中通过LocalContext获取上下文并调用:

val context = LocalContext.current
val androidId = remember { getAndroidId(context) }

2. Advertising ID(可选,适合含广告的应用)

如果你的应用涉及广告投放,可以用这个由Google Play服务提供的标识,用户可在系统设置中重置它。需要先添加依赖:

dependencies {
    implementation "com.google.android.gms:play-services-ads-identifier:18.0.1"
}

获取代码(需协程):

import com.google.android.gms.ads.identifier.AdvertisingIdClient
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

suspend fun getAdvertisingId(context: Context): String {
    return withContext(Dispatchers.IO) {
        try {
            val info = AdvertisingIdClient.getAdvertisingIdInfo(context)
            info.id ?: ""
        } catch (e: Exception) {
            ""
        }
    }
}

在Compose中启动协程调用:

val context = LocalContext.current
var advertisingId by remember { mutableStateOf("") }

LaunchedEffect(Unit) {
    advertisingId = getAdvertisingId(context)
}

二、绑定标识与分数存储

拿到设备唯一标识后,把它作为用户的唯一键,存储对应的游戏分数:

1. 本地存储(SharedPreferences,卸载即丢失)

适合不需要云端同步的场景,完全匹配你“记住信息直至卸载”的需求:

import android.content.Context
import android.content.SharedPreferences

class ScoreManager(context: Context) {
    private val prefs = context.getSharedPreferences("SnakeGamePrefs", Context.MODE_PRIVATE)

    // 保存分数:用设备ID作为键的前缀
    fun saveScore(deviceId: String, score: Int) {
        prefs.edit().putInt("score_$deviceId", score).apply()
    }

    // 获取对应设备的分数
    fun getScore(deviceId: String): Int {
        return prefs.getInt("score_$deviceId", 0)
    }
}

在Compose中使用:

val context = LocalContext.current
val scoreManager = remember { ScoreManager(context) }
val androidId = getAndroidId(context)

// 示例:保存分数
scoreManager.saveScore(androidId, 150)

// 示例:获取当前分数
val currentHighScore = scoreManager.getScore(androidId)

2. 云端存储(可选,支持跨设备同步)

如果后续需要跨设备同步分数,可以把设备ID作为用户唯一标识,上传到后端数据库(比如Firebase、自建后端)。以Firebase实时数据库为例:

import com.google.firebase.database.FirebaseDatabase

// 上传分数到云端
fun saveScoreToCloud(deviceId: String, score: Int) {
    val db = FirebaseDatabase.getInstance().reference
    db.child("snake_game_users").child(deviceId).child("high_score").setValue(score)
}

// 从云端获取分数
fun getScoreFromCloud(deviceId: String, onResult: (Int) -> Unit) {
    val db = FirebaseDatabase.getInstance().reference
    db.child("snake_game_users").child(deviceId).child("high_score")
        .get()
        .addOnSuccessListener { snapshot ->
            onResult(snapshot.value as? Int ?: 0)
        }
}

三、关键注意事项

  • 不要使用IMEI、MAC地址等标识:Android 10及以上版本已禁止第三方应用获取这些信息,且需要危险权限,审核容易被拒。
  • Android ID在极少数定制ROM上可能存在变动,但主流设备上稳定性足够。
  • 若用户恢复出厂设置,Android ID会重置,对应分数也会丢失,这属于正常的设备重置行为。

内容的提问来源于stack exchange,提问作者Yunus Emrah Uluçay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 20:40:08