使用 BroadcastReceiver 实现 Android 通知操作时出错

Posted

技术标签:

【中文标题】使用 BroadcastReceiver 实现 Android 通知操作时出错【英文标题】:Error while implementing Android Notification Actions with BroadcastReceiver 【发布时间】:2021-09-28 15:03:00 【问题描述】:

我正在尝试让通知中的操作按钮调用一种方法。我阅读并关注了一些文章,但在我的应用程序中发出通知后(应用程序本身编译没有问题),它崩溃并出现以下错误:

D/androidRuntime(28351): Shutting down VM
E/AndroidRuntime(28351): FATAL EXCEPTION: main
E/AndroidRuntime(28351): Process: com.example.tasko, PID: 28351
E/AndroidRuntime(28351): java.lang.RuntimeException: Unable to instantiate service com.example.tasko.Stopwatch: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
E/AndroidRuntime(28351):    at android.app.ActivityThread.handleCreateService(ActivityThread.java:3940)
E/AndroidRuntime(28351):    at android.app.ActivityThread.access$1500(ActivityThread.java:219)
E/AndroidRuntime(28351):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1875)
E/AndroidRuntime(28351):    at android.os.Handler.dispatchMessage(Handler.java:107)
E/AndroidRuntime(28351):    at android.os.Looper.loop(Looper.java:214)
E/AndroidRuntime(28351):    at android.app.ActivityThread.main(ActivityThread.java:7356)
E/AndroidRuntime(28351):    at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime(28351):    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
E/AndroidRuntime(28351):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
E/AndroidRuntime(28351): Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
E/AndroidRuntime(28351):    at android.content.ContextWrapper.getPackageName(ContextWrapper.java:145)
E/AndroidRuntime(28351):    at android.content.ComponentName.<init>(ComponentName.java:131)
E/AndroidRuntime(28351):    at android.content.Intent.<init>(Intent.java:6510)
E/AndroidRuntime(28351):    at com.example.tasko.Stopwatch.<init>(StopwatchService.kt:21)
E/AndroidRuntime(28351):    at java.lang.Class.newInstance(Native Method)
E/AndroidRuntime(28351):    at android.app.AppComponentFactory.instantiateService(AppComponentFactory.java:129)
E/AndroidRuntime(28351):    at androidx.core.app.CoreComponentFactory.instantiateService(CoreComponentFactory.java:75)
E/AndroidRuntime(28351):    at android.app.ActivityThread.handleCreateService(ActivityThread.java:3935)
E/AndroidRuntime(28351):    ... 8 more

这是我的简化代码:

class Stopwatch : Service() 
    // error at this line
    val intent = Intent(this, ActionReceiver::class.java).apply 
        action = "snooze"
    
    val pendingIntent: PendingIntent = PendingIntent.getBroadcast(this, 0, snoozeIntent, 0)

    private fun startForeground() 
        ...
        builder
            ...
            .addAction(R.drawable.ic_round_play_arrow_24, "Play", pendingIntent)
    

ActionReceiver.kt:

class ActionReceiver : BroadcastReceiver() 
    override fun onReceive(context: Context?, intent: Intent?) 
        println("Hello!")
    

【问题讨论】:

【参考方案1】:

问题是我需要在某些方法中初始化我的意图(在我的例子中是startForeground()),而不是在类初始化器中,如下所示:

class Stopwatch : Service() 
    private fun startForeground() 
        ...
        val intent = Intent(this, ActionReceiver::class.java).apply 
            action = "snooze"
        
        val pendingIntent: PendingIntent = PendingIntent.getBroadcast(this, 0, snoozeIntent, 0)
        builder
            ...
            .addAction(R.drawable.ic_round_play_arrow_24, "Play", pendingIntent)
    

【讨论】:

以上是关于使用 BroadcastReceiver 实现 Android 通知操作时出错的主要内容,如果未能解决你的问题,请参考以下文章

BroadCast,BroadCastReceiver

BroadcastReceiver的实现

BroadcastReceiver之实现锁屏解锁样例

使用BroadcastReceiver实现开机自动运行的Service

使用BroadcastReceiver实现系统对手机电量进行提示

BroadcastReceiver应用详解——广播