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
相关产品推荐
相关产品推荐

