'Alarm manager show notification every time when i open the app

I am using the requestj api to send and receive the data from server and setting up the alarm on time that i received from server and alarm calls two hours ago from received time but issue is that when alarm fire on exact time it also fire every time when api calls till that 2 hours didn't completed. Any one know how to prevent it? 1.API code is here

    fun getAllFriendsReminders(context: Context) {
        val getReminderHttpRequest = HttpRequest()
//        val myList = ArrayList<FriendsRemindersListModel>()
        getReminderHttpRequest.setOnResponseListener { getReminderListResponse ->

            Log.e("getReminders List", getReminderListResponse.code.toString())
            Log.e("getReminders List", getReminderListResponse.text)
            if (getReminderListResponse.code == HttpResponse.HTTP_OK) {
                Log.e("getReminders List", getReminderListResponse.code.toString())
                val jsonArray = getReminderListResponse.toJSONArray()

                getReminderListModel.clear()
                Log.e("list", jsonArray.length().toString())
                Log.e("list", jsonArray.toString())

                val loggedInUser = appGlobals.getValueString("loginUsername")

                for (i in 0 until jsonArray!!.length()) {

                    if (!onForeGround) {
                        progressBar!!.progress = i
                    }
                    Log.e("listi", i.toString())

                    val jsonObject = jsonArray.getJSONObject(i)

                    friendReminderText = jsonObject.getString("reminder")
                    friendReminderFromName = jsonObject.getString("reminder_from")
                    friendReminderToName = jsonObject.getString("reminder_to")
                    friendReminderDate = jsonObject.getString("date")
                    friendReminderStatus = jsonObject.getString("status")
                    friendReminderId = jsonObject.getString("id")

                    if (friendReminderFromName != loggedInUser) {
                        getReminderListModel.add(FriendsRemindersListModel(0, friendReminderId.toInt(),friendReminderText,
                            friendReminderDate, friendReminderFromName, friendReminderToName, friendReminderStatus))

                        //Received date time from server
                        val dateTimeFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy hh:mm:ss a")
//                        val dateFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy")
//                        val timeFormatter = DateTimeFormatter.ofPattern("hh:mm:ss a")

                        val instant = Instant.ofEpochMilli(friendReminderDate.toLong())
                        val instant1 = Instant.ofEpochMilli(friendReminderDate.toLong() - (120 * 60 * 1000))
                        val date = LocalDateTime.ofInstant(instant, ZoneId.systemDefault())
                        val date1 = LocalDateTime.ofInstant(instant1, ZoneId.systemDefault())
//                        val exactDate = dateFormatter.format(date)
//                        val exactTime = timeFormatter.format(date)
                        val exactDateTime = dateTimeFormatter.format(date)

                        val alarmDate = Date(friendReminderDate.toLong())

                        //Current date time
                        val dates = Date()
                        val stringFormat = SimpleDateFormat("dd-MM-yyyy hh:mm:ss a")
                        val dateTimeTo = stringFormat.format(dates.time)

                        //Set Alarm

                        if (alarmDate.after(dates)) {
                            Log.d("D", dates.toString())
                            Log.d("AlarmDate", alarmDate.toString())
                            Log.e("2 hour ago", dateTimeFormatter.format(date1))
                            println(friendReminderDate.toLong() - (120 * 60 * 1000))
                            Log.e("Set", exactDateTime)

                            val alarmManager: AlarmManager = context.getSystemService(
                                AppCompatActivity.ALARM_SERVICE) as AlarmManager
                            val alarmIntent = Intent(requireContext(), AlarmReceiver::class.java)
                            val pendingIntent = PendingIntent.getBroadcast(context, 0, alarmIntent, 0)

                            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
                                Log.e("Alarm", "Alarm")
                                alarmManager.setAlarmClock(AlarmManager.AlarmClockInfo(friendReminderDate.toLong() - 120*60*1000,
                                    pendingIntent), pendingIntent)
                            } else {
                                Log.e("Alarm1", "${friendReminderDate.toLong() - (120 * 60 * 1000)}")
                                alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,
                                    (friendReminderDate.toLong()) - 120 * 60 * 1000,
                                    pendingIntent)
                                Log.e("Alarm2", "Alarm")
                            }
                        }
//                        if (exactDateTime > dateTimeTo) {
//
//                        }
                    }
                }

                if (friendReminderFromName != loggedInUser) {

                    if (friendReminderId != "") {
                        reminder = FriendsRemindersListModel(0, friendReminderId.toInt(), friendReminderText, friendReminderDate,
                            friendReminderFromName, friendReminderToName, friendReminderStatus)
                    }
                }

                if (getReminderListModel.size.toString() > remindersListModel.size.toString()) {
                    Log.e("serverListSize", getReminderListModel.size.toString())
                    Log.e("dbListSize", remindersListModel.size.toString())
                    Log.e("JsonListSize", jsonArray.length().toString())

                    for (i in 0 until getReminderListModel.size - 1) {
                        Log.e("present", getReminderListModel[i].reminderId.toString())
                        var isPresent = false
                        for (j in 0 until remindersListModel.size - 1) {
                            Log.e("present", remindersListModel.toString())

                            if (remindersListModel.isNotEmpty()) {
                                if (getReminderListModel[i].reminderId == remindersListModel[i].reminderId) {
                                    isPresent = true
                                }
                            }
                        }
                        Log.e("presenting", "${!isPresent}")

                        if (isPresent) {
                            remindersViewModel.addingReminder(reminder)

                        }
                    }
                }
                else if (getReminderListModel.size.toString() < remindersListModel.size.toString()) {
                    for (i in 0 until remindersListModel.size - 1) {
                        for (j in 0 until getReminderListModel.size - 1) {
//                        var isRemoved = false
//                        Log.e("i's", i.toString())
                            Log.e("i's", getReminderListModel.size.toString())
                            Log.e("i'ss", remindersListModel.size.toString())

                            if (remindersListModel.isNotEmpty()) {
                                Log.e("delete3", remindersListModel[i].reminderId.toString())
                                Log.e("delete3", remindersListModel[i].reminderText)
                                Log.e("delete4", getReminderListModel[j].reminderId.toString())
                                Log.e("delete4", getReminderListModel[j].reminderText)
                                if (remindersListModel[i].reminderId != getReminderListModel[i].reminderId ) {
                                    Log.e("delete2", remindersListModel[i].reminderId.toString())
                                    remindersViewModel.deleteReminder(remindersListModel[i].reminderId)
//                                    getReminderListAdapter.notifyItemRemoved(i)
                                }
                            }
                        }
                    }
                }

//                if (getReminderListModel.size.toString() != getRemindersDBList.size.toString()) {
//                    remindersViewModel.deleteReceivedReminders()
//                    remindersViewModel.addReminder(getReminderListModel)
//                }

                if (progressBar!= null) {
                    progressBar!!.visibility = View.GONE
                }
            }
        }

        getReminderHttpRequest.setOnErrorListener {
            if (progressBar != null) {
                progressBar!!.visibility = View.GONE
            }
            Log.e("getReminders error", "$it")
            Log.e("Alarm1", "${friendReminderDate.toLong() - (120 * 60 * 1000)}")

        }
        val token = appGlobals.getValueString("userToken")
        val headers = HttpHeaders("Authorization", "Token $token")
        getReminderHttpRequest.get(AppGlobals.GET_REMINDERS_LIST_API, headers)
    }

2. Alarm receiver class:

class AlarmReceiver: BroadcastReceiver() {
    @RequiresApi(Build.VERSION_CODES.O)
    @SuppressLint("UnsafeProtectedBroadcastReceiver")
    override fun onReceive(context: Context?, intent: Intent?) {

            showNotification(context!!, MessagingServiceFirebase.title, MessagingServiceFirebase.body)
        Log.e("Checking notify", "Notification")

//        Toast.makeText(context, "Alarm", Toast.LENGTH_SHORT).show()

        Log.e("Checking ", "Notification")

//        ringTone(context)
    }

//    private fun ringTone(context: Context) {
//        val alert: Uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM)
//        val ringtone: Ringtone = RingtoneManager.getRingtone(context, alert)
//
//        ringtone.play()
//        Toast.makeText(context, "Alarm Called", Toast.LENGTH_SHORT).show()
//    }

    fun showNotification(ctx: Context, title: String, message: String) {
        val notificationManager =
            ctx.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channelId = "channel"
            val name: CharSequence = "channel"
            val description = "The channel"
            val importance = NotificationManager.IMPORTANCE_HIGH
            val mChannel = NotificationChannel(channelId, name, importance)
            mChannel.description = description
            mChannel.enableLights(true)
            mChannel.lightColor = Color.RED
            mChannel.enableVibration(true)
            mChannel.vibrationPattern = longArrayOf(100, 200, 300, 400, 500, 400, 300, 200, 400)
            mChannel.setShowBadge(false)
            notificationManager.createNotificationChannel(mChannel)
        }
        val builder: NotificationCompat.Builder = NotificationCompat.Builder(ctx, "channel")
            .setSmallIcon(R.drawable.ic_baseline_access_alarm_24)
            .setContentTitle(title)
            .setContentText(message)
        val resultIntent = Intent(ctx, HomeActivity::class.java)
        val stackBuilder: TaskStackBuilder = TaskStackBuilder.create(ctx)
        stackBuilder.addParentStack(HomeActivity::class.java)
        resultIntent.putExtra("NotifyTitle", title)
        resultIntent.putExtra("NotifyMessage", message)
        stackBuilder.addNextIntent(resultIntent)
        val resultPendingIntent: PendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT)
        builder.setContentIntent(resultPendingIntent)
        builder.setAutoCancel(true)
        notificationManager.notify(12, builder.build())
    }

}

3. Manifest code

<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<receiver
            android:name=".AlarmReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
            </intent-filter>
        </receiver>


Solution 1:[1]

The (-2hrs) above is only correct, when you are in: (UTC +1) zone AND there is SUMMER (+1) or (UTC +2) zone AND there is WINTER (+0)


The correct datetime is in millis (kotlin datetime to millisecond convert using local zone and daylight offset):

val myalarmdatetime: String = "2022-05-31 23:59:59"
    
val myalarmdatetimemillis: Long =
        ZonedDateTime.of(
        LocalDateTime.parse(
        myalarmdatetime,
        DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
        ), ZoneId.systemDefault()
        ).toInstant().toEpochMilli()

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Tamas Szabo