rdelrosario / xamarin-plugins

Cross platform Xamarin & Windows plugins for PCLs
MIT License
179 stars 161 forks source link

Android: Receive Push notification when App is closed (not backgrounded but closed at all) #27

Closed aunanue closed 8 years ago

aunanue commented 8 years ago

Hi, I followed all the instructions for using the plugin. I'm able to receive the notifications while the App is running but when I close the App, the notifications are not received. I have started properly the service: StartPushService as described in the documentation, in fact when the App is running I see that the service is also running (settings->Apps administration->Running...) but when the App is closed the service is removed also from the list of running Apps.

Is is possible to receive Push notifications on Android when the App is closed using this Plugin? I checked that in order to receive, the Service needs to derive from WakefulBroadcastReceiver in order to receive then the App is closed. Check: http://forums.xamarin.com/discussion/29804/push-notifications-on-closed-app-with-forms

Cheers Ariel

rdelrosario commented 8 years ago

It does work when close. but you can not force quit. Did you quit the app while debugging?

Stop debugging Reopen, the app then close by swiping.

shaungrech commented 8 years ago

Hi,

When trying to make this call in the Android 'Application':

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

    AppContext = this.ApplicationContext;

     //TODO: Initialize CrossPushNotification Plugin
     //TODO: Replace string parameter with your Android SENDER ID
     //TODO: Specify the listener class implementing IPushNotificationListener interface in the Initialize generic
     CrossPushNotification.Initialize<CrossPushNotificationListener>("<ANDROID SENDER ID>");

     //This service will keep your app receiving push even when closed.             
     StartPush

I am getting a Forms not initialized exception as this code is executed before the MainActivity code which initializes code using:

global::Xamarin.Forms.Forms.Init (this, bundle);

Are you sure the code is correct?

Thanks Shaun

rdelrosario commented 8 years ago

Did you followed this instructions: http://web.archive.org/web/20150524090527/http://lemoncode.net/2015/04/17/adding-push-notifications-to-your-xamarin-forms-application-part-1/

shaungrech commented 8 years ago

Hi,

Yes everything is the same. The problem in the code is that the 'CrossPushNotificationListener' is in the Xamarin Forms projects. When initializing it in the Android Application class, the forms init has not been called yet (this is called in the Main Activity) so Xamarin throws an exception saying that Xamarin Forms must be initialized before calling CrossPushNotificationListener.

The reason forms must be initialized is because CrossPushNotificationListener used 'Dependency' which is part of the forms namespace.

I even downloaded your sample code to try again.

Thanks Shaun

shaungrech commented 8 years ago

To clarify:

IAzureNotificationHubService _azureNotificationHubService;

public CrossPushNotificationListener () { _azureNotificationHubService = DependencyService.Get (); }

This is found in the CrossPushNotificationListener class which is in the PCL (Shared).

Now if in the Android Application class I initialize the CrossPushNotificationListener class as such: CrossPushNotification.Initialize(Keys.GOOGLE_APIs_ID);

the constructor is called. The constructor uses Forms Dependency which has not been initialized yet because this is initialized in the Main Activity.

Which alternative approach would you recommend?

Thanks again Shaun

rdelrosario commented 8 years ago

Will suggest using an interface instead of a depencyservice, because when app closed for example xamarin forms wont be initialized, so the best option here is to hace the code in the push listener no forms dependant.

Sent from my iPhone

On 5 ene 2016, at 3:36 p.m., Shaun Grech notifications@github.com wrote:

To clarify:

IAzureNotificationHubService _azureNotificationHubService;

public CrossPushNotificationListener () { _azureNotificationHubService = DependencyService.Get (); }

This is found in the CrossPushNotificationListener class which is in the PCL (Shared).

Now if in the Android Application class I initialize the CrossPushNotificationListener class as such: CrossPushNotification.Initialize(Keys.GOOGLE_APIs_ID);

the constructor is called. The constructor uses Forms Dependency which has not been initialized yet because this is initialized in the Main Activity.

Which alternative approach would you recommend?

Thanks again Shaun

— Reply to this email directly or view it on GitHub.

shaungrech commented 8 years ago

Hi what do you mean using an interface instead of the dependency service?

aunanue commented 8 years ago

@rdelrosario Thanks for the support, the original issue I wrote is working as expected. As you described when running the App in release mode (not debugging) the service keeps running the the notifications are displayed even when the App is not running. Thanks for your support

shaungrech commented 8 years ago

@aunanue are you using Xamarin Forms? Can you please share the OnCreate method in your service? Thanks

aunanue commented 8 years ago

Yes, I’m using XF. I followed the tutorial and I make it work.

http://web.archive.org/web/20150524090527/http://lemoncode.net/2015/04/17/adding-push-notifications-to-your-xamarin-forms-application-part-1/ http://web.archive.org/web/20150524090527/http:/lemoncode.net/2015/04/17/adding-push-notifications-to-your-xamarin-forms-application-part-1/

Anyway this is my MainApplication that creates the service for receiving push notification when the App is closed.

Cheers

De: Shaun Grech [mailto:notifications@github.com] Enviado el: miércoles, 06 de enero de 2016 11:48 p.m. Para: rdelrosario/xamarin-plugins xamarin-plugins@noreply.github.com CC: aunanue aunanue@solidmation.com Asunto: Re: [xamarin-plugins] Android: Receive Push notification when App is closed (not backgrounded but closed at all) (#27)

@aunanue https://github.com/aunanue are you using Xamarin Forms? Can you please share the OnCreate method in your service? Thanks

— Reply to this email directly or view it on GitHub https://github.com/rdelrosario/xamarin-plugins/issues/27#issuecomment-169532281 . https://github.com/notifications/beacon/AL0wIaHl2qiWoAntp66Avh4i4l1A3wuwks5pXclVgaJpZM4G8BhB.gif

using System; using Android.App; using Android.OS; using Android.Runtime; using Plugin.CurrentActivity; using Android.Content; using PushNotification.Plugin;

namespace App.Droid { //You can specify additional application information in this attribute [Application] public class MainApplication : Application, Application.IActivityLifecycleCallbacks { public static Context AppContext;

    public MainApplication(IntPtr handle, JniHandleOwnership transer)
      :base(handle, transer)
    {
    }

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

        AppContext = this.ApplicationContext;

        RegisterActivityLifecycleCallbacks(this);
        //A great place to initialize Xamarin.Insights and Dependency Services!

        //This service will keep your app receiving push even when closed.
        CrossPushNotification.Initialize<CrossPushNotificationListener>("YOUR ID");
        StartPushService();
    }

    public override void OnTerminate()
    {
        base.OnTerminate();
        UnregisterActivityLifecycleCallbacks(this);
    }

    public void OnActivityCreated(Activity activity, Bundle savedInstanceState)
    {
        CrossCurrentActivity.Current.Activity = activity;
    }

    public void OnActivityDestroyed(Activity activity)
    {
    }

    public void OnActivityPaused(Activity activity)
    {
    }

    public void OnActivityResumed(Activity activity)
    {
        CrossCurrentActivity.Current.Activity = activity;
    }

    public void OnActivitySaveInstanceState(Activity activity, Bundle outState)
    {
    }

    public void OnActivityStarted(Activity activity)
    {
        CrossCurrentActivity.Current.Activity = activity;
    }

    public void OnActivityStopped(Activity activity)
    {
    }

    public static void StartPushService()
    {
        AppContext.StartService(new Intent(AppContext, typeof(PushNotificationService)));
        if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Kitkat)
        {
            PendingIntent pintent = PendingIntent.GetService(AppContext, 0, new Intent(AppContext, typeof(PushNotificationService)), 0);
            AlarmManager alarm = (AlarmManager)AppContext.GetSystemService(Context.AlarmService);
            alarm.Cancel(pintent);
        }
    }

    public static void StopPushService()
    {
        AppContext.StopService(new Intent(AppContext, typeof(PushNotificationService)));
        if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Kitkat)
        {
            PendingIntent pintent = PendingIntent.GetService(AppContext, 0, new Intent(AppContext, typeof(PushNotificationService)), 0);
            AlarmManager alarm = (AlarmManager)AppContext.GetSystemService(Context.AlarmService);
            alarm.Cancel(pintent);
        }
    }
}

}

shaungrech commented 8 years ago

I have exactly the same, but this line: CrossPushNotification.Initialize("YOUR ID");

Initializes CrossPushNotificationListener which is in the shared library which makes use of Dependency. Dependency is a Xamarin Forms library which is not initialized at this point because the MainApplication : Application, Application.IActivityLifecycleCallbacks is called before the MainActivity class which contains the following line: global::Xamarin.Forms.Forms.Init(this, bundle); to initialize forms.

That is my problem.

Thanks anyway for your help though.

Kind regards, Shaun

rdelrosario commented 8 years ago

Hi

Just dont use depencyservice or any forms dependant api on the listener. Use other dependencyinjection alternatives, because forms is not initialized when app is closed. Forms is ui dependant, there is no ui when the app is closed and so you will get crashes if using xamarin forms on classes that are called with intentservices or broadcast receivers when droid app is not open.

Sent from my iPhone

On 7 ene 2016, at 11:56 a.m., Shaun Grech notifications@github.com wrote:

I have exactly the same, but this line: CrossPushNotification.Initialize("YOUR ID");

Initializes CrossPushNotificationListener which is in the shared library which makes use of Dependency. Dependency is a Xamarin Forms library which is not initialized at this point because the MainApplication : Application, Application.IActivityLifecycleCallbacks is called before the MainActivity class which contains the following line: global::Xamarin.Forms.Forms.Init(this, bundle); to initialize forms.

That is my problem.

Thanks anyway for your help though.

Kind regards, Shaun

— Reply to this email directly or view it on GitHub.

shaungrech commented 8 years ago

Hi Rosario,

Thanks for your reply. I will try doing it otherwise but in your example you say that it should work by doing:

IAzureNotificationHubService _azureNotificationHubService;

public CrossPushNotificationListener () { _azureNotificationHubService = DependencyService.Get (); }

https://lemoncoders.wordpress.com/tag/push-notification/

I will try the same example with a different Dependency Injection service.

Thanks again Shaun

rdelrosario commented 8 years ago

You are right but that sample just works foreground should get the same issue you are getting if app closes.

When using dependency injection just make sure to register the instance in the main application app in the android project, no in the main activity because the main application is instantiated when the app is closed but main activity no.

Sent from my iPhone

On 7 ene 2016, at 2:17 p.m., Shaun Grech notifications@github.com wrote:

Hi Rosario,

Thanks for your reply. I will try doing it otherwise but in your example you say that it should work by doing:

IAzureNotificationHubService _azureNotificationHubService;

public CrossPushNotificationListener () { _azureNotificationHubService = DependencyService.Get (); }

https://lemoncoders.wordpress.com/tag/push-notification/

I will try the same example with a different Dependency Injection service.

Thanks again Shaun

— Reply to this email directly or view it on GitHub.