Xamarin AlarmManager Android
The problem is that your BroadcastReceiver
does not have the [BroadcastReceiver
] attribute.
This code works:
AlarmReceiver.cs
[BroadcastReceiver]
public 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.Icon)
.SetDefaults(NotificationDefaults.All);
builder.SetContentIntent(pending);
var notification = builder.Build();
var manager = NotificationManager.FromContext(context);
manager.Notify(1337, notification);
}
}
MainActivity.cs
[Activity(Label = "App3", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : Activity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
var button = FindViewById<Button>(Resource.Id.MyButton);
button.Click += delegate
{
var alarmIntent = new Intent(this, typeof(AlarmReceiver));
alarmIntent.PutExtra("title", "Hello");
alarmIntent.PutExtra("message", "World!");
var pending = PendingIntent.GetBroadcast(this, 0, alarmIntent, PendingIntentFlags.UpdateCurrent);
var alarmManager = GetSystemService(AlarmService).JavaCast<AlarmManager>();
alarmManager.Set(AlarmType.ElapsedRealtime, SystemClock.ElapsedRealtime() + 5*1000, pending);
};
}
}
Starting AlarmManager in Android (C#)
I think the problem is that you didn't successfully declare your MyBroadcastReceiver
, in xamarin, we can use:
[BroadcastReceiver(Enabled = true)]
to declare this broadcast. It's like declare it in traditional android manifest like this:
<receiver android:name="MyBroadcastReceiver" />
So, MyBroadcastReceiver
should be like this:
[BroadcastReceiver(Enabled = true)]
public class MyBroadcastReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
Toast.MakeText(context, "Time Up... Now Vibrating !!!",
ToastLength.Long).Show();
Vibrator vibrator = (Vibrator)context
.GetSystemService(Context.VibratorService);
vibrator.Vibrate(2000);
}
}
Now you can get the toast: "Time Up... Now Vibrating !!!"
Xamarin Android - How to schedule and alarm with a BroadcastReceiver
This is how I'm creating a local notification in my Xamarin app.
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);
And here is the 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());
}
}
and in AndroidManifest.xml, you need this permission
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
also need the register the BroadcastReceiver in AndroidManifest.xml
<application android:label="YourAppName" android:largeHeap="true" android:icon="@drawable/ic_launcher">
<receiver android:name=".AlarmReceiver"></receiver>
</application>
Hope it helps.
How to set accurate time for Xamarin.Android AlarmManager
If you really need precision try to use the SetExact() method of the alarm manager class.
TimeSpan span = calendarEvent.StartTime - DateTime.Now;
manager.SetExact(AlarmType.ElapsedRealtime,(long)(SystemClock.ElapsedRealtime() + span.TotalMilliseconds),pendingIntent);
And I don't know if it is relevant, but if you are using events for a calendar maybe you should use RTC, since AlarmType.RTC is based on the clock, whereas AlarmType.ElapsedRealTime is based on the time passed since the device was turned on.
Related Topics
Escaping the Escape Character Does Not Work - SQL Like Operator
How to Validate That a String Doesn't Contain HTML Using C#
C#: Throwing Custom Exception Best Practices
Search Xdocument Using Linq Without Knowing the Namespace
Regex to Get Src Value from an Img Tag
Getters and Setters Are Bad Oo Design
How to Lock/Unlock a File Across Process
With C# Use Chrome to Covert HTML to Pdf
Navigation Property Without Declaring Foreign Key
Incorrect Syntax Near the Keyword 'User'
Why Can't Reference to Child Class Object Refer to the Parent Class Object
Load Different CSS File Based on Browser
Entity Framework Specification Pattern Implementation
C# Datetime.Ticks Equivalent in Java