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

2024年Android 13读取手机状态失效问题求助

解决Android 13上通话状态BroadcastReceiver失效问题

核心原因

Android 13(API 33)对电话权限和广播机制做了收紧:

  • 静态注册的BroadcastReceiver无法接收大部分隐式广播(包括ACTION_PHONE_STATE_CHANGED),这一限制从Android 8.0开始逐步强化,Android 13彻底阻断静态注册的触发路径。
  • 电话相关权限拆分更细,获取通话时长、类型等信息需要额外权限。

具体修复步骤

  1. 更新权限配置与动态申请
    在AndroidManifest.xml中声明必要权限:

    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.READ_CALL_LOG" />
    <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
    

    由于这些是危险权限,必须在代码中动态申请(示例为Kotlin):

    private const val REQUEST_PHONE_PERMS = 1001
    
    fun checkPhonePermissions(context: Context) {
        val neededPermissions = arrayOf(
            Manifest.permission.READ_PHONE_STATE,
            Manifest.permission.READ_CALL_LOG,
            Manifest.permission.PROCESS_OUTGOING_CALLS
        )
        val missingPermissions = neededPermissions.filter {
            ContextCompat.checkSelfPermission(context, it) != PackageManager.PERMISSION_GRANTED
        }
        if (missingPermissions.isNotEmpty()) {
            ActivityCompat.requestPermissions(context as Activity, missingPermissions.toTypedArray(), REQUEST_PHONE_PERMS)
        }
    }
    
  2. 替换静态注册为动态注册
    删除AndroidManifest.xml中静态注册的InfluencerCallBroadcastReceiver,改为在Activity或前台服务中动态注册(确保App在前台时能稳定接收广播):

    private lateinit var callReceiver: InfluencerCallBroadcastReceiver
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 先检查权限再注册
        checkPhonePermissions(this)
        callReceiver = InfluencerCallBroadcastReceiver()
        val filter = IntentFilter().apply {
            addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED)
            addAction(Intent.ACTION_NEW_OUTGOING_CALL)
        }
        registerReceiver(callReceiver, filter)
    }
    
    override fun onDestroy() {
        super.onDestroy()
        // 务必注销接收器,避免内存泄漏
        unregisterReceiver(callReceiver)
    }
    
  3. 调整广播接收器逻辑适配Android 13
    在InfluencerCallBroadcastReceiver中,获取通话时长等信息时,需通过CallLog.Calls内容提供者查询(依赖READ_CALL_LOG权限),示例:

    override fun onReceive(context: Context?, intent: Intent?) {
        if (intent?.action == TelephonyManager.ACTION_PHONE_STATE_CHANGED) {
            val state = intent.getStringExtra(TelephonyManager.EXTRA_STATE)
            if (state == TelephonyManager.EXTRA_STATE_IDLE) {
                // 通话结束,查询最新通话记录
                context?.let { ctx ->
                    if (ContextCompat.checkSelfPermission(ctx, Manifest.permission.READ_CALL_LOG) == PackageManager.PERMISSION_GRANTED) {
                        val cursor = ctx.contentResolver.query(
                            CallLog.Calls.CONTENT_URI,
                            arrayOf(CallLog.Calls.DURATION, CallLog.Calls.TYPE, CallLog.Calls.NUMBER),
                            "${CallLog.Calls.DATE} > ?",
                            arrayOf((System.currentTimeMillis() - 60000).toString()),
                            "${CallLog.Calls.DATE} DESC"
                        )
                        cursor?.use {
                            if (it.moveToFirst()) {
                                val duration = it.getLong(it.getColumnIndexOrThrow(CallLog.Calls.DURATION))
                                val type = it.getInt(it.getColumnIndexOrThrow(CallLog.Calls.TYPE))
                                val number = it.getString(it.getColumnIndexOrThrow(CallLog.Calls.NUMBER))
                                // 上传至服务器的逻辑
                                uploadCallDetails(duration, type, number)
                            }
                        }
                    }
                }
            }
        }
    }
    
  4. 处理后台运行限制
    如果需要App在后台也能监听通话状态,必须启动前台服务(Android 12+对后台服务限制严格),在服务中完成广播接收器的注册,并显示前台通知。

内容的提问来源于stack exchange,提问作者Deepjyoty nath

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 12:52:53