1

So, I've been trying to achieve that for at least five hours today and I've tried literally ANY solution found anywhere.

I'm programming a little clock app, using AlarmManager to make the app ring. It works fine when my app is open or minimized. I'm trying to make it work when the app is closed, and that's the problem. So, there is the piece of code that sets the AlarmManager :

    AlarmManager am = (AlarmManager) ctxt.getSystemService(Context.ALARM_SERVICE);
    Intent intent = new Intent(ctxt, AlarmService.class);
    PendingIntent pen = PendingIntent.getBroadcast(ctxt, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    am.setExact(AlarmManager.RTC_WAKEUP, nextRing.getTime(), pen);

(Here, ctxt is the context, I've tried both getApplicationContext() and getBaseContext() and nextRing.getTime() is a long that represents the date)

Then, I have my AlarmService class (wich used to be a service, which explain the name, but is now a BroadcastReceiver and I just don't want to rename it now)

public class AlarmService extends BroadcastReceiver {

  @Override
  public void onReceive(Context context, Intent intent) {

    /*Intent cust = new Intent(context, CustomIntent.class);
    context.startService(cust);*/
    Bundle extras = intent.getExtras();
    Intent newIntent = new Intent(context, AlarmActivity.class);
    newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    newIntent.putExtra("AlarmName", extras.getString("AlarmName"));
    context.startActivity(newIntent);
  }

}

So this is the try with only the BroadcastReceiver, wich doesn't work obviously, so I tried to add a IntentService (commented out code at the top) which has the following code

public class CustomIntent extends IntentService {
  public CustomIntent() {
    super("CustomIntent");
  }

  @Override
  protected void onHandleIntent(Intent intent) {
    Intent newIntent = new Intent(getBaseContext(), AlarmActivity.class);
    newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    getApplication().startActivity(newIntent);
  }
}

... and that's not working either ! Finally, here's the manifest I use :

<application>
[Here goes stuff that have nothing to do with my bug]
    <receiver android:name=".custom_classes.AlarmService"/>
    <service
      android:name="com.group9.abclock.custom_classes.CustomIntent"
      android:enabled="true" >
      <intent-filter>
        <action android:name="com.group9.abclock.custom_classes.CustomIntent" />
      </intent-filter>
    </service>
  </application>

Sorry for the (very) long post but I tough I should explain anything I tried. Thanks in advance if you can help !

1 Answers1

1

If your application is closed, you can't trigger a BroadcastReceiver because it's not registered, and you can't use Context methods because there is no Context.

If you want to execute tasks while the application is closed, you have to create another project with a Service, and start it with your application.

A Service runs in background until someone kill it, and once it's started, the main application is not needed anymore. So the ring functionality have to be implemented in this service.

Just remember that the AlarmManager.setExact, is not that exact from API 23, due to Doze Mode.

  • So, I just tried to fire it with PendingIntent.getService() and using my CustomIntent (which extends IntentService, which extends Service). It still works fine when my app is running (I've found an impressing number of making that part work) but no activity when I close it... How is setExat not that exact ? Seconds are okay, but minutes not for my case (it seems pretty exact to me when it works, though) – Céline Deknop Mar 15 '17 at 23:15
  • [EDIT] : just read your link and my current lvl api is 21; although my phone's over 23. To be sure, I used setExactAndAllowWhileIdle(); wich does fire when idle but still did not fixed my bug when closed – Céline Deknop Mar 15 '17 at 23:30
  • After closing the application, did you look at running process and check if your service still running? If the package isn't there, the method cannot be called. If this is the case, the service is shutting down with the application, so you have to separate them somehow. – Marcelo Ferracin Mar 16 '17 at 12:14
  • For the setExact doubt, I already had a problem very similar as yours, the AlarmManager executes their functions according to OS tasks. If you lock your device and it goes to sleep mode, every function stop working for a while, to save battery, and from time to time the device wakes up and update background funcionalities, such as AlarmManager commands. You can read more in this answer: http://stackoverflow.com/questions/24724859/alarmmanager-setexact-with-wakefulbroadcastreceiver-sometimes-not-exact – Marcelo Ferracin Mar 16 '17 at 12:19
  • I don't see my service when the app is closed... How do I separate it ? – Céline Deknop Mar 16 '17 at 13:35
  • I did a project that I had to read data every 10 minutes, in the background, so I created 2 projects. The first one was a Service with all the functionalities. I exported that service as a .jar. After that I created an application which imports that .jar, launch the Service, and then closes itself. The service runs independently and can only be killed by the user, or rebooting the device. – Marcelo Ferracin Mar 16 '17 at 13:42
  • That sounds complicated... Any code to show to me or link to examples ? Anyway, thanks a lot for your help already ! – Céline Deknop Mar 16 '17 at 14:01
  • Actually that jar solution was a special need I had for my project, it's not really mandatory. I've been reading about it, try to stick with your code, but add this override cited in this answer http://stackoverflow.com/questions/30525784/android-keep-service-running-when-app-is-killed: @Override public int onStartCommand(Intent intent, int flags, int startId) { return START_STICKY; } – Marcelo Ferracin Mar 16 '17 at 14:18
  • I just tried that (I had to add my"activity launching" code into that onStartCommand() method in order for it to fire when app is open); but still no luck and I still don't see any service in background in my dev options... – Céline Deknop Mar 16 '17 at 14:30
  • 3
    WELL. I'm coming back with news : my code works like a charm; it does fire when app is closed, probably partially thanks to you and other persons here. I just discover that it's MY STUPID PHONE that was causing the problem. I'm using an Huawei P9 Lite (and all the persons I'm working with are using Huaweis too); and that stupid thing is killing any service started by an app with the debug flag (wich is on when you install an app trough Android Studio, which I'm obviously doing). So, anyone reading this : if you're using an Huawei, try emulating with something else (may be working already) – Céline Deknop Mar 16 '17 at 15:02
  • That's good and bad to hear, too bad that your phone are doing this, but I'm glad the code is working. – Marcelo Ferracin Mar 16 '17 at 15:26
  • 3
    This answer is just wrong. You can trigger `BroadcastReceiver` if your app is not running. An entry in the manifest is all that is required. You don't need another project, or another `Service` or anything else. It looks like OP has discovered his problem and it is unrelated to this answer. This answer will only confuse other developers who come looking for assistance. I suggest that you either delete this answer, or at least edit it so that it is clear that the answer is incorrect. – David Wasser Mar 17 '17 at 12:28
  • Thanks. I had the same problem. Emulating Google Pixel did not work. But my old physical galaxy s3 worked without problems with a BroadcastReceiver. – sampa Apr 06 '21 at 20:17