Alex
Alex

Reputation: 5904

Android: Simple timer to run in background

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

Answers (4)

Khaled Alramam
Khaled Alramam

Reputation: 47

You can make a foreground service and use Timer class in it. Check https://developer.android.com/guide/components/services

Upvotes: 0

Sagar
Sagar

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

Aaditya Brahmbhatt
Aaditya Brahmbhatt

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

Mehul Kanzariya
Mehul Kanzariya

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

Related Questions