28

I have a problem with AlarmManager, I set the code for scheduling a repeating alarm and after I run the application, the alarm runs fine. Even if I click on Home button (and the application is paused), the alarm still runs on its interval.

The problem is if I open the Task Manager and force close the application, then the alarm stops from running.

Is this a normal behavior, is there any way to avoid this and keep the alarm running after closing the application?

The code is below - the method is called by the ApplicationContext class, onCreate().

 private void scheduleAlarm() {
  if (alarmScheduled == true) { return; } // we only need to schedule once.

  int alarmInterval = Def.pref(getApplicationContext()).getInt("alarmInterval", 30);

  final Intent intent = new Intent(getApplicationContext(), CollectorAlarmReceiver.class);
  final PendingIntent pending = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, 0);

  AlarmManager alarmMgr = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);

  alarmMgr.cancel(pending); // cancel others.

  alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+1000,
    alarmInterval*1000, pending);

  Def.log(TAG,"scheduleAlarm(): alarm scheduled, interval: "+alarmInterval+" seconds");
  alarmScheduled = true;
 }

Receiver code:

public void onReceive(Context context, Intent intent) {
    Log.i(TAG, "CollectorAlarmReceiver invoked, starting CollectorService in background");

    context.startService(new Intent(context, CollectorService.class));

    Intent collectorService = new Intent(context,CollectorService.class);
    collectorService.putExtra("action", CollectorService.ACTION_BACKGROUND_REQUEST_MESSAGES);

    context.sendBroadcast(collectorService);
}

Thanks!

Allan Denot
  • 293
  • 1
  • 3
  • 8
  • Can you post your receiver code and an example of what alarmInterval would be? – ninjasense Jan 10 '11 at 06:20
  • I posted the code for Receiver. The alarmInterval is 30 seconds. You can see that there is a Log in the onReceive, so I can track when the Receiver is invoked. And while running the App, it works fine, the problem is when it is closed. – Allan Denot Jan 10 '11 at 06:54
  • Why don't you set a alarm clock in the system default clock. Then kill it by task manager and see if it behave like your app. If it also can't alarm you. I think it is ok for your app and you don't need to do anything. – Owen Zhao Aug 21 '13 at 22:02

7 Answers7

9

I believe @GSree is wrong. There's a simple way to achieve this. Just use a custom action. Here's how:

First, define a custom action name, such as:

public static final String MY_ACTION = "com.sample.myaction"

Then create a BroadcastReceiver:

public class MyAlarmReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(MY_ACTION)) {
            // Do something here
        }
    }    
}

Register the receiver on your AndroidManifest.xml:

<receiver android:name="com.sample.MyAlarmReceiver">
    <intent-filter>
        <action android:name="com.sample.myaction"/>
    </intent-filter>
</receiver>

Then, to setup the alarm, use the following PendingIntent:

Intent i = new Intent(MY_ACTION);
PendingIntent pi = PendingIntent.getBroadcast(getApplicationContext(), 0, i, 0);

There may be other ways to do it, but I tried this solution and the BroadcastReceiver gets called even if I force-quit my app from the shell.

Notice how this solution does not require you to create a service.

bmarcov
  • 170
  • 2
  • 9
  • 6
    tried this, not working after I force-quit my app, I'm using android 4.2.1. It only works when I tap the home button (the app is only paused - not killed). Any ideas why? – Sagi Mann Jan 05 '15 at 07:55
  • did anyone find issue on kitkat and up OS platform? this solution does not work there plz help – KOTIOS Jan 28 '16 at 08:00
  • 1
    This is equivalent to what OP is doing, and does not solve the problem of alarms being removed when the app quits – Christopher Pickslay May 15 '19 at 00:18
8

This is normal behaviour. If the user voluntarily force stop the applicaiton, then it should be stopped. Else, you are creating a virus like application.

If you really want, you could write another service which monitors if your other service is running and runs the service if the one is not running. But this will be another application and (you hope) the user wont kill this app using task manager.

Personally, I wouldn't worry. If the user stopped it, they wanted to stop it. Don't annoy the user.

GSree
  • 2,890
  • 1
  • 23
  • 25
  • 33
    I disagree as there are many apps that will do this with good intentions in mind such as a simple alarm clock. Also Android is not meant to have tasks killed via a task killer. – ninjasense Jan 10 '11 at 06:28
  • Yes, in my case, I want to reproduce the behaviour of Foursquare "ping" service, where you can receive notifications even after closing the Foursquare app. Facebook App does the same but I think it uses C2DM. Is C2DM the only way to do that without keeping a service in memory? – Allan Denot Jan 10 '11 at 06:49
  • 1
    You make a great point. But what happens with people that use the TaskKiller. They don't know that doing so means the alarms will not go off. I would rather not make a second application that monitors the actual app to make sure the alarms are set. Any ideas? (I know its an old post). – Andy Jul 07 '12 at 03:58
  • 8
    Your comment is nonsense. The OS can kill your app if it needs to free up memory or resources and if it does it will kill your alarms. Killing an app/service either manually or by the OS doing it shouldn't affect the scheduled alarms. If the user doesn't want a scheduled alarm running, the developer can provide a option in their app to turn it off. – Johann Apr 29 '13 at 07:59
  • 6
    GSree, in that case, how do you propose to write an alarm clock aplication? It is not possible? – Greg Ennis Dec 23 '14 at 15:10
  • I disagree with your answer –  Oct 19 '17 at 10:45
2

I've done this a few times, but wonder why ya'll are assigning a requestCode of 0; I'd think that giving your alarm a unique number would help a lot.

0

I have been able to do exactly what you need. Even if you stop the application through the running tab in the application manager tool, the service restarts itself. The only way to kill it is throught the force stop button next to the unistall option in application manager. Basically you call the Service directly. Here is My Code:

public class TestService extends Service {

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
        Toast.makeText(this, "Ejecutando Servicio ...", Toast.LENGTH_SHORT).show();
    return Service.START_NOT_STICKY;    
    }

@Override
    public void onCreate() {
      super.onCreate();
      Toast.makeText(this, "Iniciando Servicio ...", Toast.LENGTH_SHORT).show();
}

    @Override
    public void onDestroy() {
      super.onDestroy();
      Toast.makeText(this, "Deteniendo Servicio ...", Toast.LENGTH_SHORT).show();
}   

On client activity write the following code:

            Calendar cal = Calendar.getInstance();
        Intent intent = new Intent(this,TestService.class);
        PendingIntent pIntent = PendingIntent.getService(this.getApplicationContext(), 0, intent, 0);
        alarm=  (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        alarm.setRepeating(AlarmManager.RTC_WAKEUP,cal.getTimeInMillis(), 3*1000, pIntent);

And declare the service in manifest:

        <service
      android:name="TestService"
      android:icon="@drawable/ic_launcher"
      android:label="TestService"
      >
    </service>         
Igor Zelaya
  • 4,167
  • 4
  • 35
  • 52
  • Service is the way to go @Igor, i need more help with you on the service stuff making an alarm clock , i used it but seems not working well, can u help me and check my code? – Lutaaya Huzaifah Idris Nov 07 '17 at 08:42
  • This is link1 https://github.com/huxaiphaer/DiabeticsApp/blob/master/Droid/AlarmReceiver.cs link2 . https://github.com/huxaiphaer/DiabeticsApp/blob/master/Droid/AppStickyService.cs – Lutaaya Huzaifah Idris Nov 07 '17 at 08:47
  • Maybe this link can help? http://www.truiton.com/2014/09/android-service-broadcastreceiver-example/ – Igor Zelaya Nov 14 '17 at 17:19
0

That's a normal behavoiur ! The alarm will stop working when your app goes to onDestroy().

utkarsh dubey
  • 141
  • 2
  • 14
-1

Add

<receiver android:name=".AlarmReceiver" android:process=":remote" />

in manifest file. The alarm will work even if app is killed.

Jon
  • 9,156
  • 9
  • 56
  • 73
  • 8
    Welcome to StackOverflow. Please be careful when adding an answer to an old thread with several other responses, especially when one of them has been accepted. You need to explain why your answer is better than any of the existing ones. – APC Jan 01 '16 at 13:32
  • Tried this approach on Android 10, did not work for me, the receiver was still not getting called. I was killing the app by using the "Force stop" option in the Settings – VladimirVip Apr 27 '20 at 20:33
-1

Forcing your application to close is not the correct way to close an app and may give you incorrect behavior.

This question might also be of some help.

Community
  • 1
  • 1
ninjasense
  • 13,756
  • 19
  • 75
  • 92