Xamarin 通知 Android 崩溃 [英] Xamarin Notification Android Crash
问题描述
我收到以下异常:
Java.Lang.IllegalStateException:指定的孩子已经有一个父母.您必须在孩子的父母拳头上调用 removeVeiw().
Java.Lang.IllegalStateException: The specified child already has a parent. You must call removeVeiw() on the child's parent fist.
运行以下代码块时.这一切都从我的表单页面开始,按下按钮使用警报管理器生成预定的通知.问题是如果点击通知,如果应用程序仍然处于活动状态,则会抛出上述异常.
when running the following code blocks. It all starts in my Forms Page with a button press that uses the alarm manager to generate a scheduled notification. The problem is that if the notification is clicked on, the above exception gets thrown if the app is still active.
如果我在手机上切换应用程序,然后单击通知,它会按预期恢复应用程序而不会崩溃.
If I switch applications on the phone, then click the notification, it brings the application back up as intended without the crash.
以下是此工作流程的相关代码片段:
Below are the code snippets in question for this workflow:
来自 xamarin 页面:
from xamarin page:
private void BtnStartJob_Clicked(object sender, EventArgs e)
{
lblStatus.Text = "";
if (btnStartJob.Text == "Start Job")
{
tmrToggle.StartCommand.Execute(null);
App.Manager.StartJob(App.Manager.currentTimesheet.ProjectID);
btnStartJob.Text = "Start Break";
}
else if (btnStartJob.Text == "End Break")
{
tmrAlert.PauseCommand.Execute(null);
tmrToggle.StartCommand.Execute(null);
App.Manager.EndBreak(App.Manager.currentTimesheet.TimesheetID);
btnStartJob.Text = "Start Break";
var notificationService = DependencyService.Get<INotificationService>();
notificationService.CancelNotification();
}
else if (btnStartJob.Text == "Start Break")
{
tmrAlert.StartCommand.Execute(null);
tmrToggle.PauseCommand.Execute(null);
App.Manager.StartBreak(App.Manager.currentTimesheet.TimesheetID);
btnStartJob.Text = "End Break";
// schedule the notification here.
var notificationService = DependencyService.Get<INotificationService>();
notificationService.CreateNotification("Take Action", "Your break started 1 second ago, please take action.", TimeSpan.FromSeconds(15).Ticks);
}
}
通知服务
public class NotificationService : INotificationService
{
public void CancelNotification()
{
var alarmIntent = new Intent(Android.App.Application.Context, typeof(AlarmReceiver));
var pending = PendingIntent.GetBroadcast(Android.App.Application.Context, 0, alarmIntent, PendingIntentFlags.UpdateCurrent);
var alarmManager = Android.App.Application.Context.GetSystemService("alarm").JavaCast<AlarmManager>();
alarmManager.Cancel(pending);
}
public void CreateNotification(string title, string message, long durationInTicks)
{
var duration = TimeSpan.FromTicks(durationInTicks);
var alarmIntent = new Intent(Forms.Context, typeof(AlarmReceiver));
alarmIntent.PutExtra("title", title);
alarmIntent.PutExtra("message", message);
var pending = PendingIntent.GetBroadcast(Android.App.Application.Context, 0, alarmIntent, PendingIntentFlags.UpdateCurrent);
var alarmManager = Android.App.Application.Context.GetSystemService("alarm").JavaCast<AlarmManager>();
alarmManager.Set(AlarmType.ElapsedRealtime, duration.Milliseconds, pending);
}
}
警报接收器:
[BroadcastReceiver]
class AlarmReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
var message = intent.GetStringExtra("message");
var title = intent.GetStringExtra("title");
var resultIntent = new Intent(context, typeof(MainActivity));
resultIntent.SetFlags(ActivityFlags.NewTask | ActivityFlags.ClearTask);
var pending = PendingIntent.GetActivity(context, 0,
resultIntent,
PendingIntentFlags.CancelCurrent);
var builder =
new Notification.Builder(context)
.SetContentTitle(title)
.SetContentText(message)
.SetSmallIcon(Resource.Drawable.WESSUClogo)
.SetDefaults(NotificationDefaults.All);
builder.SetContentIntent(pending);
var notification = builder.Build();
var manager = NotificationManager.FromContext(context);
manager.Notify(1337, notification);
}
}
主要活动:global::Xamarin.Forms.Platform.Android.FormsApplicationActivity{
MainActivity: global::Xamarin.Forms.Platform.Android.FormsApplicationActivity {
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
global::Xamarin.Forms.Forms.Init(this, bundle);
LoadApplication(new App());
}
}
关于如何解决的任何建议?对我来说,最大的问题是我需要在哪个对象上调用 removeView()?这个异常是在 LoadApplication(newApp()) 上抛出的;行在我的 MainActivity 中.
Any suggestions on how to resolve? For me the biggest question is what object do I need to call removeView() on? This exception is thrown on the LoadApplication(newApp()); line in my MainActivity.
由于完整的堆栈跟踪真的很长,请单击此处获取 pastebin.
Since a full stack trace is really long, click here for the pastebin.
推荐答案
自己发现了答案.
在 AlarmReceiver 中,我需要做的就是:
inside the AlarmReceiver all I need to do was this:
resultIntent.SetFlags(ActivityFlags.Singletop);
resultIntent.SetFlags(ActivityFlags.Singletop);
这篇关于Xamarin 通知 Android 崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!