Kotlin 实战:Android 设备语言与国家地区的 5 种获取方式

Kotlin 实现获取 Android 国家/地区和语言信息

在 Android 应用中获取用户的国家/地区和语言信息有多种方法,以下是几种常见的 Kotlin 实现方式:

1. 获取设备当前语言

kotlin 复制代码
// 获取当前系统语言代码 (例如 "en", "zh")
val languageCode = Locale.getDefault().language

// 获取完整语言标签 (例如 "en-US", "zh-CN")
val languageTag = Locale.getDefault().toLanguageTag()

// 获取显示名称 (例如 "English", "中文")
val displayName = Locale.getDefault().displayName

2. 获取设备国家/地区

kotlin 复制代码
// 方法1:通过Locale获取 (可能返回空字符串)
val countryCode = Locale.getDefault().country // 例如 "US", "CN"

// 方法2:通过TelephonyManager获取 (需要权限)
fun getCountryFromTelephony(context: Context): String? {
    return if (ContextCompat.checkSelfPermission(
            context,
            Manifest.permission.READ_PHONE_STATE
        ) == PackageManager.PERMISSION_GRANTED
    ) {
        val telephonyManager = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
        telephonyManager.simCountryIso ?: telephonyManager.networkCountryIso
    } else {
        null
    }
}

// 方法3:通过Network获取 (需要权限)
fun getCountryFromNetwork(context: Context): String? {
    val locale = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        context.resources.configuration.locales[0]
    } else {
        context.resources.configuration.locale
    }
    return locale.country
}

3. 获取用户首选语言列表

kotlin 复制代码
// 获取用户设置的所有语言偏好 (按优先级排序)
fun getPreferredLanguages(context: Context): List<Locale> {
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        context.resources.configuration.locales.toList()
    } else {
        listOf(context.resources.configuration.locale)
    }
}

4. 使用 AndroidX 的 LocaleManager (API 33+)

kotlin 复制代码
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
fun getSystemLocales(context: Context): List<Locale> {
    val localeManager = context.getSystemService(Context.LOCALE_SERVICE) as LocaleManager
    return localeManager.systemLocales.toList()
}

5. 完整工具类示例

kotlin 复制代码
import android.content.Context
import android.Manifest
import android.content.pm.PackageManager
import android.os.Build
import android.telephony.TelephonyManager
import androidx.core.content.ContextCompat
import java.util.*

class LocaleHelper {

    companion object {
        
        // 获取当前语言代码
        fun getCurrentLanguage(): String {
            return Locale.getDefault().language
        }

        // 获取当前国家代码
        fun getCurrentCountry(): String {
            return Locale.getDefault().country
        }

        // 获取设备可能的国家代码 (尝试多种方法)
        fun getDeviceCountry(context: Context): String {
            return when {
                // 1. 首先尝试从SIM卡获取
                ContextCompat.checkSelfPermission(
                    context,
                    Manifest.permission.READ_PHONE_STATE
                ) == PackageManager.PERMISSION_GRANTED -> {
                    val tm = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
                    tm.simCountryIso?.takeIf { it.isNotBlank() }
                        ?: tm.networkCountryIso?.takeIf { it.isNotBlank() }
                        ?: getCurrentCountry()
                }
                
                // 2. 尝试从网络获取
                getCurrentCountry().isNotBlank() -> getCurrentCountry()
                
                // 3. 最后使用默认值
                else -> "US"
            }.uppercase(Locale.ROOT)
        }

        // 获取用户设置的所有语言偏好
        fun getUserPreferredLocales(context: Context): List<Locale> {
            return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                context.resources.configuration.locales.toList()
            } else {
                listOf(context.resources.configuration.locale)
            }
        }

        // 检查是否使用特定语言 (如中文)
        fun isUsingChinese(): Boolean {
            return Locale.getDefault().language == "zh"
        }
    }
}

使用示例

kotlin 复制代码
// 获取当前语言和国家
val language = LocaleHelper.getCurrentLanguage() // "zh"
val country = LocaleHelper.getCurrentCountry()  // "CN"

// 获取设备国家 (更可靠的方式)
val deviceCountry = LocaleHelper.getDeviceCountry(context) // "CN"

// 检查是否使用中文
if (LocaleHelper.isUsingChinese()) {
    // 显示中文内容
}

注意事项

  1. 权限要求:

    • 读取 SIM 卡信息需要 READ_PHONE_STATE 权限
    • 在 Android 10 及以上版本,可能无法获取完整的 SIM 卡信息
  2. 兼容性:

    • 不同 Android 版本获取方式可能不同
    • 某些设备可能返回空值
  3. 用户偏好:

    • 用户可能在系统设置中更改了语言偏好
    • 考虑提供应用内语言覆盖选项
  4. 格式化:

    • 国家代码通常是大写的 ISO 3166-1 alpha-2 代码
    • 语言代码通常是小写的 ISO 639-1 代码
相关推荐
千里马学框架6 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台6 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone6 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc6 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo6 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077006 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
ai2work6 天前
ch23 综合复刻:从零做一个最小可用版本(capstone)
kotlin
其实防守也摸鱼6 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
ai2work6 天前
ch21 签名、校验与发版
kotlin
AFinalStone6 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui