wake-up-neo.com

So verwenden Sie Push-Benachrichtigungen in Xamarin-Formularen

Ich habe eine App mit Xamarin.Forms für IOS, Android und WP 8. 

Ich brauche die Push-Benachrichtigungsfunktion in meiner App. 

Ich habe die pushsharp-Demos gesehen und es scheint vielversprechend. Alle Codes, die ich gesehen habe, werden jedoch für jede Plattform separat erstellt. 

Ich möchte, dass es im Xamarin.Forms-Projekt irgendwo in App.cs gemacht wird, sodass ich den Code für die Registrierung des Geräts nicht wiederholen muss und wie Push-Benachrichtigungen verarbeitet werden sollen. 

Jede Hilfe wäre sehr dankbar. Beispielcodes oder Referenzhinweise für das Lernprogramm sind willkommen. 

Edit: Ich habe es basierend auf Idots answer implementiert. Hier ist der link für meine Antwort. 

45

Ich habe vor ein paar Tagen die Push-Benachrichtigung implementiert, und ich werde meine Lösung hier veröffentlichen (basierend auf PushSharp )

Schritt für Schritt Anleitung:

1) Erstellen Sie in Ihrem freigegebenen Projekt eine Schnittstelle mit dem Namen IPushNotificationRegister

public interface IPushNotificationRegister
{
    void ExtractTokenAndRegister();
}

Diese Schnittstelle wird zum Abrufen des Push-Tokens verwendet und dann an den Server gesendet. Dieses Token ist pro Gerät eindeutig.

2) In Ihrem freigegebenen Projekt sollten Sie ExtractTokenAndRegister aufrufen (mit Ihrem bevorzugten IOC habe ich es gleich nach dem Login aufgerufen).

Android-Implementierung:

3) Fügen Sie Empfänger hinzu, um Ereignisse zu hören, die vom Google GCM-Dienst empfangen wurden:

ein)

[BroadcastReceiver]
[IntentFilter(new[] { Intent.ActionBootCompleted })]
public class GCMBootReceiver : BroadcastReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
        MyIntentService.RunIntentInService(context, intent);
        SetResult(Result.Ok, null, null);
    }
}

b) 

[Assembly: Permission(Name = "@[email protected]_MESSAGE")]
[Assembly: UsesPermission(Name = "Android.permission.WAKE_LOCK")]
[Assembly: UsesPermission(Name = "@[email protected]_MESSAGE")]
[Assembly: UsesPermission(Name = "com.google.Android.c2dm.permission.RECEIVE")]
[Assembly: UsesPermission(Name = "Android.permission.GET_ACCOUNTS")]
[Assembly: UsesPermission(Name = "Android.permission.INTERNET")]

namespace Consumer.Mobile.Droid.PushNotification
{
    [BroadcastReceiver(Permission = "com.google.Android.c2dm.permission.SEND")]
    [IntentFilter(new string[] { "com.google.Android.c2dm.intent.RECEIVE" }, Categories = new string[] { "@[email protected]" })]
    [IntentFilter(new string[] { "com.google.Android.c2dm.intent.REGISTRATION" }, Categories = new string[] { "@[email protected]" })]
    [IntentFilter(new string[] { "com.google.Android.gcm.intent.RETRY" }, Categories = new string[] { "@[email protected]" })]
    [IntentFilter (new[]{ Intent.ActionBootCompleted }, Categories = new[]{ Intent.CategoryDefault })]
    public class GCMBroadcastReceiver : BroadcastReceiver
    {
        public override void OnReceive(Context context, Intent intent)
        {
            MyIntentService.RunIntentInService(context, intent);
            SetResult(Result.Ok, null, null);
        }
    }
}

c) Fügen Sie den Intent-Dienst hinzu, um die Benachrichtigung zu verarbeiten 

using Android.App;
using Android.Content;
using Android.Graphics;
using Android.Media;
using Android.OS;
using Android.Support.V4.App;
using Consumer.Mobile.Infra;
using Consumer.Mobile.Services.PushNotification;
using Java.Lang;
using XLabs.Ioc;
using TaskStackBuilder = Android.Support.V4.App.TaskStackBuilder;

namespace Consumer.Mobile.Droid.PushNotification
{
    [Service]
    public class MyIntentService : IntentService
    {
        private readonly ILogger _logger;
        private readonly IPushNotificationService _notificationService;
        private readonly IPushNotificationRegister _pushNotificationRegister;

        public MyIntentService()
        {
            _logger = Resolver.Resolve<ILogger>();
            _notificationService = Resolver.Resolve<IPushNotificationService>();
            _pushNotificationRegister = Resolver.Resolve<IPushNotificationRegister>();
        }

        static PowerManager.WakeLock _sWakeLock;
        static readonly object Lock = new object();


        public static void RunIntentInService(Context context, Intent intent)
        {
            lock (Lock)
            {
                if (_sWakeLock == null)
                {
                    // This is called from BroadcastReceiver, there is no init.
                    var pm = PowerManager.FromContext(context);
                    _sWakeLock = pm.NewWakeLock(
                    WakeLockFlags.Partial, "My WakeLock Tag");
                }
            }

            _sWakeLock.Acquire();
            intent.SetClass(context, typeof(MyIntentService));
            context.StartService(intent);
        }

        protected override void OnHandleIntent(Intent intent)
        {
            try
            {
                Context context = this.ApplicationContext;
                string action = intent.Action;

                if (action.Equals("com.google.Android.c2dm.intent.REGISTRATION"))
                {
                    HandleRegistration(context, intent);
                }
                else if (action.Equals("com.google.Android.c2dm.intent.RECEIVE"))
                {
                    HandleMessage(context, intent);
                }
            }
            finally
            {
                lock (Lock)
                {
                    //Sanity check for null as this is a public method
                    if (_sWakeLock != null)
                        _sWakeLock.Release();
                }
            }
        }

        private void HandleMessage(Context context, Intent intent)
        {

            Intent resultIntent = new Intent(this, typeof(MainActivity));


            TaskStackBuilder stackBuilder = TaskStackBuilder.Create(this);

            var c = Class.FromType(typeof(MainActivity));
            stackBuilder.AddParentStack(c);
            stackBuilder.AddNextIntent(resultIntent);

            string alert = intent.GetStringExtra("Alert");
            int number = intent.GetIntExtra("Badge", 0);

            var imageUrl = intent.GetStringExtra("ImageUrl");
            var title = intent.GetStringExtra("Title");

            Bitmap bitmap = GetBitmap(imageUrl);

            PendingIntent resultPendingIntent = stackBuilder.GetPendingIntent(0, (int)PendingIntentFlags.UpdateCurrent);

            NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
                .SetAutoCancel(true) // dismiss the notification from the notification area when the user clicks on it
                .SetContentIntent(resultPendingIntent) // start up this activity when the user clicks the intent.
                .SetContentTitle(title) // Set the title
                .SetNumber(number) // Display the count in the Content Info
                .SetSmallIcon(Resource.Drawable.Icon) // This is the icon to display
                .SetLargeIcon(bitmap)
                .SetSound(RingtoneManager.GetDefaultUri(RingtoneType.Notification))
                .SetContentText(alert); // the message to display.

            // Build the notification:
            Notification notification = builder.Build();

            // Get the notification manager:
            NotificationManager notificationManager =
                GetSystemService(Context.NotificationService) as NotificationManager;

            // Publish the notification:
            const int notificationId = 0;
            notificationManager.Notify(notificationId, notification);
        }

        private void HandleRegistration(Context context, Intent intent)
        {
            var token = intent.GetStringExtra("registration_id");
            _logger.Info(this.Class.SimpleName, "Received Token : " + token);

            if (_pushNotificationRegister.ShouldSendToken(token))
            {
                var uid = Android.Provider.Settings.Secure.GetString(MainActivity.Context.ContentResolver, Android.Provider.Settings.Secure.AndroidId);
                _notificationService.AddPushToken(token, DeviceUtils.GetDeviceType(), uid);
            }
        }


        private Bitmap GetBitmap(string url)
        {

            try
            {
                System.Net.WebRequest request =
                    System.Net.WebRequest.Create(url);
                System.Net.WebResponse response = request.GetResponse();
                System.IO.Stream responseStream =
                    response.GetResponseStream();
                return BitmapFactory.DecodeStream(responseStream);


            }
            catch (System.Net.WebException)
            {
                return null;
            }

        }

    }
}

d) Implementieren Sie die Schnittstelle IPushNotificationRegister:

using Android.App;
using Android.Content;
using Consumer.Mobile.Services;
using Consumer.Mobile.Services.PushNotification;
[Assembly: Permission(Name = "@[email protected]_MESSAGE")]
[Assembly: UsesPermission(Name = "@[email protected]_MESSAGE")]

// Gives the app permission to register and receive messages.
[Assembly: UsesPermission(Name = "com.google.Android.c2dm.permission.RECEIVE")]

// Needed to keep the processor from sleeping when a message arrives
[Assembly: UsesPermission(Name = "Android.permission.WAKE_LOCK")]
[Assembly: UsesPermission(Name = "Android.permission.RECEIVE_BOOT_COMPLETED")]
namespace Consumer.Mobile.Droid.PushNotification
{
    public class PushNotificationRegister : IPushNotificationRegister
    {          
        public override void ExtractTokenAndRegister()
        {
            string senders = AndroidConfig.GCMSenderId;
            Intent intent = new Intent("com.google.Android.c2dm.intent.REGISTER");
            intent.SetPackage("com.google.Android.gsf");
            intent.PutExtra("app", PendingIntent.GetBroadcast(MainActivity.Context, 0, new Intent(), 0));
            intent.PutExtra("sender", senders);
            MainActivity.Context.StartService(intent);
        }


    }
}

iOS-Implementierung:

4) Fügen Sie in Ihrer AppDelegate die folgende Methode hinzu:

ein) 

public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
{
    var deviceTokenString = deviceToken.ToString().Replace("<","").Replace(">", "").Replace(" ", "");
    var notificationService = Resolver.Resolve<IPushNotificationService>();
    var pushNotificationRegister = Resolver.Resolve<IPushNotificationRegister>();

    if (pushNotificationRegister.ShouldSendToken(deviceTokenString))
    {
        var uid = UIDevice.CurrentDevice.IdentifierForVendor.AsString();
        notificationService.AddPushToken(deviceTokenString, DeviceUtils.GetDeviceType(), uid);
    }
}

b) Implementiere IPushNotificationRegister:

using Consumer.Mobile.Services;
using Consumer.Mobile.Services.PushNotification;
using UIKit;

namespace Consumer.Mobile.iOS.PushNotification
{
    public class iOSPushNotificationRegister : IPushNotificationRegister
    {
        public override void ExtractTokenAndRegister()
        {
            const UIRemoteNotificationType notificationTypes = UIRemoteNotificationType.Alert | UIRemoteNotificationType.Badge | UIRemoteNotificationType.Sound;
            UIApplication.SharedApplication.RegisterForRemoteNotificationTypes(notificationTypes);
        }
    }
}

In Bezug auf WP habe ich es nicht implementiert.

Wenn Sie den Code auf der Serverseite mit PushSharp benötigen, lassen Sie es mich wissen.

Sie können die Client-Muster überprüfen, auf denen meine Lösung basiert hier

48
IdoT

Ich wurde vorgeschlagen, das folgende Plugin von Xamarin-Support und -Formulare zu verwenden. 

Dieses Plugin funktioniert gut

https://github.com/rdelrosario/xamarin-plugins/tree/master/PushNotification

Aktualisiere die Antwort, sobald ich sie zum Laufen gebracht habe. 

UPDATE:

Ich habe Push-Benachrichtigungen für iOS und Android.

Ich habe Google Cloud Messaging Client verwendet, eine hervorragende Komponente für Android, und musste nicht viel Code schreiben, wie in diese Antwort erwähnt. 

Meine iOS-Implementierung war ähnlich wie this , es ist nicht viel Code erforderlich. 

Und für das Senden der Benachrichtigungen vom Server habe ich das Nuget-Paket von PushSharp verwendet. 

Ich habe es nicht in WP implementiert, da dies in meinem Projekt nicht erforderlich war.

Diese Xamarin-Hilfe zu Push-Benachrichtigungen ist lesenswert, wenn Sie Push-Benachrichtigungen implementieren möchten. 

Update (Juni 2018) - Verwenden Sie das folgende Plugin für FCM unter iOS und Android. Ti unterstützt Xamarin.Forms - FirebasePushNotificationPlugin

16

In Xamarin Forms können Sie auch ein Benachrichtigungs-SDK wie Donky (das europäische Äquivalent zum amerikanischen urbanen Luftschiff) verwenden. Sie können problemlos ein skalierbares Benachrichtigungsprojekt an einem einzigen Tag erstellen. Mit diesem SDK habe ich zweimal WhatsApp-Clone-Shells in weniger als 35 Minuten erstellt. Siehe http://docs.mobiledonky.com

2
Xamtastic

Sie können sich die Appboy-Komponente ansehen, die diese Unterstützung von Anfang an unterstützt. https://components.xamarin.com/view/appboy-sdk-bindings

Wie andere schon gesagt haben, können Sie nicht generell ohne plattformspezifische Komponenten auskommen.

1
Brian Wheeler

Vor kurzem wurde hier ein Blogbeitrag zur Implementierung von Push-Benachrichtigungen für Xamarin-Formulare (insbesondere für jede einzelne Plattform, da keine formularbasierte Implementierung vorhanden ist) mithilfe von Azure Mobile Services bereitgestellt.

http://www.xamarinhelp.com/Push-notifications/

1
Adam Pedley

Dies ist in reinen Xamarin.Forms nicht möglich, aber es ist relativ einfach, eine Lösung zu implementieren, mit der sie in App.cs behandelt werden können (obwohl dies plattformspezifische Implementierungen erfordert). 

Schauen Sie sich die IXForms-Implementierung im Xamarin.Forms.Labs-Projekt an, in der die Benachrichtigungen an das Forms-Projekt zurückgeleitet werden:

https://github.com/XLabs/Xamarin-Forms-Labs

und genauer:

https://github.com/XLabs/Xamarin-Forms-Labs/tree/master/src/Platform/XLabs.Platform/Mvvm

0
JordanMazurke