How to run code when an alarmmanager alarm fires - java

I'm trying to figure out how to run some code when an alarmmanager alarm fires. I currently can schedule the alarms, and right now I am sending a broadcast when the alarm fires and I have a broadcast receiver to pick it up. The problem is when the user closes the app by swiping it out of recent apps, my broadcast receivers get stopped, so even when the broadcast is sent, there is no receiver to pick it up. How can I run code straight from the alarm?
Here is my code I am using right now to create a notification at a certian time:
Creating the alarm:
alarmManager.SetExactAndAllowWhileIdle(AlarmType.ElapsedRealtimeWakeup, SystemClock.ElapsedRealtime() + ((long)(App.checkInTimes[i].TimeOfDay.TotalSeconds - DateTime.Now.TimeOfDay.TotalSeconds) * 1000), PendingIntent.GetBroadcast(Android.App.Application.Context, 0, new Intent("android.intent.action.CREATE_CHECKIN_NOTIFICATION"), PendingIntentFlags.UpdateCurrent));
And the broadcast receiver to create the notification:
[IntentFilter(new[] { "android.intent.action.CREATE_CHECKIN_NOTIFICATION" })]
public class NotificationReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
//Send Check In Notification
//Setup notification
Notification.Builder builder = new Notification.Builder(Android.App.Application.Context);
builder.SetContentTitle("Please Check In Now");
builder.SetContentText("Tap here to check in");
builder.SetSmallIcon(Resource.Drawable.exclamationPoint);
builder.SetPriority(2);
long[] pattern = { 1000, 1000, 1000, 1000 };
builder.SetVibrate(pattern);
builder.SetLights(Android.Graphics.Color.Red, 1500, 1500);
Intent launchIntent = new Intent(Android.App.Application.Context, typeof(CheckInScreen));
PendingIntent pendingIntent = PendingIntent.GetActivity(Android.App.Application.Context, 1, launchIntent, PendingIntentFlags.UpdateCurrent);
builder.SetContentIntent(pendingIntent);
//Build notification
Notification notification = builder.Build();
notification.Flags = NotificationFlags.AutoCancel;
//Get Notification Manager
NotificationManager notificationManager = Android.App.Application.Context.GetSystemService(Context.NotificationService) as NotificationManager;
//Publish Notification
notificationManager.Notify(0, notification);}

From this:
The problem is your BroadcastReceiver does not have the [BroadcastReceiver] attribute.
Looking at your code, this is exactly the problem. You are missing said attribute.
Try adding
[BroadcastReceiver]
before your class definition.

Related

Late notifications on Background Service

I'm doing a simple service that, every 10 minutes, download a WebPage (The HTML code), and notify the user if something is changed. Now, the problem is that the first 3-4 notifications are shown correctly, but after these, there's an important delay between notifications, and sometimes they don't arrive.
Here's my code:
Monitor.java
public void onCreate() {
super.onCreate();
customHandler = new android.os.Handler();
customHandler.postDelayed(runnable, 0);
}
Runnable runnable = new Runnable() {
#Override
public void run() {
RUN = true;
LINK = readMessage("ADDR");
Ion.with(getApplicationContext()).load(LINK).asString().setCallback(new FutureCallback<String>() {
#Override
public void onCompleted(Exception e, String result) {
Risultad = result;
if (fileExists(getApplicationContext(), "AVV") == false)
{
Savefile(Risultad, "AVV");
Intent i = new Intent(getApplicationContext(), MainActivity.class);
PendingIntent pi = PendingIntent.getActivity(getApplicationContext(), 0, i, 0);
NotificationManager notificationManager = (NotificationManager)
getSystemService(NOTIFICATION_SERVICE);
NotificationCompat.Builder n = new NotificationCompat.Builder(getApplicationContext())
.setContentTitle("First")
.setContentText(Risultad.toString())
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setVibrate(new long[]{2000})
.setContentIntent(pi)
.setAutoCancel(true)
.setSmallIcon(android.R.drawable.ic_dialog_email);
notificationManager.notify(0, n.build());
}
if (fileExists(getApplicationContext(), "AVV") == true)
{
final String OldAvv = readMessage("AVV");
if (Risultad.equals(OldAvv + "\r\n") == false) {
Savefile(result, "AVV");
Intent i = new Intent(getApplicationContext(), MainActivity.class);
PendingIntent pi = PendingIntent.getActivity(getApplicationContext(), 0, i, 0);
NotificationManager notificationManager = (NotificationManager)
getSystemService(NOTIFICATION_SERVICE);
NotificationCompat.Builder n = new NotificationCompat.Builder(getApplicationContext())
.setContentTitle("Something happened")
.setContentText(result.toString())
.setContentIntent(pi)
.setAutoCancel(true)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setSmallIcon(android.R.drawable.ic_dialog_email);
notificationManager.notify(0, n.build());
}
}
}
});
customHandler.postDelayed(this, 300000);
}
I'm using the Ion library to download the page.
readMessage, SaveFile and fileExist are used to read,save or check my HTML code stored on the device.
Sometimes, the notifications are shown when I open the app.
What can I do to receive the notifications on time?
Have a look at AlarmManager
These allow you to schedule your application to be run at some point in the future. When an alarm goes off, the Intent that had been registered for it is broadcast by the system, automatically starting the target application if it is not already running. Registered alarms are retained while the device is asleep (and can optionally wake the device up if they go off during that time), but will be cleared if it is turned off and rebooted.
Note: The Alarm Manager is intended for cases where you want to have your application code run at a specific time, even if your application is not currently running. For normal timing operations (ticks, timeouts, etc) it is easier and much more efficient to use Handler.
See this guide for more info and code examples

System notification from SyncAdapter:onPerformSync

I have sync adapter that performs some operation in background. To notify my main activity about sync operation status, I used broadcast receivers, so my activity is able to receive messages from sync adapter. It works fine. However, I also need to display notification on android status bar, that indicates some sync results.
So I wrote simple method reponsible to disaply system notification:
private void sendNotification(Context ctx, String message)
{
Intent intent = new Intent(ctx, this.getClass());
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent.FLAG_ONE_SHOT);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(ctx)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Mobile Shopping")
.setContentText(message)
.setAutoCancel(true)
.setDefaults(Notification.DEFAULT_SOUND | Notification.FLAG_SHOW_LIGHTS)
.setLights(0xff00ff00, 300, 100)
.setPriority(Notification.PRIORITY_DEFAULT);
//.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 , notificationBuilder.build());
}
Then, above method is called in onPerform sync:
#Override
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult)
{
.................
sendNotification(context, message);
}
Context is retrieved from constructor. It works without any problems, notification is showing.
However I also need to show main activity after user cicks on notification. So I believe I need to create PendingIntent and pass it to my notification builder (as it's commented in my code). But to pass main activity object to my sync adapter? Notification can be also displayed after auto sync finished.
Any tips?
So, I figured it out. Solution is to create pending intent this way:
Intent notificationIntent = new Intent(ctx, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(ctx, 0, notificationIntent, 0);
So after user clicks to notification, main activity will be shown.

Why my regular notifications are stopped after my phone is getting off?

I wrote an app and I set an alarm manager which set to send a notification every 3 hours. Assume my notification has to be send at 11:10 and my phone is getting off at 11:00. So, I will not receive any notification. When my phone is turned on, I will receive the next notification at 2:10, so everything is working correctly.
Although, it was observed that I will not receive any notification after my phone is getting off for two round of notification. Do you have any suggestion?
The code is provided:
Intent intentAlarm = new Intent(this, NotifyBroadcast.class);
PendingIntent pintentAlarm = PendingIntent.getBroadcast(this, 0, intentAlarm, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager mgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
// Start every 30 seconds
mgr.setRepeating(AlarmManager.RTC_WAKEUP, Calendar.getInstance().getTimeInMillis(), 300, pintentAlarm);
// NotifyBroadcast:
public class NotifyBroadcast extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
NotificationManager mNotificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Intent resultIntent = new Intent(context, MainActivity.class);
PendingIntent resultPendingIntent =
PendingIntent.getActivity(
context,
0,
resultIntent,
0
);
Notification notification = new Notification(R.drawable.ic_launcher, "Let me know what is your emotion buddy!", System.currentTimeMillis());
notification.defaults |= Notification.DEFAULT_SOUND;
notification.sound = Uri.parse("file:///sdcard/notification/notification.mp3");
//notification.flags = Notification.FLAG_AUTO_CANCEL;
notification.setLatestEventInfo(context, "emotion interface", "Let me know what is your emotion buddy!", resultPendingIntent);
int mId = 001;
// mId allows you to update the notification later on.
mNotificationManager.notify(mId, notification);
// mNotificationManager.notify(mId,mBuilder.build());
// mNotificationManager.cancel(mId);
}
}
I didn't understand following part very well :
I will not receive any notification after my phone is getting off for two round of notification .
Just check that you are relaunching your service after reboot. For that you need to add a receiver that launches your Service again after the reboot. You need to handle that on android.intent.action.BOOT_COMPLETED intent broadcast. Some of the questions that might help you are:
Android: make notification persist across phone reboot
android notification after reboot
Android: why did the Alarm notification stop after system reboot
Hope this helps in some way.

Multiple notification on same intent

I am writing an application and in this application I need to set multiple notification with same intent just like open my application whenever user tap on any notification.
All the notification comes on different time and date without having any data but the problem is, if I set two notification for 03:27 PM and 03:28 PM then the first notification (03:27 PM) is canceled (Overwritten by second) and second is working correctly.
I am currently using this code for achieving this goal:
this method is used to set notification from Activity:
public static void setNotificationOnDateTime(Context context, long fireTime)
{
int requestID = (int) System.currentTimeMillis();
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, NotificationReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(context, requestID, i, 0);
am.set(AlarmManager.RTC_WAKEUP, fireTime, pi);
}
and my NotificationReceiver class look like this:
NotificationManager nm;
#Override
public void onReceive(Context context, Intent intent) {
Log.w("TAG", "Notification fired...");
nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent contentIntent;
Bundle bundle = intent.getExtras().getBundle("NotificationBundle");
if(bundle == null)
{
contentIntent = PendingIntent.getActivity(context, 0,
new Intent(context, SplashScreen.class), 0);
}
else
{
contentIntent = PendingIntent.getActivity(context, 0,
new Intent(context, MenuScreen.class)
.putExtra("NotificationBundle", bundle), 0);
}
Notification notif = new Notification(R.drawable.ic_launcher,
"Crazy About Android...", System.currentTimeMillis());
notif.setLatestEventInfo(context, "Me", "Message test", contentIntent);
notif.flags |= Notification.FLAG_AUTO_CANCEL;
nm.notify(1, notif);
}
I alerady spend a lot time on googling and found some solutions but they didn't work for me here is the link of some of them:
android pending intent notification problem
Multiple notifications to the same activity
If any one knows how to do this please help me.
Quote:
Post a notification to be shown in the status bar. If a notification with the same id has already been posted by your application and has not yet been canceled, it will be replaced by the updated information.
But you're always using 1 for the id parameter. Use a unique ID when you post several notifications.
Update If that doesn't help, you can still create Intents which do not compare as being equal, while having an equal effect.
this may be helpful
notif.flags |= Notification.FLAG_ONGOING_EVENT;
the notification will never close...
Try to set as below :
contentIntent=PendingIntent.getActivity(p_context, i, new Intent(context, MenuScreen.class),PendingIntent.FLAG_CANCEL_CURRENT);
It might help you.

Notifications disappear as soon as service ends

I've got a service that scrapes a website for data then if necessary gives the user a notification.
The problem I'm having is that the notifications disappear as soon as the service closes (which could be instantly). The below code is all of the notification code the app has. I haven't put in any code to cancel the notifications.
public static void CreateNotificationCompat(int notificationID, String link, String title, String text, Context ctx)
{
Intent notificationIntent = new Intent("android.intent.action.VIEW", Uri.parse(link));
PendingIntent contentIntent = PendingIntent.getActivity(ctx.getApplicationContext(), 0, notificationIntent, 0);
NotificationManager nm = (NotificationManager) ctx
.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder builder = new NotificationCompat.Builder(ctx);
Resources res = ctx.getResources();
builder.setContentIntent(contentIntent)
.setSmallIcon(R.drawable.notify_icon)
.setWhen(System.currentTimeMillis())
.setContentTitle(title)
.setContentText(text)
.setAutoCancel(false);
Notification n = builder.getNotification();
nm.notify(notificationID, n);
}
If it makes any difference (pretty sure it doesn't) i'm using the application context here.
My services is started periodically, processes a website, notifies if needed and then closes.
At the end of my service instead of just calling stopSelf() i sleep for 30 or so seconds and then call stopSelf(). Then the notification stays for 30 seconds and then disappears. Nothing relevant appears in logcat at the time the notifications disappear.
I've only been able to test using ICS so far.
The code you have posted works. I tested it from both an activity and a service on jb, and the notification stays when the components are stopped. I even verified that I could kill the process and the notification stays. Try to strip down the app and see if the problem persists. Specifically check to see that you don't call cancel on the notification by mistake.
You seem to forgot check developer manual first. See here http://developer.android.com/guide/topics/ui/notifiers/notifications.html and look for FLAG_ONGOING_EVENT and FLAG_NO_CLEAR flags.
I've only been able to test using ICS so far.
That's why simulators are quite useful. Try it. It's part of SDK.
Please try the old way on the same device and tell us if it behaves the same way:
private static void CreateNotificationCompat(int notificationID, String link, String title, String text, Context ctx) {
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager) ctx.getSystemService(ns);
Notification notification = new Notification(R.drawable.notify_icon, title, System.currentTimeMillis());
notification.flags = Notification.FLAG_AUTO_CANCEL;
PendingIntent contentIntent;
Bundle bundle = new Bundle();
Intent notificationIntent = new Intent("android.intent.action.VIEW", Uri.parse(link));
contentIntent = PendingIntent.getActivity(ctx, notificationID,
notificationIntent, 0);
notification.setLatestEventInfo(ctx, title, text,
contentIntent);
mNotificationManager.notify(notificationID, notification);
}
Just aa note this behaviour occurs when startForeground() is used and then stopSelf() is called.

Categories

Resources