Reputation: 5904
I want to build a very simple app that will trigger a "ding" every 5 minutes for 1 hour. It will also show a progress on the screen.
The problem I encountered until now is that if I use AsyncTasks, Threads or Handlers, the background task stops the moment the phone enters into the sleep state.
The app must be able to play the "ding" even if in background or the phone is in sleep mode.
Please advice what architecture or API to use.
Upvotes: 0
Views: 822
Reputation: 47
You can make a foreground service and use Timer class in it. Check https://developer.android.com/guide/components/services
Upvotes: 0
Reputation: 24907
I want to build a very simple app that will trigger a "ding" every 5 minutes for 1 hour. It will also show a progress on the screen.
You can create Foreground Service which can easily update the notification to indicate the progress. Do note that this service won't run indefinitely, if OS detects you are performing CPU intensive work, this service could also get terminated. You can follow this SO for implementation details.
You can also use WorkManager
, if its not mandatory to request "ding" every 5 minutes. Do note that minimum frequency for triggering WorkManager
is 15 minutes and you cannot pin point exactly that the Work will be triggered at 15 minutes. You can follow this SO for implementation details.
Upvotes: 2
Reputation: 417
background task stops the moment the phone enters into the sleep state.
I would suggest you set alarm with alarmmanager and to use setExactAndAllowWhileIdle
for devices with 6.0 or greater. (checkout answer by @Jo Jo Roid here)
Please advice what architecture or API to use.
You can get long time = System.getCurrentTimeInMillis();
and then creating Calendar instance setting time to calender.setTimeInMillis(time + (5 * 60 * 1000));
AlarmManager am;
Intent intent = new Intent(this, YourBroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
if (Build.VERSION.SDK_INT >= 23) {
// Wakes up the device in Doze Mode
am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, time,
pending);
} else if (Build.VERSION.SDK_INT >= 19) {
// Wakes up the device in Idle Mode
am.setExact(AlarmManager.RTC_WAKEUP, time, pending);
} else {
// Old APIs
am.set(AlarmManager.RTC_WAKEUP, time, pending);
}
When your BroadcastReceiver receives Broadcast, set next another alarm by adding 5 mins to current time. Repeat this for 11 times when you receive broadcast and play Ding sound from AlarmStream. Simple!
You might be wondering "Why not use repeating alarm". Well to allow while in idle above M its the only workaround.
Also to show progress you can show notification with progressBar. (Because where else will you show progress if user leaves app or removes it from recents?
P.S. Don't forget to register your BroadcastReceiver and ask WAKE_LOCK permission in Manifest also.
Upvotes: 0
Reputation: 1348
You should schedule the tasks using WorkManager
which is the recommended approach and does all the heavy lifting for you.
To know more, visit the official docs.
Upvotes: 2