Kotlin开发Android应用:BroadcastReceiver触发通知失效问题排查
Android BroadcastReceiver 通知推送失效问题排查与修复
我用Kotlin开发一款Android应用,希望在日期变更(DATE_CHANGED)、屏幕点亮(SCREEN_ON)、设备开机完成(BOOT_COMPLETED)时推送通知。尝试用BroadcastReceiver实现,但功能没生效,以下是相关代码:
BroadcastReceiver 实现代码
import android.app.NotificationManager import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import androidx.appcompat.app.AppCompatActivity import androidx.core.app.NotificationCompat class SendNotification: BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { if (intent?.action == Intent.ACTION_DATE_CHANGED || intent?.action == Intent.ACTION_SCREEN_ON || intent?.action == Intent.ACTION_BOOT_COMPLETED){ println(intent) println(context) val hours = TOTKTime.getHours() val days = TOTKTime.getDays() val notificationManager = context?.getSystemService(AppCompatActivity.NOTIFICATION_SERVICE) as NotificationManager val notification = NotificationCompat.Builder(context, "TOTK").setContentText("about ${days}days, ${hours} hours left until TOTK's release").setContentTitle("time until tears of the kingdom").setSmallIcon(R.mipmap.ic_totk).build() notificationManager.notify(1, notification) } } }
AndroidManifest.xml 配置
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <application android:name=".app" android:allowBackup="true" android:dataExtractionRules="@xml/data_extraction_rules" android:fullBackupContent="@xml/backup_rules" android:icon="@mipmap/ic_totk_round" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/Theme.TOKTTimer" tools:targetApi="31"> <activity android:name=".MainActivity" android:exported="true" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <receiver android:name=".SendNotification" android:exported="false"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> <action android:name="android.intent.action.SCREEN_ON" /> <action android:name="android.intent.action.DATE_CHANGED" /> </intent-filter> </receiver> </application> </manifest>
通知通道初始化代码
import android.app.Application import android.app.NotificationChannel import android.app.NotificationManager import android.content.Context class app: Application() { override fun onCreate() { super.onCreate() val channel = NotificationChannel( "TOTK", "Time till TOKT", NotificationManager.IMPORTANCE_HIGH ) val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager notificationManager.createNotificationChannel(channel) } }
问题排查与修复方案
1. 静态广播接收限制(Android 8.0+)
Android 8.0(API 26)起,ACTION_SCREEN_ON、ACTION_DATE_CHANGED这类隐式广播无法通过静态注册的BroadcastReceiver接收,系统会直接忽略这类静态注册的广播,只有ACTION_BOOT_COMPLETED属于少数可静态注册的例外,但仍需满足额外条件。
2. 调整SCREEN_ON与DATE_CHANGED的接收方式
这两个广播必须通过动态注册实现:
在Activity或Service中,在合适的生命周期节点(如onResume())注册BroadcastReceiver,onPause()时注销,避免内存泄漏。示例代码如下:
class MainActivity : AppCompatActivity() { private lateinit var notificationReceiver: SendNotification override fun onResume() { super.onResume() notificationReceiver = SendNotification() val intentFilter = IntentFilter().apply { addAction(Intent.ACTION_SCREEN_ON) addAction(Intent.ACTION_DATE_CHANGED) } registerReceiver(notificationReceiver, intentFilter) } override fun onPause() { super.onPause() unregisterReceiver(notificationReceiver) } }
3. BOOT_COMPLETED静态注册的注意事项
- 应用必须至少被用户手动启动过一次,否则系统不会向从未启动的应用发送开机广播。
- 部分厂商的系统存在后台限制,需手动允许应用的「自启动」权限,否则开机广播可能无法被接收。
4. 其他潜在问题修复
- NotificationManager获取方式优化:把
AppCompatActivity.NOTIFICATION_SERVICE替换为Context.NOTIFICATION_SERVICE,避免上下文类型不匹配导致的异常:val notificationManager = context?.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager - 动态申请通知权限:Android 13(API 33)及以上版本,需在运行时动态申请
POST_NOTIFICATIONS权限,否则通知无法弹出。在MainActivity的onCreate()中添加权限申请逻辑:import android.os.Build import android.Manifest import android.content.pm.PackageManager override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { if (checkSelfPermission(Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) { requestPermissions(arrayOf(Manifest.permission.POST_NOTIFICATIONS), 1001) } } } - 校验业务逻辑:确保
TOTKTime类的getHours()和getDays()方法能正常返回有效值,避免因空值或异常导致通知构建失败。
内容的提问来源于stack exchange,提问作者rxt01
相关产品推荐
相关产品推荐

