Push Notification issue sent from BroadcastReceiver

david196david196 Member
edited January 16 in Xamarin.Android

Hello,

I'm new in the notification development and I'm stuck right now.

I have an app which have to check my API for new notifications for the logged user while the app is killed (i've kinda managed that)

Here is my service class

using Android;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Support.V4.App;
using Android.Util;
using Android.Widget;
using System;
using System.Threading;
using Xamarin.Forms;

namespace WhereAbouts
{
[Service(Exported = true, Enabled = true)]
class NotificationServiceMng : Service
{
private const string TAG = "bgservice";

    private int wakelockcount = 0;
    private System.Timers.Timer _timer = null;
    private PowerManager.WakeLock wakelock = null;

    public override IBinder OnBind(Intent intent)
    {
        return null;
    }

    public override void OnCreate()
    {
        base.OnCreate();

        PowerManager pmanager = (PowerManager)this.GetSystemService("power");
        wakelock = pmanager.NewWakeLock(WakeLockFlags.Partial, "servicewakelock");
        wakelock.SetReferenceCounted(false);

    }
    public override void OnDestroy()
    {
        base.OnDestroy();
        //SendBroadcast(new Intent(this, typeof(AlarmReceiver)));
    }

    public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
    {

        Log.Info(TAG, "OnstartCommand ");
        //SetWakeLock();

        AlarmManager manager = (AlarmManager)GetSystemService(AlarmService);
        long triggerAtTime = SystemClock.ElapsedRealtime() + (10 * 60 * 100);
        Intent alarmintent = new Intent(this, typeof(AlarmReceiver));

        PendingIntent pendingintent = PendingIntent.GetBroadcast(this, 0, alarmintent, 0);
        if (Android.OS.Build.VERSION.SdkInt >= BuildVersionCodes.M)
        {
            manager.Cancel(pendingintent);
            manager.SetAndAllowWhileIdle(AlarmType.ElapsedRealtimeWakeup, triggerAtTime, pendingintent);
            Log.Info(TAG, "Alarm SetAndAllowWhileIdle Set");

        }
        else if (Android.OS.Build.VERSION.SdkInt == BuildVersionCodes.Kitkat || Android.OS.Build.VERSION.SdkInt == BuildVersionCodes.Lollipop)
        {
            manager.Cancel(pendingintent);
            manager.SetExact(AlarmType.ElapsedRealtimeWakeup, triggerAtTime, pendingintent);
        }

        return StartCommandResult.Sticky;
    }

}

}

This is the BroadcastReceiver

[BroadcastReceiver(Enabled = true, Permission = "com.google.android.c2dm.permission.SEND")]
public class AlarmReceiver : BroadcastReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
        NotificationCheck.CheckNotifications();
        // Build the notification:
        //var notificationBuilder = new NotificationCompat.Builder(context, "TEST")
        //              .SetAutoCancel(true)                                   // Dismiss the notification from the notification area when the user clicks on it
        //              .SetContentTitle("WB TEST")                                // Set the title
        //              .SetNumber(2)                         // Display the count in the Content Info
        //              .SetSmallIcon(Resource.Drawable.WhereAboutsLogo)  // This is the icon to display
        //              .SetContentText("sper sa mearga");                              // the message to display.

        //var notificationManager = NotificationManagerCompat.From(context);
        //notificationManager.Notify(1000, notificationBuilder.Build());
        //Toast.MakeText(context, "Receiver", ToastLength.Long).Show();
        Intent i = new Intent(context, typeof(NotificationServiceMng));
        i.AddFlags(ActivityFlags.NewTask);
        context.StartService(i);
    }
}

This is my MainActivity

   protected override void OnCreate(Bundle savedInstanceState)
    {
        TabLayoutResource = Resource.Layout.Tabbar;
        ToolbarResource = Resource.Layout.Toolbar;
        base.OnCreate(savedInstanceState);

        global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
        LoadApplication(new App());
        CreateNotificationChannel();
        StartService(new Android.Content.Intent(this, typeof(NotificationServiceMng)));
    }
    void CreateNotificationChannel()
    {
        if (Build.VERSION.SdkInt < BuildVersionCodes.O)
        {
            return;
        }

        var channel = new NotificationChannel("TEST", "test", NotificationImportance.Default)
        {
            Description = "TEST AREA"
        };

        var notificationManager = (NotificationManager)GetSystemService(NotificationService);
        notificationManager.CreateNotificationChannel(channel);
    }
}

And I also have implemented AndroidNotificationManager,INotificationManager and NotificationEventArgs.

Ok, if i run the app the notification with the code from above the notification wont come even when the app is running.
If I use in BroadCastReceiver this code to create a notification
// Build the notification:
//var notificationBuilder = new NotificationCompat.Builder(context, "TEST")
// .SetAutoCancel(true) // Dismiss the notification from the notification area when the user clicks on it
// .SetContentTitle("WB TEST") // Set the title
// .SetNumber(2) // Display the count in the Content Info
// .SetSmallIcon(Resource.Drawable.WhereAboutsLogo) // This is the icon to display
// .SetContentText("sper sa mearga"); // the message to display.

        //var notificationManager = NotificationManagerCompat.From(context);
        //notificationManager.Notify(1000, notificationBuilder.Build());

It's working even if i kill the app, and i receive the notification.

Can anyone help me? I really need to use my method from NotificationCheck class which retrieve the data from API.

Answers

  • jezhjezh Member, Xamarin Team Xamurai
    edited 1:21PM

    What do you mean by words:·I have an app which have to check my API for new notifications for the logged user while the app is killed? Could you please post more details about it?

    Besides, if it is convenient for you, could you please post a basic demo so that we can help you better?

  • david196david196 Member

    Hei, thanks for your answer.
    So, after I run the app and login, my service will start and set an alarm for lets say 1min which calls the AlarmReceiver,inside AlarmReceiver I call a method which gets all the notifications which were not sent to the mobile calling my API.

    While the app is running there is no problem, the receiver works and send the notifications every minute, after the application is killed the service and the receiver are still working but without sending the notifications and returning a tost with the message "Error" as you can see in the code below.

    Also, if I throw some dummy data in my foreach the notifications keep working after the app is killed.

    I'm aware that the receiver might not call the method(don't know for sure because i can't use the debuger).

    public class AlarmReceiver : BroadcastReceiver
    {
        private int count = 0;
        public override async void OnReceive(Context context, Intent intent)
        {
    
            Toast.MakeText(context, "Receiver", ToastLength.Long).Show();
    
            try {
                List<WhereAbouts.Models.Notification> notif = await NotificationCheck.GetNotificationsAsync();
                foreach (WhereAbouts.Models.Notification item in notif)
                {
                    count++;
                    var notificationBuilder = new NotificationCompat.Builder(context, "TEST")
                   .SetAutoCancel(true)                                   
                   .SetContentTitle("WhereAbouts")                                // Set the title
                   .SetNumber(count)                         // Display the count in the Content Info
                   .SetSmallIcon(Resource.Drawable.WhereAboutsLogo)  // This is the icon to display
                   .SetContentText($"{item.NotificationText}!");                        // the message to display.
                    var notificationManager = NotificationManagerCompat.From(context);
                    notificationManager.Notify(count, notificationBuilder.Build());
    
                }
            }
            catch(Exception e)
            {
                Toast.MakeText(context, "Error" , ToastLength.Long).Show();
            }
    
            Intent i = new Intent(context, typeof(NotificationServiceMng));
            i.AddFlags(ActivityFlags.NewTask);
            context.StartService(i);
        }
    }
    

    --notice that this is an updated AlarmReceiver

Sign In or Register to comment.