c# - 在 xamarin 表单中关闭应用程序时无法显示通知
问题描述
我正在尝试实现一个后台服务,它会不断地通知我。因此,我正在使用警报管理器和广播接收器。这是我的广播接收器代码
[BroadcastReceiver(Enabled = true)]
[IntentFilter(new string[] {PeriodicService.AlarmService, "android.intent.action.BOOT_COMPLETED" }, Priority = (int)IntentFilterPriority.LowPriority)]
public class BackgroundReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
PowerManager pm = (PowerManager)context.GetSystemService(Context.PowerService);
PowerManager.WakeLock wakeLock = pm.NewWakeLock(WakeLockFlags.Partial, "BackgroundReceiver");
wakeLock.Acquire();
Device.StartTimer(new TimeSpan(0, 0, 10), () =>
{
// do something every 60 seconds
Device.BeginInvokeOnMainThread(() =>
{
Toast.MakeText(Android.App.Application.Context, "Hi when app opened", ToastLength.Short).Show();
NotificationCenter.NotifyNotificationTapped(intent);
var alarmAttributes = new AudioAttributes.Builder()
.SetContentType(AudioContentType.Sonification)
.SetUsage(AudioUsageKind.Alarm)
.Build();
// var alarmUri = Android.Net.Uri.Parse("Resources/Audio/AlarmSound.wav");
NotificationCenter.Current.Show((notification) => notification
.WithScheduleOptions((schedule) => schedule
.Build())
.WithAndroidOptions((android) => android
.WithAutoCancel(true)
.WithChannelId("General")
.WithPriority(Plugin.LocalNotification.NotificationPriority.High)
.Build())
.WithiOSOptions((ios) => ios
.ShouldPlayForegroundSound(true)
.Build())
.WithReturningData("Dummy Data")
.WithTitle("Test Title")
.WithDescription("Test Description")
.WithNotificationId(100)
.Create());
Toast.MakeText(Android.App.Application.Context, "HI", ToastLength.Short).Show();
MessagingCenter.Send<object, string>(this, "UpdateLabel", "Hello from Android");
});
return true; // runs again, or false to stop
});
wakeLock.Release();
}
}
这是我的后台服务代码
[Service]
public class PeriodicService : Service
{
public override IBinder OnBind(Intent intent)
{
return null;
}
public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
{
// From shared code or in your PCL
MessagingCenter.Send<object, string>(this, "UpdateLabel", "Hello from Android");
Device.StartTimer(new TimeSpan(0, 0, 10), () =>
{
// do something every 60 seconds
Device.BeginInvokeOnMainThread(() =>
{
Toast.MakeText(Android.App.Application.Context, "Hi when app closed", ToastLength.Short).Show();
});
return true; // runs again, or false to stop
});
return StartCommandResult.Sticky;
}
}
这是我的主要活动代码
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
global::Xamarin.Essentials.Platform.Init(this, savedInstanceState);
ZXing.Net.Mobile.Forms.Android.Platform.Init();
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
global::ZXing.Net.Mobile.Forms.Android.Platform.Init();
LoadApplication(new App());
Intent alarmIntent = new Intent(Application.Context, typeof(BackgroundReceiver));
BackgroundReceiver myreceiver = new BackgroundReceiver();
RegisterReceiver(myreceiver, new IntentFilter("android.intent.action.BOOT_COMPLETED"));
//StartService(new Intent(this, typeof(PeriodicService)));
// CreateNotificationChannel();
if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.O)
{
//DispatchNotificationThatServiceIsRunning();
//StartForegroundService(Intent);
StartService(new Intent(this, typeof(PeriodicService)));
}
else
{
StartService(new Intent(this, typeof(PeriodicService)));
}
//alarmIntent.PutExtra("message", "This is my test message!");
//alarmIntent.PutExtra("title", "This is my test title!");
//PendingIntent pendingIntent = PendingIntent.GetBroadcast(Application.Context, 0, alarmIntent, PendingIntentFlags.UpdateCurrent);
//AlarmManager alarmManager = (AlarmManager)Application.Context.GetSystemService(Context.AlarmService);
//alarmManager.SetAndAllowWhileIdle(AlarmType.RtcWakeup, DateTime.Now.Millisecond + 5000, pendingIntent);
}
这是我在清单中的代码
<application android:theme="@style/MainTheme" android:usesCleartextTraffic="true" android:allowBackup="false" android:label="myproject">
<receiver android:name=".BackgroundReceiver" android:enabled="true" android:exported="true" android:process=":remote" android:label="myproject" />
</application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"></uses-permission>
这是我请求许可的代码。
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
{
global::Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
global::ZXing.Net.Mobile.Android.PermissionsHandler.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
我经历了许多解决方案,但没有任何帮助。这些是我经历过的链接
Android - 应用程序关闭后,AlarmManager 不工作
我也尝试使用前台服务,这是我的服务代码
public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
{
// From shared code or in your PCL
MessagingCenter.Send<object, string>(this, "UpdateLabel", "Hello from Android");
CreateNotificationChannel();
DispatchNotificationThatServiceIsRunning();
return StartCommandResult.Sticky;
}
public void DispatchNotificationThatServiceIsRunning()
{
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.SetDefaults((int)NotificationDefaults.All)
.SetVibrate(new long[] { 100, 200, 300, 400, 500, 400, 300, 200, 400 })
.SetSound(null)
.SetPriority(NotificationCompat.PriorityHigh)
.SetAutoCancel(false)
.SetSmallIcon(Resource.Drawable.notification_icon_background)
.SetContentTitle("test")
.SetContentText("service started")
.SetOngoing(true);
Notification bui = mBuilder.Build();
NotificationManager notificationManager = (NotificationManager)GetSystemService(NotificationService);
notificationManager.Notify(0, bui);
StartForeground(121, bui);
}
public void CreateNotificationChannel()
{
if (Build.VERSION.SdkInt < BuildVersionCodes.O)
{
return;
}
var channelName = "Notification_Channel";
var channelDescription = "Foreground Notification";
var channel = new NotificationChannel("10121", channelName, NotificationImportance.High)
{
Description = channelDescription
};
var notificationManager = (NotificationManager)GetSystemService(NotificationService);
notificationManager.CreateNotificationChannel(channel);
}
到目前为止,我在应用程序设置中获得了通知渠道,但没有为我显示通知。我正在使用Redmi note 8 设备,我的目标 android 版本是 Android 11.0(API level 30)。我已经浏览了满足我要求的应用程序StepSetGo,您可以在 Playstore 中看到即使应用程序被杀死,应用程序也会持续显示通知,并且它会记录没有互联网的步数。我已经为此应用程序授予了相同的权限,例如自动启动并且没有电池限制,但它仍然无法正常工作。我不知道如何解决这个任何建议?
解决方案
广播接收器将与应用程序一起死亡。我会使用该服务来启动广播接收器并让它直接与服务对话。
为您服务: MyReceiver myreceiver = new MyReceiver(this); RegisterReceiver(myreceiver, new IntentFilter("com.example.MyReceiver");
在您的接收器中:
service.Notify("现在该起床了!");
另外,我注意到您的服务没有永久运行的通知。它将被操作系统杀死。
在您的服务中: StartForeground(intID, notification);
推荐阅读
- go - 如何为其他人创建 golang 模块?
- r - 如何在 markdown / knitr 中的消息中换行?
- excel - hlookup vlookup 返回多个值
- python - 使用 Twisted 像服务一样运行 python 脚本
- python - 在 groupby 之后的多索引数据帧 .columns.levels[1] 给出整个数据帧的列
- java - (JOOQ)当我尝试编译项目时,Mysql 出现连接错误
- .net - MVVM-Light EventToCommand 风格
- flask - 在 jinja2 和 js 之间共享设计数据
- swift - 如何定义节点的区域以使其成为按钮
- python - 8x8 矩阵上的陀螺仪动画