gpt4 book ai didi

xamarin - 在 Xamarin Forms Android 中处理通知

转载 作者:行者123 更新时间:2023-12-02 10:02:14 25 4
gpt4 key购买 nike

我正在使用库 https://github.com/aritchie/notifications我可以正确地创建和安排通知。

我希望在 Android 中处理它们,以便根据通知 - 当用户点击它时它将导航到特定页面。

我发现当我点击通知(在我的 Android 项目中)时会触发以下事件

 protected override void OnNewIntent(Intent intent)
{

}

但是,我在通知中找不到意图中的任何信息,以便建立到特定页面的导航。

如有任何建议,我们将不胜感激。

干杯!

编辑 #1(为相关问题添加其他代码):

如果我发出通知,并在收到通知之前关闭应用程序 - 我会收到一条错误消息,指出应用程序已崩溃。如果我收到通知并关闭应用程序 - 我可以从通知加载应用程序。

我有一个依赖服务,它使用以下方法。

public void Remind(DateTime dateTime, string msgtype, string usermedid)
{
DateTime now = DateTime.Now;
var diffinseconds = (dateTime - now).TotalSeconds;
Intent alarmIntent = new Intent(Forms.Context, typeof(AlarmBroadcastReceiver));
alarmIntent.PutExtra("notificationtype", msgtype);
alarmIntent.PutExtra("id", id);


PendingIntent pendingIntent = PendingIntent.GetBroadcast(Forms.Context, 0, alarmIntent, PendingIntentFlags.UpdateCurrent);
AlarmManager alarmManager = (AlarmManager)Forms.Context.GetSystemService(Context.AlarmService);

//TODO: For demo set after 5 seconds.
alarmManager.Set(AlarmType.ElapsedRealtime, SystemClock.ElapsedRealtime() + diffinseconds * 1000, pendingIntent);

}

[BroadcastReceiver(Enabled = true)]
[IntentFilter(new string[]{"android.intent.action.BOOT_COMPLETED"}, Priority = (int) IntentFilterPriority.LowPriority)]
public class AlarmBroadcastReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
string notificationtype = intent.GetStringExtra("notificationtype");

PowerManager.WakeLock sWakeLock;
var pm = PowerManager.FromContext(context);
sWakeLock = pm.NewWakeLock(WakeLockFlags.Partial, "GCM Broadcast Reciever Tag");
sWakeLock.Acquire();

intent = new Intent(Forms.Context, typeof(MainActivity));
intent.PutExtra("notificationtype", notificationtype);
intent.AddFlags(ActivityFlags.IncludeStoppedPackages);



// Instantiate the builder and set notification elements, including pending intent:
NotificationCompat.Builder builder = new NotificationCompat.Builder(Forms.Context)
.SetDefaults((int)NotificationDefaults.Sound | (int)NotificationDefaults.Vibrate)
.SetAutoCancel(true)
.SetContentIntent(PendingIntent.GetActivity(Forms.Context, 0, intent, 0)).SetContentTitle("Sample Notification")
.SetContentText("Hello World! This is my first action notification!")
.SetTicker("New Notification")

.SetSmallIcon(Resource.Drawable.icon);


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

notification.Flags = NotificationFlags.AutoCancel;

// Get the notification manager:
//NotificationManager notificationManager = Forms.Context.GetSystemService(Context.NotificationService) as NotificationManager;
var manager = NotificationManagerCompat.From(context);

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

sWakeLock.Release();



}
}

当应用程序关闭时,如何使广播接收器保持事件状态?

最佳答案

好吧,我花了一些时间才弄清楚这个问题。当应用程序位于后台并且单击通知时,将调用 OnNewIntent。每次应用程序最小化和恢复时也会调用它...因此为了区分这两个事件之间的区别,您需要检查传入的 Intent 以了解其中包含哪些额外数据。额外的数据将来自您首次启动通知时所做的Intent

另外,请确保将 MainActivityLaunchMode 设置为 LaunchMode.SingleTop,这样您的应用就不会在每次收到通知时重新启动被点击。

[Activity(LaunchMode = LaunchMode.SingleTop, ....)]
public class MainActivity : FormsApplicationActivity {

....

/// <summary>
/// Called when the app is in the background and a notification is clicked on (also called each time the app is minimized and the brought back up), a new <c>Intent</c> is created
/// and sent out, since we use <c>LaunchMode</c> set to <c>SingleTop</c> this method is called instead of the app being restarted.
/// </summary>
/// <param name="intent">The <c>Intent</c> that was set when the call was made. If started from a notification click, extra <c>string</c> values can be extracted.</param>
protected override void OnNewIntent(Intent intent) {

if(intent.HasExtra("Some special key you made up")) { //Here is where you check for special notification intent extras
//Do something brilliant now that you know a notification was clicked on
}
base.OnNewIntent(intent);
}

要了解如何将数据添加到 Intent,您可以查看 the Xamarin Sport App ,但不要像我总是倾向于做的那样,过多地陷入他们正在做的所有其他事情中。只需关注 PutExtra 部分即可。

编辑#1:

如果您的应用完全关闭,您需要从传递到 OnCreateIntent 中提取数据,并将其传递到您的 App 类中或者用它做其他事情:

protected override async void OnCreate(Android.OS.Bundle bundle) {

base.OnCreate(bundle);

Forms.Init(this, bundle);

string parameterValue = Intent.GetStringExtra("Some special key you made up"); //This would come in from the Push Notification being clicked on

Console.WriteLine("\nIn MainActivity.OnCreate() - Param Intent Extras: {0}\n", parameterValue);

//MessagingCenter.Send("nothing", ConstantKeys.NewNotification); //Do something special with the notification data

LoadApplication(parameterValue != null ? new App(parameterValue) : new App()); //Do something special with the notification data
}

编辑#2:

我会根据我当前的代码建议您对 OnReceive 方法进行一些更改(有些可能不是必需的,但这正是我正在做的事情):

  • Label your Broadcast Receiver
  • Add stupid Xamarin constructors
  • Used constant property instead of string for IntentFilter
  • Remove IntentFilter Priority
  • Check for null Intent (might not be necessary)
  • Use Application.Context instead of Forms.Context (I use Forms.Context in other parts of my app so not sure about this one, but can't hurt)
  • Do not overwrite the passed in Intent
  • Create startup intent instead of regular
  • Add IncludeStoppedPackages flag before pulling out extras
  • Check for boot completed event
  • Use Notification.Builder instead of NotificationCompat.Builder (though you might need to change this back)
  • Add following flags to pendingintent: PendingIntentFlags.UpdateCurrent | PendingIntentFlags.OneShot -- Use NotificationManager (unless you have a specific reason you commented it out)
[assembly: UsesPermission(Android.Manifest.Permission.Vibrate)]  
[assembly: UsesPermission(Android.Manifest.Permission.WakeLock)] //Optional, keeps the processor from sleeping when a message is received
[assembly: UsesPermission(Android.Manifest.Permission.ReceiveBootCompleted)] //Allows our app to be opened and to process notifications even when the app is closed

namespace Your.App.Namespace {

[BroadcastReceiver(Enabled = true, Label = "GCM Alarm Notifications Broadcast Receiver")]
[IntentFilter(new []{ Intent.ActionBootCompleted })]
public class AlarmBroadcastReceiver : BroadcastReceiver {
#region Constructors

// ReSharper disable UnusedMember.Global
public AlarmBroadcastReceiver() { }

public AlarmBroadcastReceiver(IntPtr handle, JniHandleOwnership transfer) : base(handle, transfer) { }
// ReSharper restore UnusedMember.Global

#endregion

public void Remind(DateTime dateTime, string msgtype, string usermedid) {
DateTime now = DateTime.Now;
var diffinseconds = (dateTime - now).TotalSeconds;

Intent alarmIntent = new Intent(Application.Context, typeof(AlarmBroadcastReceiver));
alarmIntent.PutExtra("notificationtype", msgtype);
alarmIntent.PutExtra("id", id);

PendingIntent pendingIntent = PendingIntent.GetBroadcast(Application.Context, 0, alarmIntent, PendingIntentFlags.UpdateCurrent);
AlarmManager alarmManager = (AlarmManager)Application.Context.GetSystemService(Context.AlarmService);

//TODO: For demo set after 5 seconds.
alarmManager.Set(AlarmType.ElapsedRealtime, SystemClock.ElapsedRealtime() + diffinseconds * 1000, pendingIntent);
}

public override void OnReceive(Context context, Intent intent) {
#region Null Check

if(intent == null) {
Console.WriteLine("\nIn AlarmBroadcastReceiver.OnReceive() - Intent is null\n");
return;
}

#endregion

intent.AddFlags(ActivityFlags.IncludeStoppedPackages);

string action = intent.Action;
Console.WriteLine("\nIn AlarmBroadcastReceiver.OnReceive() - Action: {0}\n", action);

#region Boot Completed Check

if(action.Equals("android.intent.action.BOOT_COMPLETED")) {

PowerManager pm = PowerManager.FromContext(context);
PowerManager.WakeLock sWakeLock = pm.NewWakeLock(WakeLockFlags.Partial, "GCM Broadcast Receiver Tag");
sWakeLock.Acquire();

Console.WriteLine("\nIn AlarmBroadcastReceiver.OnReceive() - Process Shared Preferences Notifications\n");

#region Process Saved Scheduled Notifications

//Get list of saved scheduled notifications that did not fire off before the device was turned off (I store them in SharedPreferences and delete them after they are fired off)

//Go through the list and reschedule them

#endregion

sWakeLock.Release();
return;
}

#endregion

string notificationtype = intent.GetStringExtra("notificationtype");

Intent startupIntent = Application.Context.PackageManager.GetLaunchIntentForPackage(Application.Context.PackageName);
startupIntent.PutExtra("notificationtype", notificationtype);

// Instantiate the builder and set notification elements, including pending intent:
Notification.Builder builder = new Notification.Builder(Application.Context)
.SetDefaults((int)NotificationDefaults.Sound | (int)NotificationDefaults.Vibrate)
.SetAutoCancel(true)
.SetContentIntent(PendingIntent.GetActivity(Application.Context, 0, intent, PendingIntentFlags.UpdateCurrent | PendingIntentFlags.OneShot))
.SetContentTitle("Sample Notification")
.SetContentText("Hello World! This is my first action notification!")
.SetTicker("New Notification")
.SetSmallIcon(Resource.Drawable.icon);

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

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

// Publish the notification:
int notificationId = ??;//This should be a real unique number, otherwise it can cause problems if there are ever multiple scheduled notifications
notificationManager.Notify(notificationId, notification);
}
}
}

关于xamarin - 在 Xamarin Forms Android 中处理通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43936784/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com