My app was working fine, then all of a sudden, I started getting these null pointer errors. For some reason the alarm object is not being retrieved by the code.
var alarm = alarmRepository.getAlarm(intentAlarmId.toLong())
I have no idea why. Even if I replace intentAlarmId.toLong() with a 1, it will still not retrieve it. So it is not that. It takes an intent extra containing the alarm id, and gets it from the room database. I have narrowed it down to the alarm object being null. I just don't know why it is doing that. It was working then all of a sudden it is not, with no explanation.
/////// 2022-06-24 07:59:51.814 2753-2753/com.example.alarmapp2 E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.alarmapp2, PID: 2753 java.lang.RuntimeException: Unable to start receiver com.example.alarmapp2.AlarmReceiver: java.lang.NullPointerException at android.app.ActivityThread.handleReceiver(ActivityThread.java:4041) at android.app.ActivityThread.access$1400(ActivityThread.java:237) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1924) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:223) at android.app.ActivityThread.main(ActivityThread.java:7656) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) Caused by: java.lang.NullPointerException at com.example.alarmapp2.AlarmReceiver.onReceive(AlarmReciever.kt:61) at android.app.ActivityThread.handleReceiver(ActivityThread.java:4032) at android.app.ActivityThread.access$1400(ActivityThread.java:237) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1924) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:223) at android.app.ActivityThread.main(ActivityThread.java:7656) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
/////
class AlarmReceiver: BroadcastReceiver(){
@RequiresApi(Build.VERSION_CODES.O)
private lateinit var alarmIntent: Intent
private lateinit var alarmPendingIntent: PendingIntent
private var alarmMgr: AlarmManager? = null
private lateinit var calendar: Calendar
@RequiresApi(Build.VERSION_CODES.O)
override fun onReceive(context: Context, intent: Intent?) {
var intentAlarmId = ""
val alarmRepository = AlarmRepository.get()
if (intent != null) {
intentAlarmId = intent.getStringExtra("alarmId").toString()
//intentAlarmId = "1"
val text = "Intent is not NULL!"
val duration = Toast.LENGTH_SHORT
val toast = Toast.makeText(context, text, duration)
toast.show()
}
var alarm = alarmRepository.getAlarm(intentAlarmId.toLong())
// take alarm into if and see if todays day matches the true boolean of the alarm and
// acitivate the notification if it does.
/* val channelID = "com.example.lazyalarm.main.channel1"
var notificationManager:NotificationManager? = null
notificationManager = getSystemService(context, NotificationManager::class.java) as NotificationManager
createNotificationChannel(channelID, "alarmChannel", "alarmsNotificationChannel")
val notifcationId = 45
val notificaiton = NotificationCompat.Builder( context, channelID)
.setContentTitle(("Demo Notif Title"))
.setContentText("This is a notification!")
.setSmallIcon(android.R.drawable.ic_dialog_info)
.setAutoCancel(true)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.build()
notificationManager?.notify(notifcationId, notificaiton)*/
if (alarm.monday && LocalDate.now().dayOfWeek.toString() == "MONDAY") {
val text = "Its Monday!"
val duration = Toast.LENGTH_SHORT
val toast = Toast.makeText(context, text, duration)
toast.show()
} //fixme put other ifs in and make the alarm repeating
if (alarm.tuesday && LocalDate.now().dayOfWeek.toString() == "TUESDAY") {
val text = "Its Tuesday!"
val duration = Toast.LENGTH_SHORT
val toast = Toast.makeText(context, text, duration)
toast.show()
}
if (alarm.wednesday && LocalDate.now().dayOfWeek.toString() == "WEDNESDAY") {
val text = "Its Wednesday!"
val duration = Toast.LENGTH_SHORT
val toast = Toast.makeText(context, text, duration)
toast.show()
}
if (alarm.thursday && LocalDate.now().dayOfWeek.toString() == "THURSDAY") {
val text = "Its Thursday!"
val duration = Toast.LENGTH_SHORT
val toast = Toast.makeText(context, text, duration)
toast.show()
}
if (alarm.friday && LocalDate.now().dayOfWeek.toString() == "FRIDAY") {
val text = "Its Friday"
val duration = Toast.LENGTH_SHORT
val toast = Toast.makeText(context, text, duration)
toast.show()
}
if (alarm.saturday && LocalDate.now().dayOfWeek.toString() == "SATURDAY") {
val text = "Its Saturday!"
val duration = Toast.LENGTH_SHORT
val toast = Toast.makeText(context, text, duration)
toast.show()
}
if (alarm.sunday && LocalDate.now().dayOfWeek.toString() == "SUNDAY") {
val text = "Its sunday!"
val duration = Toast.LENGTH_SHORT
val toast = Toast.makeText(context, text, duration)
toast.show()
}
/////////////////
package com.example.alarmapp2.DataBase
import android.content.Context
import androidx.room.Room
import com.example.alarmapp2.Alarm
import com.example.alarmapp2.AlarmTimeEntity
import com.example.alarmapp2.MainActivity
import java.util.concurrent.Executors
private const val DATABASE_NAME = "alarm_database2"
class AlarmRepository private constructor(context: Context) {
val db = Room.databaseBuilder(
context.applicationContext,
AlarmDataBase::class.java, "alarm_database2"
).allowMainThreadQueries().build()
private val alarmDao = db.alarmDao()
fun getAlarmList(): List<Alarm> = alarmDao.getAllAlarms()
fun getAlarm(id: Long): Alarm = alarmDao.getAlarm(id)
fun addAlarm(alarm: Alarm) {
alarmDao.insertAlarm(alarm)
}
fun addAlarmTime(alarmTime: AlarmTimeEntity) {
alarmDao.insertAlarmTime(alarmTime)
}
fun deleteAlarms() {
//executor.execute {
alarmDao.deleteAlarms()
//}
}
fun updateAlarm(alarm: Alarm) {
alarmDao.updateAlarm(alarm)
}
companion object {
private var INSTANCE: AlarmRepository? = null
fun initialize(context: MainActivity) {
if (INSTANCE == null) {
INSTANCE = AlarmRepository(context)
}
}
fun get(): AlarmRepository {
return INSTANCE
?: throw IllegalStateException("AlarmRepository must be initialized")
}
}
}
//////////
package com.example.alarmapp2.DataBase
import androidx.room.*
import com.example.alarmapp2.Alarm
import com.example.alarmapp2.AlarmTimeEntity
@Dao
interface AlarmDatabaseDao {
@Insert
fun insertAlarm(alarm: Alarm)
@Insert
fun insertAlarmTime(alarmTime: AlarmTimeEntity)
@Update
fun updateAlarmTime(alarmTime: AlarmTimeEntity)
@Update
fun updateAlarm(alarm: Alarm)
@Query("SELECT * FROM alarm_table ORDER BY cast (hour as int) ASC, cast (minute as int) ASC")
fun getAllAlarms(): List<Alarm>
@Query("SELECT * FROM alarm_table where alarmId = :id")
fun getAlarm(id: Long): Alarm
@Query("DELETE FROM alarm_table WHERE deleteCheck = 1")
fun deleteAlarms(): Integer
@Query("DELETE FROM alarm_time_table WHERE alarmId = :id")
fun deleteAlarmTimesWithAlarmId(id: Long): Integer
@Delete
fun deleteAlarmTime(alarmTime: AlarmTimeEntity)
@Delete
fun deleteAlarm(alarm: Alarm)
}
CodePudding user response:
The exception's stacktrace should actually show you where the root of null is.
My bet is your DAO: what happens if there is no matching Alarm in your database? You define your getAlarm
function with a non-nullable type. But the underlying query could also yield no result which would lead to a null Alarm
.
Try changing the signature to fun getAlarm(id: Long): Alarm?
(mind nullable Alarm
) and adjust consuming code accordingly.
CodePudding user response:
For anyone who cares, I found out why it was null. I have not fixed this issue, but it is being caused by the intent.putextra. The alarm id I was adding to the intent was staying the same, so when i deleted the alarms, the intent would keep the same alarm id referring to alarms that were not there. For any expert android developer, i would think this would be pretty obvious. Not everyone knows intents keep their extra information until the phone is restarted. Guess I know now, but I got my question downvoted by some jerk that thinks this knowledge is imparted at birth. You just need to clear the intent, and add in the new id. Thanks guys! best of luck to all your honest new developers that are trying hard at something.