Como usar as notifications por push nos formulários Xamarin

Eu sou um aplicativo usando Xamarin.Forms segmentação IOS, Android e WP 8.

Preciso do recurso de notifications push no meu aplicativo.

Eu vi os demos pushsharp e parece promissor. Mas todos os códigos que vi foram feitos separadamente para cada plataforma.

Eu gostaria que fosse feito no projeto Xamarin.Forms, em algum lugar no App.cs, para que eu não precise repetir o código para registrar o dispositivo e manipular como as notifications por push devem ser processadas.

Qualquer ajuda seria muito apreciada. Códigos de amostra ou referências de tutorial são bem-vindos.

Edit : Eu implementei com base na resposta do Idot. Aqui está o link para minha resposta.

Acabei de implementar a notificação por push há alguns dias e compartilharei minha solução aqui (com base no PushSharp )

Guia passo a passo:

1) Em seu projeto compartilhado, crie uma interface chamada IPushNotificationRegister

 public interface IPushNotificationRegister { void ExtractTokenAndRegister(); } 

Essa interface é usada para buscar o token de envio e enviá-lo ao servidor. este token é único por dispositivo.

2) Em seu projeto compartilhado, você deve invocar ExtractTokenAndRegister (usando seu IOC favorito, eu o chamei logo após o login).

Implementação do Android:

3) Adicionar receptores para ouvir events recebidos pelo serviço do Google GCM:

a)

 [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 = "@PACKAGE_NAME@.permission.C2D_MESSAGE")] [assembly: UsesPermission(Name = "android.permission.WAKE_LOCK")] [assembly: UsesPermission(Name = "@PACKAGE_NAME@.permission.C2D_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[] { "@PACKAGE_NAME@" })] [IntentFilter(new string[] { "com.google.android.c2dm.intent.REGISTRATION" }, Categories = new string[] { "@PACKAGE_NAME@" })] [IntentFilter(new string[] { "com.google.android.gcm.intent.RETRY" }, Categories = new string[] { "@PACKAGE_NAME@" })] [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) Adicionar serviço de intenção para processar a notificação

 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(); _notificationService = Resolver.Resolve(); _pushNotificationRegister = Resolver.Resolve(); } 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) Implementar a Interface IPushNotificationRegister :

 using Android.App; using Android.Content; using Consumer.Mobile.Services; using Consumer.Mobile.Services.PushNotification; [assembly: Permission(Name = "@PACKAGE_NAME@.permission.C2D_MESSAGE")] [assembly: UsesPermission(Name = "@PACKAGE_NAME@.permission.C2D_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); } } } 

Implementação iOS:

4) Em seu AppDelegate , adicione o seguinte método:

a)

 public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken) { var deviceTokenString = deviceToken.ToString().Replace("<","").Replace(">", "").Replace(" ", ""); var notificationService = Resolver.Resolve(); var pushNotificationRegister = Resolver.Resolve(); if (pushNotificationRegister.ShouldSendToken(deviceTokenString)) { var uid = UIDevice.CurrentDevice.IdentifierForVendor.AsString(); notificationService.AddPushToken(deviceTokenString, DeviceUtils.GetDeviceType(), uid); } } 

b) Implementar 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); } } } 

Em relação ao WP, não o implementei.

Se você precisar do código no lado do servidor usando PushSharp, me avise.

Você pode verificar as amostras de clientes. Baseei minha solução aqui

Eu tenho sido sugerido para usar o seguinte plugin por xamarin suporte e formulários.

Este plugin funciona bem

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

Vai atualizar a resposta assim que eu começar a trabalhar.

ATUALIZAÇÃO:

Recebi notifications push para iOS e Android.

Eu usei o Google Cloud Messaging Client , um excelente componente para Android, e não precisei escrever muito do código, conforme mencionado nesta resposta .

Minha implementação do iOS foi semelhante a isso , não é necessário muito código.

E para empurrar as notifications do servidor eu usei o pacote nuget do PushSharp .

Eu não implementei no WP, pois isso não era necessário no meu projeto.

Esta ajuda de Xamarin em notifications push vale a pena ler se você estiver indo para implementar notifications push.

Atualização (junho de 2018) – Use o seguinte plugin para o FCM no iOS e Android, ti suporta Xamarin.Forms – FirebasePushNotificationPlugin

No Xamarin Forms, você também pode usar um SDK de notifications como o Donky (que é o equivalente europeu do American Urban Airship); você pode facilmente fazer um projeto de notifications escalável em um único dia. Eu construí duas vezes clones do WhatsApp em menos de 35 minutos cada vez usando este SDK. Veja http://docs.mobiledonky.com

Isso não é possível em Xamarin.Forms puro, mas é relativamente trivial implementar uma solução na qual eles possam ser manipulados no App.cs (embora isso exija implementações específicas da plataforma).

Dê uma olhada na implementação do IXForms dentro do projeto Xamarin.Forms.Labs, onde as notifications são canalizadas de volta para o projeto Forms:

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

e mais especificamente:

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

Recentemente, há uma postagem no blog sobre a implementação de notifications por push no Xamarin Forms (bem, em cada plataforma individual, porque não há nenhuma implementação baseada em formulários) usando os Serviços Móveis do Azure.

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

Você pode olhar para o componente Appboy, que tem suporte para este fora da checkbox. https://components.xamarin.com/view/appboy-sdk-bindings

Como outros já disseram, você não pode fazer genericamente sem alguns componentes específicos da plataforma.