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

Android 12下如何使用TelephonyCallback.CellInfoListener获取小区信息?

Android 12 获取小区信息问题解决

你的代码存在几个关键问题,以下是修复步骤:

1. 修正权限问题

Android 10及以上版本获取小区信息必须持有ACCESS_FINE_LOCATION权限,Android 12还需要确保权限已动态申请(仅在Manifest中声明不够):

  • 首先在AndroidManifest.xml中添加权限声明:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" /> <!-- 部分场景需额外添加 -->
  • 在代码中动态申请权限:
// 注册权限申请回调
private val permissionLauncher = registerForActivityResult(ActivityResultContracts.RequestPermission()) { granted ->
    if (granted) {
        // 权限通过后注册监听
        registerCellInfoListener()
    }
}

// 检查权限并发起申请
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
    permissionLauncher.launch(Manifest.permission.ACCESS_FINE_LOCATION)
} else {
    registerCellInfoListener()
}

2. 修正TelephonyCallback实现语法与逻辑

你代码中TelephonyCallback的实现存在语法问题,且旧版本监听类型错误,修复后的完整代码如下:

private fun registerCellInfoListener() {
    val tm: TelephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        tm.registerTelephonyCallback(mainExecutor, object : TelephonyCallback(), TelephonyCallback.CellInfoListener {
            override fun onCellInfoChanged(cellInfo: List<CellInfo>) {
                // 解析具体小区信息,避免直接toString()输出无用内容
                val cellInfoContent = StringBuilder()
                cellInfo.forEach { info ->
                    when (info) {
                        is CellInfoLte -> {
                            val identity = info.cellIdentity
                            val signal = info.cellSignalStrength
                            cellInfoContent.append("LTE小区:\n")
                            cellInfoContent.append("eNodeB ID: ${identity.enbId}\n")
                            cellInfoContent.append("小区ID: ${identity.cellId}\n")
                            cellInfoContent.append("信号强度: ${signal.dbm} dBm\n\n")
                        }
                        is CellInfoGsm -> {
                            val identity = info.cellIdentity
                            val signal = info.cellSignalStrength
                            cellInfoContent.append("GSM小区:\n")
                            cellInfoContent.append("基站ID: ${identity.cid}\n")
                            cellInfoContent.append("信号强度: ${signal.dbm} dBm\n\n")
                        }
                        // 可扩展添加5G、WCDMA等其他网络类型的解析
                    }
                }
                testTextView?.text = cellInfoContent.toString()
            }
        })
    } else {
        // 旧版本需监听LISTEN_CELL_INFO而非信号强度
        val psListener = object : PhoneStateListener() {
            @SuppressLint("MissingPermission")
            override fun onCellInfoChanged(cellInfo: List<CellInfo>?) {
                super.onCellInfoChanged(cellInfo)
                cellInfo?.let {
                    val cellInfoContent = StringBuilder()
                    it.forEach { info ->
                        // 同上解析逻辑
                    }
                    testTextView?.text = cellInfoContent.toString()
                }
            }
        }
        tm.listen(psListener, PhoneStateListener.LISTEN_CELL_INFO)
    }
}

3. 关键注意事项

  • 不要依赖@SuppressLint("MissingPermission")跳过权限检查,必须确保用户已授予ACCESS_FINE_LOCATION,否则监听逻辑不会触发。
  • 旧版本中原代码监听的LISTEN_SIGNAL_STRENGTHS仅能获取信号强度,无法获取小区信息,需改为LISTEN_CELL_INFO。
  • 直接调用cellInfo.toString()只会输出对象内存地址,需根据CellInfo的具体网络类型提取有效参数。

内容的提问来源于stack exchange,提问作者Sara-Omidvar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 02:50:51