我正在尝试发出警报,在应用程序关闭时发送通知。我在 MainActivity 中创建了一个警报管理器,并为 BroadcastReceiver 创建了一个内部类,一旦触发
onReceive()
,我就需要发送通知。警报有效,但每次尝试发送通知时,我都会收到错误
2020-03-25 13:19:33.166 15045-15045/com.kotlin.ambulantlcs E/AndroidRuntime:致命异常:main 进程:com.kotlin.ambulantlcs,PID:15045 java.lang.RuntimeException:无法启动接收器 com.kotlin.ambulantlcs.ui.MainActivity$Receiver: kotlin.UninitializedPropertyAccessException:lateinit 属性 notificationManager 尚未初始化 在 android.app.ActivityThread.handleReceiver(ActivityThread.java:3997) 在 android.app.ActivityThread.access 1500 美元(ActivityThread.java:267) 在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:1992) 在 android.os.Handler.dispatchMessage(Handler.java:107) 在 android.os.Looper.loop(Looper.java:237) 在 android.app.ActivityThread.main(ActivityThread.java:7777) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1047) 引起原因:kotlin.UninitializedPropertyAccessException:lateinit 属性 notificationManager 尚未初始化 在 com.kotlin.ambulantlcs.ui.MainActivity$Receiver.onReceive(MainActivity.kt:100) 在 android.app.ActivityThread.handleReceiver(ActivityThread.java:3988) 在 android.app.ActivityThread.access 1500 美元(ActivityThread.java:267) 在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:1992) 在 android.os.Handler.dispatchMessage(Handler.java:107) 在 android.os.Looper.loop(Looper.java:237) 在 android.app.ActivityThread.main(ActivityThread.java:7777) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1047)
请参阅下面我的完整代码:
import android.app.*
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.widget.RemoteViews
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.NavOptions
import androidx.navigation.Navigation
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.NavigationUI
import com.kotlin.ambulantlcs.R
import com.kotlin.ambulantlcs.storage.SharedDataManager
import com.kotlin.ambulantlcs.ui.fragments.LoginFragmentDirections
import java.util.*
open class MainActivity : AppCompatActivity() {
lateinit var context: Context
lateinit var alarmManager: AlarmManager
val obj: MainActivity = this
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val appBarConfiguration = AppBarConfiguration
.Builder(R.id.homeFragment, R.id.loginFragment)
.build()
setAlarm()
if(SharedDataManager.getInstance(this).isLoggedIn) {
var navOptions = NavOptions.Builder()
.setPopUpTo(R.id.action_login_Home, true)
.build()
val navController = Navigation.findNavController(this, R.id.fragment)
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration)
navController.navigate(
LoginFragmentDirections.actionLoginHome()
)
} else {
val navController = Navigation.findNavController(this, R.id.fragment )
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration)
}
}
override fun onBackPressed() {
Toast.makeText(applicationContext, "Function is not allowed", Toast.LENGTH_SHORT).show()
}
override fun onSupportNavigateUp(): Boolean {
return NavigationUI.navigateUp(Navigation.findNavController(this, R.id.fragment), null)
}
fun setAlarm() {
Log.d("MainActivity", "Create: ${Date().toString()}")
context = this
alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
val seconds = 10 * 1000
val intent = Intent(context, Receiver::class.java)
val pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
Log.d("MainActivity", "SECONDS: ${seconds.toLong()}")
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, seconds.toLong(), seconds.toLong(), pendingIntent)
}
class Receiver : BroadcastReceiver() {
lateinit var notificationManager : NotificationManager
lateinit var notificationChannel : NotificationChannel
lateinit var builder : Notification.Builder
private val channelId = "i.apps.notifications"
private val description = "Test notification"
override fun onReceive(context: Context?, intent: Intent?) {
Log.d("MainActivity", " Receiver: ${Date().toString()}")
val intent = Intent(context, MainActivity::class.java)
val pIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
val contentView = RemoteViews("com.kotlin.ambulantlcs",
R.layout.activity_main)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
notificationChannel = NotificationChannel(
channelId,description,NotificationManager.IMPORTANCE_HIGH)
notificationChannel.enableLights(true)
notificationChannel.lightColor = Color.GREEN
notificationChannel.enableVibration(false)
notificationManager.createNotificationChannel(notificationChannel)
builder = Notification.Builder(context, channelId)
.setContent(contentView)
.setSmallIcon(R.drawable.ic_launcher_background)
.setContentIntent(pIntent)
}else{
builder = Notification.Builder(context)
.setContent(contentView)
.setSmallIcon(R.drawable.ic_launcher_background)
.setContentIntent(pIntent)
}
notificationManager.notify(1234,builder.build())
}
}
}
我该如何纠正这个问题?
你的notificationManger是null(你没有初始化他)。试试这个:
if (notificationManager == null) {
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
}
应用程序崩溃的原因是您没有初始化
notificationManager
。您可以在 lateinit var
类中初始化它,而不是将其声明为 Receiver
:
val notificationManager : NotificationManager = getSystemService(Context.NOTIFICATION_SERVICE)
lateinit
变量现在具有isInitialized
属性,用于检查变量是否已初始化。
你可以这样使用它:
if (!this::notificationManager.isInitialized) {
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
}else {
//THE NOTIFICATION MANAGER IS INITIALIZED
}