Martin Pokorný
Martin Pokorný

Reputation: 49

Xamarin.Forms: Broadcast receiver not working when app is closed

I am working on an app using Xamarin.Forms and while most of it is working fine, I just can't find a way to get my Broadcast receiver work while the app isn't in RAM - and that means even when it's "gently" closed by Android, and not by user force closing it.

Broadcast receiver itself is working properly when the app is running in the foreground or when the app is in the background, but not killed yet. I've spent a few days now searching for solution, and I just couldn't succeed. I've seen some hints on Xamarin Forums and here to declare my Broadcast receiver in the service, and launch that service in MainActivity file, and while it seems like service is running, it's still not doing anything with my local notifications.

As far as my understanding goes, in Java Android development all you have to do is to declare receiver in manifest file and it will work, but that doesn't seem to be the case when using Xamarin's (otherwise awesome) technology.

I hope some of you faced this issue too and know about solution, because I'm pretty desperate. Thanks alot for your time and have a nice day!

EDIT:

Receiver is declared using Xamarin's code way, in generated Manifest it looks like this:

receiver android:name="md5d0a2bd06806e04fc29264ca7dfdf52f5.AlarmService"

And here's the BroadcastReceiver itself:

[BroadcastReceiver(Enabled=true)]
public class AlarmService : BroadcastReceiver, IAlarmService
{
    List<LocalNotification> notifications;
    public override void OnReceive (Context context, Intent intent)
    {
        PowerManager pm = (PowerManager) context.GetSystemService(Context.PowerService);
        PowerManager.WakeLock wl = pm.NewWakeLock(WakeLockFlags.Partial, "");
        wl.Acquire();

        Intent resultIntent = new Intent(context, context.GetType());
        resultIntent.PutExtra ("Notification", true);

        IList<string> values = intent.GetStringArrayListExtra ("NotificationStrings");

        new LocalNotificationService(context).Notify (values [0], values [1], values [2], values[3]);
        wl.Release();       
    }

And PendingIntent it receives is set up like this:

Intent intent = new Intent (context, typeof(AlarmService));
        intent.SetAction (notifications [requestCode].Id ?? Guid.NewGuid ().ToString ());
        intent.PutStringArrayListExtra ("NotificationStrings", new List<string>() {
            notifications [requestCode].Title,
            notifications [requestCode].Body,
            notifications [requestCode].AlertAction,
            notifications [requestCode].UserData,
            notifications [requestCode].Id
        });
AlarmManager am = (AlarmManager)context.GetSystemService(Context.AlarmService);

        PendingIntent pi = PendingIntent.GetBroadcast(context, 0, intent, 0);

        am.Set (AlarmType.RtcWakeup, (long)(Java.Lang.JavaSystem.CurrentTimeMillis () + (dateTime.Value.ToUniversalTime () - DateTime.Now.ToUniversalTime ()).TotalMilliseconds), pi);

However, even when I delete code inside OnReceive, instead of nothing happening, I get system message stating that application has stopped working, which makes me think that something must be wrong with either Context, or Intent - everything works well when app Activity is in the RAM.

Upvotes: 4

Views: 5899

Answers (2)

Martin Pokorn&#253;
Martin Pokorn&#253;

Reputation: 49

It turns out that I'm a total idiot; the issue wasn't in the Receiver nor alarm setter. I handled the wrong Context in my LocalNotificationService. I was using Forms.Context the enttire time instead of the Context passed by my receiver.

Sorry about wasting your time, guys. Thanks for help!

Upvotes: 0

IdoT
IdoT

Reputation: 2871

You need to add a permission to run in the background in the app manifest. Check out my working solution here

Upvotes: 1

Related Questions