Я завершил получение тестового уведомления от консоли FCM. Теперь я пытаюсь открыть страницу при нажатии на уведомление. Любые идеи о том, как этого добиться? Я искал в Интернете, но не могу найти работающее решение. Я также могу отправить уведомление через почтальона.
Xamarin Forms: загрузить страницу содержимого при нажатии push-уведомления Android
Ответы (2)
Я обрабатываю уведомление следующим образом. Загрузка страницы обрабатывается в App.xaml.cs.
При создании():
//Background or killed mode
if (Intent.Extras != null)
{
foreach (var key in Intent.Extras.KeySet())
{
var value = Intent.Extras.GetString(key);
if (key == "webContentList")
{
if (value?.Length > 0)
{
isNotification = true;
LoadApplication(new App(domainname, value));
}
}
}
}
//Foreground mode
if (FirebaseNotificationService.webContentList.ToString() != "")
{
isNotification = true;
LoadApplication(new App(domainname, FirebaseNotificationService.webContentList.ToString()));
FirebaseNotificationService.webContentList = "";
}
//Normal loading
if (!isNotification)
{
LoadApplication(new App(domainname, string.Empty));
}
В FirebaseNotificationService:
[Service]
[IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
public class FirebaseNotificationService : FirebaseMessagingService
{
public static string webContentList = "";
public override void OnMessageReceived(RemoteMessage message)
{
base.OnMessageReceived(message);
webContentList = message.Data["webContentList"];
try
{
SendNotificatios(message.GetNotification().Body, message.GetNotification().Title);
}
catch (Exception ex)
{
Console.WriteLine("Error:>>" + ex);
}
}
public void SendNotificatios(string body, string Header)
{
if (Build.VERSION.SdkInt < BuildVersionCodes.O)
{
var intent = new Intent(this, typeof(MainActivity));
intent.AddFlags(ActivityFlags.ClearTop);
var pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.OneShot);
var notificationBuilder = new Android.App.Notification.Builder(this, Utils.CHANNEL_ID)
.SetContentTitle(Header)
.SetSmallIcon(Resource.Drawable.icon)
.SetContentText(body)
.SetAutoCancel(true)
.SetContentIntent(pendingIntent);
var notificationManager = NotificationManager.FromContext(this);
notificationManager.Notify(0, notificationBuilder.Build());
}
else
{
var intent = new Intent(this, typeof(MainActivity));
intent.AddFlags(ActivityFlags.ClearTop);
var pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.OneShot);
var notificationBuilder = new Android.App.Notification.Builder(this, Utils.CHANNEL_ID)
.SetContentTitle(Header)
.SetSmallIcon(Resource.Drawable.icon)
.SetContentText(body)
.SetAutoCancel(true)
.SetContentIntent(pendingIntent)
.SetChannelId(Utils.CHANNEL_ID);
if (Build.VERSION.SdkInt < BuildVersionCodes.O)
{
return;
}
var channel = new NotificationChannel(Utils.CHANNEL_ID, "FCM Notifications", NotificationImportance.High)
{
Description = "Firebase Cloud Messages appear in this channel"
};
var notificationManager = (NotificationManager)GetSystemService(NotificationService);
notificationManager.CreateNotificationChannel(channel);
notificationManager.Notify(0, notificationBuilder.Build());
}
}
Я не знаю, какова ваша фактическая реализация Firebase, но это может вам помочь.
Есть хороший пакет для Firebase
в Xamarin Forms, который мы используем в нашем рабочем приложении, созданном командой CrossGeeks. Он отлично работает и имеет все handlers
для ваших нужд. Это работает с iOS и Android, и вам не нужно писать специфичный для платформы код, только конфигурацию и некоторый код в AppDelegate.cs
и MainActivity.cs
.
Я написал простую службу PushNotificationService, которая обрабатывает автоматическое обновление и/или отправляет новые страницы с учетом данных push-уведомлений.
Когда приложение закрывается и пользователь нажимает на уведомление, я сохраняю данные push-уведомления, используя Akavache.
CrossFirebasePushNotification.Current.OnNotificationOpened += async (s, p) =>
{
if (App.AppBeenResumed)
{
await BlobCache.UserAccount.InsertObject("pushNotifData", p.Data);
}
else
{
await ProcessReceivedPushNotification(p.Data);
}
};
И на целевой странице приложения я проверяю, существуют ли данные push-уведомления в методе OnAppearing
страницы.
protected override void OnAppearing()
{
base.OnAppearing();
App.AppBeenResumed = false;
HandlePushNotificationIfExists();
}
private async void HandlePushNotificationIfExists()
{
IDictionary<string, object> pushNotifData;
try
{
pushNotifData = await BlobCache.UserAccount.GetObject<IDictionary<string, object>>("pushNotifData");
}
catch (KeyNotFoundException)
{
pushNotifData = null;
}
if (pushNotifData == null) return;
await BlobCache.UserAccount.InvalidateAllObjects<IDictionary<string, object>>();
await PushNotificationService.ProcessReceivedPushNotification(pushNotifData);
}
В ProcessReceivedPushNotification
вы можете делать все, что хотите... напрямую отправлять страницу или что-то еще... вызывать другую службу, которая будет выполнять работу по отправке новой страницы и некоторого бизнес-процесса.
Обратите внимание, что App.AppBeenResumed
– это статическое логическое значение, определяющее, было ли приложение запущено или возобновлено для правильной обработки процесса обработки push-уведомления (обработать его мгновенно или сохранить в кэше BLOB-объектов, чтобы обработать его позже на целевой странице). Появляется).
In MainActivity.cs
:
protected override void OnCreate(Bundle bundle)
{
...
LoadApplication(new App(true));
}
В App.cs
:
public App(bool beenResumedOrStarted)
{
...
AppBeenResumed = beenResumedOrStarted;
...
}
protected override void OnResume()
{
AppBeenResumed = false;
}
protected override void OnSleep()
{
//iOS states are not the same so always false when device is iOS
AppBeenResumed = Device.RuntimePlatform != Device.iOS;
}