У меня возникают проблемы с сохранением и отображением уведомления pu sh в пользовательском интерфейсе моих приложений, когда приложение извлекается из памяти или закрывается. Я все еще получаю уведомления в этом состоянии, но после открытия приложения или нажатия на уведомление, чтобы открыть приложение, сообщение не отображается. Все работает нормально, когда приложение работает или в фоновом режиме. Я следил за документацией здесь https://docs.microsoft.com/en-us/xamarin/xamarin-forms/data-cloud/azure-services/azure-notification-hub с небольшими изменениями, чтобы сохранить уведомление в файле SQLite. Наконец-то я заставил это работать для iOS, но на Android не повезло. Вот мой код.
Класс FireBaseService
[Service]
[IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
public class FirebaseService : FirebaseMessagingService
{
public override void OnMessageReceived(RemoteMessage message)
{
base.OnMessageReceived(message);
string messageBody = string.Empty;
if (message.GetNotification() != null)
{
messageBody = message.GetNotification().Body;
}
// NOTE: test messages sent via the Azure portal will be received here
else
{
messageBody = message.Data.Values.First();
}
// convert the incoming message to a local notification
SendLocalNotification(messageBody);
// send the incoming message directly to the MainPage
SendMessageToMainPage(messageBody);
}
//public override void HandleIntent(Intent intent)
//{
// base.HandleIntent(intent);
// //Create your notification
//}
public override void OnNewToken(string token)
{
// TODO: save token instance locally, or log if desired
SendRegistrationToServer(token);
}
void SendLocalNotification(string body)
{
var intent = new Intent(this, typeof(MainActivity));
intent.AddFlags(ActivityFlags.ClearTop);
intent.PutExtra("message", body);
var pendingIntent = PendingIntent.GetActivity(this, 0, intent,
PendingIntentFlags.OneShot);
var notificationBuilder = new NotificationCompat.Builder(this,
AppConstants.NotificationChannelName)
.SetContentTitle("MyMessage")
.SetSmallIcon(Resource.Drawable.pushimageicon)
.SetContentText(body)
.SetAutoCancel(true)
.SetWhen(JavaSystem.CurrentTimeMillis())
.SetShowWhen(true)
.SetStyle(new NotificationCompat.BigTextStyle())
.SetContentIntent(pendingIntent);
if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
{
notificationBuilder.SetChannelId(AppConstants.NotificationChannelName);
}
int m = (int)((new Date().Time / 1000L) % Integer.MaxValue);
var notificationManager = NotificationManager.FromContext(this);
notificationManager.Notify(m, notificationBuilder.Build());
}
void SendMessageToMainPage(string body)
{
//send to AppShell to save in SQLite
(Xamarin.Forms.Application.Current.MainPage as AppShell)?.AddMessage(body);
}
void SendRegistrationToServer(string token)
{
try
{
NotificationHub hub = new NotificationHub(AppConstants.NotificationHubName,
AppConstants.ListenConnectionString, this);
// register device with Azure Notification Hub using the token from FCM
Registration registration = hub.Register(token, AppConstants.SubscriptionTags);
// subscribe to the SubscriptionTags list with a simple template.
string pnsHandle = registration.PNSHandle;
TemplateRegistration templateReg = hub.RegisterTemplate(pnsHandle, "defaultTemplate",
AppConstants.FCMTemplateBody, AppConstants.SubscriptionTags);
}
catch (System.Exception e)
{
Log.Error(AppConstants.DebugTag, $"Error registering device: {e.Message}");
}
}
}
MainActivity.cs
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle savedInstanceState)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(savedInstanceState);
Rg.Plugins.Popup.Popup.Init(this, savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
//SQLite Code
string fileName = "sample.db";
string folderPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
string completePath = Path.Combine(folderPath, fileName);
if (!File.Exists(completePath))
{
using (var binaryReader = new BinaryReader(Android.App.Application.Context.Assets.Open(fileName)))
{
using (var binaryWriter = new BinaryWriter(new FileStream(completePath, FileMode.Create)))
{
byte[] buffer = new byte[2048];
int length = 0;
while ((length = binaryReader.Read(buffer, 0, buffer.Length)) > 0)
{
binaryWriter.Write(buffer, 0, length);
}
}
}
}
//End SQLite Code
LoadApplication(new App(completePath));
//For azure push notification
if (!IsPlayServiceAvailable())
{
throw new Exception("This device does not have Google Play Services and cannot receive push notifications.");
}
CreateNotificationChannel();
//END azure push notification
}
//For azure push notification
protected override void OnNewIntent(Intent intent)
{
if (intent.Extras != null)
{
var message = intent.GetStringExtra("message");
// save message in SQLite on AppShell
(Xamarin.Forms.Application.Current.MainPage as AppShell)?.AddMessage(message);
}
base.OnNewIntent(intent);
}
bool IsPlayServiceAvailable()
{
int resultCode = GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable(this);
if (resultCode != ConnectionResult.Success)
{
if (GoogleApiAvailability.Instance.IsUserResolvableError(resultCode))
Log.Debug(AppConstants.DebugTag, GoogleApiAvailability.Instance.GetErrorString(resultCode));
else
{
Log.Debug(AppConstants.DebugTag, "This device is not supported");
}
return false;
}
return true;
}
void CreateNotificationChannel()
{
// Notification channels are new as of "Oreo".
// There is no need to create a notification channel on older versions of Android.
if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
{
var channelName = AppConstants.NotificationChannelName;
var channelDescription = String.Empty;
var channel = new NotificationChannel(channelName, channelName, NotificationImportance.Default)
{
Description = channelDescription
};
var notificationManager = (NotificationManager)GetSystemService(NotificationService);
notificationManager.CreateNotificationChannel(channel);
}
}
//END azure push notification
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
AndroidManifest. xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1" android:versionName="1.0"
package="YOUR_PACKAGE_NAME"
android:installLocation="auto">
<uses-sdk android:minSdkVersion="21" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission
android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<application android:label="Notification Hub Sample">
<receiver
android:name="com.google.firebase.iid.FirebaseInstanceIdInternalReceiver"
android:exported="false" />
<receiver
android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION"
/>
<category android:name="${applicationId}" />
</intent-filter>
</receiver>
</application>
</manifest>
Любая помощь приветствуется. Пока все, что я нашел, говорит об использовании метода onHandleIntent, но мое приложение говорит, что для этого метода нет переопределения.