Android应用被终止时如何检测来电 现有广播接收实现偶发失效咨询
安卓来电广播接收器偶发失效解决方案
一、权限适配补全
安卓高版本对电话相关权限限制严格,仅清单声明权限无法正常接收广播、获取来电信息:
- 在
AndroidManifest.xml中添加必要权限声明:
<!-- 读取电话状态基础权限 --> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <!-- 安卓10及以上获取来电号码必须权限 --> <uses-permission android:name="android.permission.READ_CALL_LOG" /> <!-- 悬浮窗显示权限 --> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
- 应用首次启动时主动申请以上动态权限,悬浮窗权限需要引导用户到系统设置页手动开启,未授权状态下系统不会将来电广播派发给你的应用。
二、广播配置与后台保活调整
- 调整接收器配置,提高优先级、添加广播权限校验避免无效触发:
<receiver android:name="InterceptCall" android:exported="true" android:enabled="true" android:permission="android.permission.READ_PHONE_STATE"> <!-- 优先级设为int最大值,避免被其他电话应用拦截广播 --> <intent-filter android:priority="2147483647"> <action android:name="android.intent.action.PHONE_STATE"/> </intent-filter> </receiver>
- 针对小米、华为、OPPO、vivo、鸿蒙等国内定制ROM,引导用户关闭应用的省电优化,允许应用后台自启动、关联启动,避免应用被系统后台查杀后收不到广播。
- 必要时可启动一个低功耗前台服务驻留后台,提高应用进程优先级,降低被系统回收的概率。
三、代码逻辑隐患修复
原代码存在空指针风险、权限校验缺失等问题,会导致部分场景下逻辑中断看似广播失效,优化后代码参考:
override fun onReceive(context: Context?, intent: Intent) { // 非法场景直接返回,避免异常崩溃 if (context == null || intent.action != TelephonyManager.ACTION_PHONE_STATE_CHANGED) return try { val state = intent.getStringExtra(TelephonyManager.EXTRA_STATE) ?: return val incomingNumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER) when (state) { TelephonyManager.EXTRA_STATE_RINGING -> { Log.d("INFO", "来电号码: ${incomingNumber ?: "未知号码"}") Toast.makeText(context, "Gelen Arama $incomingNumber", Toast.LENGTH_SHORT).show() incomingNumber?.let { // 先校验悬浮窗权限,避免无权限时崩溃 if (Settings.canDrawOverlays(context)) { // 避免重复创建悬浮窗实例 if (simpleFloatingWindow == null) { simpleFloatingWindow = SimpleFloatingWindow(context) } simpleFloatingWindow?.show() } } } TelephonyManager.EXTRA_STATE_OFFHOOK, TelephonyManager.EXTRA_STATE_IDLE -> { // 通话接通/挂断时销毁悬浮窗,避免内存泄漏 simpleFloatingWindow?.dismiss() simpleFloatingWindow = null } } } catch (e: Exception) { e.printStackTrace() } }
内容的提问来源于stack exchange,提问作者Ahmet Bugra Ozcan
相关产品推荐
相关产品推荐

