【问题标题】:Xamarin Android - How to schedule and alarm with a BroadcastReceiverXamarin Android - 如何使用 BroadcastReceiver 安排和报警
【发布时间】:2018-01-25 03:23:31
【问题描述】:

(我在这里问是因为我没有在 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);
    }

在调用该代码之前,我的班级确保这些代码也已执行:

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# 时,它不再起作用。

【问题讨论】:

  • @JonDouglas 谢谢,但这是 Android Java。所以我已经有一个可以正确执行所有这些的 android 应用程序。当我将其转换为 Xamarin 和 C# 时,它不再起作用。
  • 那么请把它包含在你的原始帖子中。
  • @sadelbrid setTime.Ticks 的值是多少?即temp.Ticks & offset 的值是多少?
  • 为什么 Xamarin 论坛如此休眠?

标签: xamarin xamarin.android broadcastreceiver alarmmanager


【解决方案1】:

这就是我在 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 类:

[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>

希望对你有帮助。

【讨论】:

  • 好像做到了。文档不太清楚要发送什么值作为触发时间(毫秒与滴答声以及从什么基准时间开始)。非常感谢
  • 你好日历,可以帮我处理 DateTime.Parse("22:30"),因为我想设置系统时间,可以在日历上完成,如果没有请告诉我如何处理 Datetime 来安排某个时间
  • 我不明白你想要什么。请提供更多详细信息。也许,问一个新问题?
  • 你为IOS做了什么?
  • @Borshonsaydurrahman checkout UNUserNotificationCenter for iOS
【解决方案2】:

首先,您必须在应用程序内的清单中声明 &lt;receiver android:name=".AlarmReceiver"&gt;&lt;/receiver&gt;

并创建一个 BroadcastReceiver 类:

[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();

        //
    }

下面的代码是启动和取消挂起的intent

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);
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多