0

I am trying to schedule SMS messages in my app, using alarm manager with the RTC_WAKEUP type so that it will fire even when the device is in doze mode (as it needs to be exact). I have had reports of it not working and in my own testing it seems that if I for example schedule a message for an hour ahead it will fire, but then scheduling for the next day does not fire. (I have verified that the times being scheduled are correct).

Here is the code for the scheduling:

fun scheduleTimeMessage(activity: Context, time: Long) {
        val manager = activity.getSystemService(Context.ALARM_SERVICE) as AlarmManager
        val intent = Intent(activity, TimeSendReceiver::class.java)
        intent.putExtra("TIME", time)

        Log.e("ERROR?", "Time is " + time + SimpleDateFormat(" dd/MM/yy hh:mm", Locale.US).format(Date(time)))

        if (Build.VERSION.SDK_INT >= 23)
            manager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, time, PendingIntent.getBroadcast(activity, time.toInt(), intent, PendingIntent.FLAG_UPDATE_CURRENT))
        else
            manager.setExact(AlarmManager.RTC_WAKEUP, time, PendingIntent.getBroadcast(activity, time.toInt(), intent, PendingIntent.FLAG_UPDATE_CURRENT))
    }

Here is the BroadcastReceiver:

class TimeSendReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        val epoch = intent.getLongExtra("TIME", 0)
        val database = SchedulerDatabase(context)
        val cursor = database.getTimeCursor(epoch)

        if (cursor.moveToFirst()) {
            do {
                if (cursor.getString(cursor.getColumnIndex("Address")).contains(","))
                    sendGroupMessage(context, cursor)
                else {
                    if (cursor.getString(cursor.getColumnIndex("Image")) == "")
                        sendSMSMessage(context, cursor)
                    else
                        sendMMSMessage(context, cursor)
                }
            } while (cursor.moveToNext())
            database.deleteMessageData(epoch)
            cursor.close()
        }
    }
}
Nick Mowen
  • 2,572
  • 2
  • 22
  • 38

2 Answers2

1

Ok this one is hard to test (I would have to wait for a day for one test), but here a some things you might try:

Check out the WakefulBroadcastReceiver, explained in this post

Check whether your device has some battery optimization settings. This can result in your app being killed after some time and all it's alarms being canceled. You should be able to turn off optimization for certain apps.

Adrian K
  • 3,942
  • 12
  • 15
  • Thank you for this. I'll look into the wakeful receiver. I actually did have the battery optimizations turned off so it seems as though that wasn't it. Also like I said I tried on an emulator forcing doze and it still sent. – Nick Mowen Dec 12 '17 at 13:21
0

I ended up using the JobScheduler API and I set the JobInfo.Builder to:

val jobInfo = JobInfo.Builder(Constants.JOB_SCEDULE_ID, ComponentName())
    .setOverrideDeadLine(millis + 100)
    .setMinimumLatency(millis - 100)
    .build()

This makes it so that the scheduler wakes up the device on the necessary time as needed by the user, but uses smart scheduling.

Nick Mowen
  • 2,572
  • 2
  • 22
  • 38