Xamarin Android - 如何使用 BroadcastReceiver 进行调度和报警
Xamarin Android - How to schedule and alarm with a BroadcastReceiver
(我在这里问是因为我没有在 Xamarin 论坛上获得帮助)我正在使用以下代码创建警报:
Intent alarmIntent = new Intent(context, typeof(AlarmReceiver));
notificationClickIntent = PendingIntent.GetActivity(context, 0, new Intent(), 0);
pendingIntent = PendingIntent.GetBroadcast(context, 0, alarmIntent, PendingIntentFlags.UpdateCurrent);
am = (AlarmManager)Android.App.Application.Context.GetSystemService(Context.AlarmService);
DateTime setTime = new DateTime(temp.Ticks + offset); //temp is the current time where seconds field = 0
if ((int)Build.VERSION.SdkInt >= 21) //my device enters this case
{
AlarmManager.AlarmClockInfo info = new AlarmManager.AlarmClockInfo(setTime.Ticks, notificationClickIntent);
am.SetAlarmClock(info, pendingIntent);
}
else {
am.SetExact(AlarmType.RtcWakeup, setTime.Ticks, notificationClickIntent);
}
在调用该代码之前,我的 class 确保这些代码也已执行:
ComponentName receiver = new ComponentName(context, Java.Lang.Class.FromType(typeof(AlarmReceiver)));
PackageManager pm = context.PackageManager;
pm.SetComponentEnabledSetting(receiver, ComponentEnabledState.Enabled, ComponentEnableOption.DontKillApp);
Intent alarmIntent = new Intent(context, typeof(AlarmReceiver));
notificationClickIntent = PendingIntent.GetActivity(context, 0, new Intent(), 0);
pendingIntent = PendingIntent.GetBroadcast(context, 0, alarmIntent, PendingIntentFlags.UpdateCurrent);
am = (AlarmManager)Android.App.Application.Context.GetSystemService(Context.AlarmService);
这是我的接收器:
[BroadcastReceiver (Process = ":remote")]
public class AlarmReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
Console.WriteLine("alarm fired");
Toast.MakeText(context, "Received intent!", ToastLength.Short).Show();
}
}
好的,Xamarin 正确注册了接收器。我知道这一点,因为如果我给 AlarmClockInfo 一个不正确的刻度值(一个超出 DateTime 刻度范围的值),闹钟会立即响起并调用我的 OnReceive 方法。但是,当我给它一个刻度值时,比如比当前时间早一分钟,闹钟不会响。也许时间不对?...似乎不是这样,因为我已经记录了系统下一个预定警报的时间,并且它会在我设置的同一时间报告回来。有什么想法吗?
编辑:所以我已经有一个 android 应用程序可以正确执行所有这些操作。当我将它转换为 Xamarin 和 C# 时,它不再有效。
这就是我在我的 Xamarin 应用程序中创建本地通知的方式。
DateTime time = ... // whatever time
AlarmManager manager = (AlarmManager)context.GetSystemService(Context.AlarmService);
Java.Util.Calendar calendar = Java.Util.Calendar.Instance;
calendar.TimeInMillis = Java.Lang.JavaSystem.CurrentTimeMillis();
calendar.Set(time.Year, time.Month - 1, time.Day, time.Hour, time.Minute, 0);
manager.SetRepeating(AlarmType.RtcWakeup, calendar.TimeInMillis,
AlarmManager.IntervalDay, pendingIntent);
这是 BroadcastReceiver class:
[BroadcastReceiver]
public class AlarmReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
NotificationManager nManager = (NotificationManager)context.GetSystemService(Context.NotificationService);
Intent repeatingIntent;
// Here I'm opening two different Activities based on condition
if (CommonUtils.isLoggedIn()))
{
repeatingIntent = new Intent(context, typeof(MainActivity));
repeatingIntent.PutExtra(MainActivity.SELECT_TAB, 1);
}
else
{
repeatingIntent = new Intent(context, typeof(SplashActivity));
}
repeatingIntent.SetFlags(ActivityFlags.ClearTop);
PendingIntent pIntent = PendingIntent.GetActivity(context, 100, repeatingIntent, PendingIntentFlags.UpdateCurrent);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
.SetContentIntent(pIntent)
.SetSmallIcon(Resource.Drawable.az_logo_small)
.SetColor(ContextCompat.GetColor(context, Resource.Color.PrimaryColor))
.SetContentTitle(CommonUtils.MAIN_TITLE)
.SetContentText(UIMessages.VITAL_REMINDER)
.SetAutoCancel(true);
nManager.Notify(100, builder.Build());
}
}
并且在 AndroidManifest.xml 中,您需要此权限
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
还需要在AndroidManifest.xml
中注册BroadcastReceiver
<application android:label="YourAppName" android:largeHeap="true" android:icon="@drawable/ic_launcher">
<receiver android:name=".AlarmReceiver"></receiver>
</application>
希望对您有所帮助。
首先你必须在你的应用程序中的清单中声明<receiver android:name=".AlarmReceiver"></receiver>
并创建一个 BroadcastReceiver class:
[BroadcastReceiver]
class AlarmReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
//Miramos si la alarma debe repetirse
var repeat = intent.GetStringExtra("repeat");
//Hacemos sonar la alarma
Uri notification = RingtoneManager.GetDefaultUri(RingtoneType.Alarm);
Ringtone r = RingtoneManager.GetRingtone(context, notification);
r.Play();
//
}
下面的代码是启动和取消挂起的意图
public void SetAlarm(long miliseconds)
{
AlarmManager alarmManager = (AlarmManager)this.Activity.GetSystemService(Context.AlarmService);
Intent intent = new Intent(this.Activity, typeof(AlarmReceiver));
intent.PutExtra("repeat", repeat);
PendingIntent pendingIntent = PendingIntent.GetBroadcast(this.Activity, /*id de la alarma que sea unico */0, intent, PendingIntentFlags.CancelCurrent);
alarmManager.Set(AlarmType.RtcWakeup, miliseconds, pendingIntent);
Toast toast = Toast.MakeText(this.Activity, Resource.String.set_alarm, ToastLength.Short);
toast.Show();
}
public void CancelAlarm()
{
AlarmManager alarmManager = (AlarmManager)this.Activity.GetSystemService(Context.AlarmService);
Intent intent = new Intent(this.Activity, typeof(AlarmReceiver));
PendingIntent pendingIntent = PendingIntent.GetBroadcast(this.Activity, /*a traves del anterior id ahora podemos pedir que se actualice */0, intent, PendingIntentFlags.UpdateCurrent);
//Con el pending intent actualizado podemos cancelarlo
pendingIntent.Cancel();
alarmManager.Cancel(pendingIntent);
Toast toast = Toast.MakeText(this.Activity, Resource.String.remove_alarm, ToastLength.Short);
toast.Show();
}
要完成,您必须在单击它们时调用它们
if (alarm.Active == true)
{
alarm.Active = false;
alarmsFragment.CancelAlarm();
}
else
{
alarm.Active = true;
// the time you want in milliseconds
long miliseconds = Java.Lang.JavaSystem.CurrentTimeMillis() + 10000 ;
alarmsFragment.SetAlarm(miliseconds);
}
(我在这里问是因为我没有在 Xamarin 论坛上获得帮助)我正在使用以下代码创建警报:
Intent alarmIntent = new Intent(context, typeof(AlarmReceiver));
notificationClickIntent = PendingIntent.GetActivity(context, 0, new Intent(), 0);
pendingIntent = PendingIntent.GetBroadcast(context, 0, alarmIntent, PendingIntentFlags.UpdateCurrent);
am = (AlarmManager)Android.App.Application.Context.GetSystemService(Context.AlarmService);
DateTime setTime = new DateTime(temp.Ticks + offset); //temp is the current time where seconds field = 0
if ((int)Build.VERSION.SdkInt >= 21) //my device enters this case
{
AlarmManager.AlarmClockInfo info = new AlarmManager.AlarmClockInfo(setTime.Ticks, notificationClickIntent);
am.SetAlarmClock(info, pendingIntent);
}
else {
am.SetExact(AlarmType.RtcWakeup, setTime.Ticks, notificationClickIntent);
}
在调用该代码之前,我的 class 确保这些代码也已执行:
ComponentName receiver = new ComponentName(context, Java.Lang.Class.FromType(typeof(AlarmReceiver)));
PackageManager pm = context.PackageManager;
pm.SetComponentEnabledSetting(receiver, ComponentEnabledState.Enabled, ComponentEnableOption.DontKillApp);
Intent alarmIntent = new Intent(context, typeof(AlarmReceiver));
notificationClickIntent = PendingIntent.GetActivity(context, 0, new Intent(), 0);
pendingIntent = PendingIntent.GetBroadcast(context, 0, alarmIntent, PendingIntentFlags.UpdateCurrent);
am = (AlarmManager)Android.App.Application.Context.GetSystemService(Context.AlarmService);
这是我的接收器:
[BroadcastReceiver (Process = ":remote")]
public class AlarmReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
Console.WriteLine("alarm fired");
Toast.MakeText(context, "Received intent!", ToastLength.Short).Show();
}
}
好的,Xamarin 正确注册了接收器。我知道这一点,因为如果我给 AlarmClockInfo 一个不正确的刻度值(一个超出 DateTime 刻度范围的值),闹钟会立即响起并调用我的 OnReceive 方法。但是,当我给它一个刻度值时,比如比当前时间早一分钟,闹钟不会响。也许时间不对?...似乎不是这样,因为我已经记录了系统下一个预定警报的时间,并且它会在我设置的同一时间报告回来。有什么想法吗?
编辑:所以我已经有一个 android 应用程序可以正确执行所有这些操作。当我将它转换为 Xamarin 和 C# 时,它不再有效。
这就是我在我的 Xamarin 应用程序中创建本地通知的方式。
DateTime time = ... // whatever time
AlarmManager manager = (AlarmManager)context.GetSystemService(Context.AlarmService);
Java.Util.Calendar calendar = Java.Util.Calendar.Instance;
calendar.TimeInMillis = Java.Lang.JavaSystem.CurrentTimeMillis();
calendar.Set(time.Year, time.Month - 1, time.Day, time.Hour, time.Minute, 0);
manager.SetRepeating(AlarmType.RtcWakeup, calendar.TimeInMillis,
AlarmManager.IntervalDay, pendingIntent);
这是 BroadcastReceiver class:
[BroadcastReceiver]
public class AlarmReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
NotificationManager nManager = (NotificationManager)context.GetSystemService(Context.NotificationService);
Intent repeatingIntent;
// Here I'm opening two different Activities based on condition
if (CommonUtils.isLoggedIn()))
{
repeatingIntent = new Intent(context, typeof(MainActivity));
repeatingIntent.PutExtra(MainActivity.SELECT_TAB, 1);
}
else
{
repeatingIntent = new Intent(context, typeof(SplashActivity));
}
repeatingIntent.SetFlags(ActivityFlags.ClearTop);
PendingIntent pIntent = PendingIntent.GetActivity(context, 100, repeatingIntent, PendingIntentFlags.UpdateCurrent);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
.SetContentIntent(pIntent)
.SetSmallIcon(Resource.Drawable.az_logo_small)
.SetColor(ContextCompat.GetColor(context, Resource.Color.PrimaryColor))
.SetContentTitle(CommonUtils.MAIN_TITLE)
.SetContentText(UIMessages.VITAL_REMINDER)
.SetAutoCancel(true);
nManager.Notify(100, builder.Build());
}
}
并且在 AndroidManifest.xml 中,您需要此权限
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
还需要在AndroidManifest.xml
中注册BroadcastReceiver<application android:label="YourAppName" android:largeHeap="true" android:icon="@drawable/ic_launcher">
<receiver android:name=".AlarmReceiver"></receiver>
</application>
希望对您有所帮助。
首先你必须在你的应用程序中的清单中声明<receiver android:name=".AlarmReceiver"></receiver>
并创建一个 BroadcastReceiver class:
[BroadcastReceiver]
class AlarmReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
//Miramos si la alarma debe repetirse
var repeat = intent.GetStringExtra("repeat");
//Hacemos sonar la alarma
Uri notification = RingtoneManager.GetDefaultUri(RingtoneType.Alarm);
Ringtone r = RingtoneManager.GetRingtone(context, notification);
r.Play();
//
}
下面的代码是启动和取消挂起的意图
public void SetAlarm(long miliseconds)
{
AlarmManager alarmManager = (AlarmManager)this.Activity.GetSystemService(Context.AlarmService);
Intent intent = new Intent(this.Activity, typeof(AlarmReceiver));
intent.PutExtra("repeat", repeat);
PendingIntent pendingIntent = PendingIntent.GetBroadcast(this.Activity, /*id de la alarma que sea unico */0, intent, PendingIntentFlags.CancelCurrent);
alarmManager.Set(AlarmType.RtcWakeup, miliseconds, pendingIntent);
Toast toast = Toast.MakeText(this.Activity, Resource.String.set_alarm, ToastLength.Short);
toast.Show();
}
public void CancelAlarm()
{
AlarmManager alarmManager = (AlarmManager)this.Activity.GetSystemService(Context.AlarmService);
Intent intent = new Intent(this.Activity, typeof(AlarmReceiver));
PendingIntent pendingIntent = PendingIntent.GetBroadcast(this.Activity, /*a traves del anterior id ahora podemos pedir que se actualice */0, intent, PendingIntentFlags.UpdateCurrent);
//Con el pending intent actualizado podemos cancelarlo
pendingIntent.Cancel();
alarmManager.Cancel(pendingIntent);
Toast toast = Toast.MakeText(this.Activity, Resource.String.remove_alarm, ToastLength.Short);
toast.Show();
}
要完成,您必须在单击它们时调用它们
if (alarm.Active == true)
{
alarm.Active = false;
alarmsFragment.CancelAlarm();
}
else
{
alarm.Active = true;
// the time you want in milliseconds
long miliseconds = Java.Lang.JavaSystem.CurrentTimeMillis() + 10000 ;
alarmsFragment.SetAlarm(miliseconds);
}