Android Notification using alarm manager not working - java

I have been trying to get notifications to launch on Android at the correct time. I want them to go off 2 mins in the future from App launch. If I can get it working here I can easily get it working where I really need to do it. The logs show that the needed lines of code are running but the notification never launches. I am up to over 8 hours of trying to debug this and getting no where. Any help would be great.
Here is the Reminder code I have created:
final PendingIntent pi = PendingIntent.getBroadcast(this.mContext,
0,
i,
PendingIntent.FLAG_ONE_SHOT);
TimeZone timeZone= TimeZone.getDefault();
Calendar time= Calendar.getInstance(timeZone);
time.add(Calendar.MINUTE, 2);
this.mAlarmManager.set(AlarmManager.RTC_WAKEUP,
time.getTimeInMillis(),
pi);
Log.d ("setReminder",time.getTime().toLocaleString());
Now below is my OnAlarmRecieve code that is never running 2 mins later according to the logs. The class extends BroadcastReceiver
#Override
public void onReceive(final Context context,
final Intent intent) {
Log.d(TAG, "Recieved wake up cal from Alarm Manger");
final String tableName = intent.getStringExtra(IntentExtraStringStorage.TABLE_NAME);
final long rowID = intent.getLongExtra(IntentExtraStringStorage.ROW_ID,
-1);
final String titleString = intent.getStringExtra(IntentExtraStringStorage.NOTIFICATION_TITLE);
final String notificationString=intent.getStringExtra(IntentExtraStringStorage.NOTIFICATION_NOTE);
WakeUpReminderIntentService.acuireStaticLock(context);
/*if (tableName== Task.TABLE_NAME) {
launchTaskView(context, rowID);
}
else {
Log.e (TAG, "Did not Launch");
Toast.makeText(context, "Did not work right", Toast.LENGTH_SHORT).show();
}*/
Intent i = new Intent (context, ReminderService.class);
i.putExtra("taskID", rowID);
i.putExtras(intent.getExtras());
Log.d(TAG, "Launched task");
//TODO Added code to build the screen correctly
//FIXIT this need to be finished.
context.startService(i);
}]=

The problem was not putting the OnAlarmReciever in the mainfest as a receiver, and there was something not being put into the services as well.

Related

Multiple Notifications while repeating them in an interval of one Day.Used Unique ID in notify function but unable to get desired output

Problem: All notifications are seen On the day when they are set. But after One Day interval when the time comes for all the notifications to be displayed together then only the notification I set Last is visible (maybe I am wrong that's not the last one but only one notification is displayed)
I have gone through different solutions of Multiple Notification in android through various sites as well as stack overflow. All are mentioning to use a Unique Id in notificationManager.notify() but I have already done this but still same result..
This is my code for generating the notification as well as repeating it with one day interval
I have used shared preferences for unique ID
Intent intent=new Intent(PolicyDetails.this,AlarmReciever.class);
pref=this.getSharedPreferences("MyPref",0);
editor=pref.edit();
editor.putInt("MID",pref.getInt("MID",0)+1);
editor.commit();
PendingIntent pendingIntent=PendingIntent.getBroadcast(PolicyDetails.this,pref.getInt("MID",0),intent,PendingIntent.FLAG_CANCEL_CURRENT);
// Constants.setMID(Constants.MID+1);
AlarmManager alarmManager=(AlarmManager)PolicyDetails.this.getSystemService(PolicyDetails.this.ALARM_SERVICE);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis(),AlarmManager.INTERVAL_DAY,pendingIntent);
This is my Notification Builder Code
Intent i1=new Intent(context,PaidCancel.class);
Intent i2=new Intent(context,PaidCancel.class);
i1.putExtra("code",1);
i2.putExtra("code",2);
pref=context.getSharedPreferences("MyPref",0);
PendingIntent pi =PendingIntent.getBroadcast(context,0,i1,0);
PendingIntent p2=PendingIntent.getBroadcast(context,1,i2,0);
NotificationCompat.Builder mnotifybuilder=new NotificationCompat.Builder(context).setSmallIcon(R.drawable.ic_menu_gallery)
.setContentTitle("Alarm fired").setContentText("A Remainder for your task No "+pref.getInt("MID",0)).setAutoCancel(false).addAction(R.id.paid,"Button1",pi).addAction(R.id.dismiss,"Button2",p2).setVibrate(new long[]{1000,1000,1000,1000});
NotificationManager notificationManager=(NotificationManager)`enter code here`context.getSystemService(context.NOTIFICATION_SERVICE);
notificationManager.notify(pref.getInt("MID",0),mnotifybuilder.build());
Log.d("Increased...","increased"+pref.getInt("MID",0));
This is my Paidcancel class code
static public class PaidCancel extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getIntExtra("code",0)==1) {
Log.d("see once...", "paid button clivked");
}
else
if(intent.getIntExtra("code",0)==2)
Log.d("see once..","cancel Button clicked");
else
Log.d("not ","no");
}
}
This code works for me to create unique notification id..
SharedPreferences prefs = mContext.getSharedPreferences(MainActivity.class.getSimpleName()
, Context.MODE_PRIVATE);
int notificationNumber = prefs.getInt("notificationNumber", 0);
// generate Notify id from SharedPreferences.
mNotificationManager.notify(notificationNumber, mBuilder.build());
SharedPreferences.Editor editor = prefs.edit();
if (notificationNumber < 5000)
notificationNumber++;
else
notificationNumber = 0;
editor.putInt("notificationNumber", notificationNumber);
editor.commit();

Is there a way to prevent user from easily closing app that starts AlarmManager?

I am working on app to track device's position and compare it to set values. For example: parent wants to be sure that on Monday, between 8am and 3pm his kid is in the school. The app should stay on kid's phone, check its position every now and then and then compare it with school's coords within certain radius. If kid's phone happened to be out of bounds, phone would send simple notification to the parent via email, sms or whatever (haven't programmed that part yet).
My problem is that app does its job only when the it's open. And that's pretty obvious and understandable but I'd like it to work more like an alarm clock. Alarm clocks are not present in 'Recent apps' menu, so you can't easily kill it but still it goes off on time and works as desired. Also I don't have to reopen my alarm clock after restarting the phone, which as a feature could be also a great addition to my app.
I don't want it to be completely UNclosable. Just a little bit harder, so little kids or old people with memory problems could use it without closing accidentally.
Here's my code I've done so far:
public class Alarm extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "");
wl.acquire();
//HERE WAS MY LOCATIONMANAGER MAGIC
wl.release();
}
public void setAlarm(Context context)
{
AlarmManager am =( AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, Alarm.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 20, pi); // Millisec * Second * Minute
}
public void cancelAlarm(Context context)
{
Intent intent = new Intent(context, Alarm.class);
PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(sender);
}
}

Run a Service continuously in the background to watch for the time

I've a date and time stored in database, I need to continuously monitor the time and date in the background and run a function in the app when that time comes, there can be set of of date and time's, i only know that i need services to do this, but not more than that. can some please tell whether this can be achieved or not? if yes, please suggest me how I can proceed further.Thank u...
Android has a very developer friendly class for that: AlarmManager
So, take the Date an Time from database, define an alarm event with it, subscribe your app for notifications for that and wait until the event comes to do the job you need to do.
this is how:
public class MyAlarm extends IntentService {
private NotificationManager myAlarmNotificationManager;
public MyAlarm() {
super("MyAlarm");
}
//this send the notification
private void sendNotification(String message) {
Log.d("MyAlarm", "Preparing to send notification...: " + message);
myAlarmNotificationManager = (NotificationManager) this
.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, AlarmActivity.class), 0);
NotificationCompat.Builder alamNotificationBuilder = new NotificationCompat.Builder(
this).setContentTitle("Alarm").setSmallIcon(R.drawable.ic_launcher)
.setStyle(new NotificationCompat.BigTextStyle().bigText(message))
.setContentText(message);
alamNotificationBuilder.setContentIntent(contentIntent);
myAlarmNotificationManager.notify(1, alamNotificationBuilder.build());
Log.d("MyAlarm", "Notification sent.");
}
#Override
public void onHandleIntent(Intent intent) {
sendNotification("Do something");
}
}

Android set() and setExact() alarms firing at incorrect intervals

I'm developing an app that should perform a certain task every 60 seconds. Since there's some accuracy problems with alarms in Android 4.4+, where all alarms are inexact, I've opted for the chained model: A BroadcastReceiver fires the first alarm, and each alarm in turn sets the next alarm.
The problem is that, even though I'm setting the alarms at intervals of 60 seconds (60000 ms), the alarms trigger at 5 second intervals, and sometimes even less. I've tested the code on my Nexus 5 (Android 5.1.1) and on an Android 5.0.1 emulator, both giving the same result.
I should point out that both receivers are registered on the AndroidManifest and my application has the RECEIVE_BOOT_COMPLETED permission.
EDIT: setExact() causes exactly the same problem
StartupReceiver.java (BroadcastReceiver for BOOT_COMPLETED):
public class StartupReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "Got the BOOT_COMPLETED signal");
// Get the first alarm to be invoked immediately
AlarmReceiver.setNextScanAlarm(context, 0);
}
}
AlarmReceiver.java
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Start the service
Intent startServiceIntent = new Intent(context, BackgroundService.class);
startServiceIntent.putExtra("interval", 60000);
startServiceIntent.putExtra("action", "scan");
context.startService(startServiceIntent);
// Schedule the next alarm
setNextScanAlarm(context, 60000);
}
public static void setNextScanAlarm(Context context, int interval) {
Intent scanIntent = new Intent(context, AlarmReceiver.class);
scanIntent.putExtra("interval", interval);
scanIntent.putExtra("action", "scan");
PendingIntent pendingIntent = PendingIntent.getBroadcast(
context,
0,
scanIntent,
PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.set(
AlarmManager.ELAPSED_REALTIME_WAKEUP,
interval,
pendingIntent);
}
}
What could be the problem?
I believe because this is an alarm clock when calling
alarmManager.set(
AlarmManager.ELAPSED_REALTIME_WAKEUP,
interval,
pendingIntent);
The variable you are calling interval is the amount of time you want to elapse UNTIL the next alarm , but when you think about this when does it know to start? More so, when does time actually equal zero? When you create it? No. When you call .set()? No. It is actually zero upon BOOT. So you are asking it to launch 60 seconds after boot, and your asking for this everytime, this time will have already elapsed.
This is where the confusion is, and where you should probably just use a call like new
Handler.postDelayed(Runnnable r, 60000) instead of an alarm Manager. It will be much more accurate and will not be subject to some problems with understanding the Android Operating System and its alarms/clocks/etc/etc.
But for your specific case I believe you could solve it by accessing System function calls/variables. So inside of your function setNextScanAlarm() I believe it would look like this:
public static void setNextScanAlarm(Context context, int interval) {
//create the intent the same way as before
Intent scanIntent = new Intent(context, AlarmReceiver.class);
scanIntent.putExtra("interval", interval);
scanIntent.putExtra("action", "scan");
PendingIntent pendingIntent = PendingIntent.getBroadcast(
context,
0,
scanIntent,
PendingIntent.FLAG_ONE_SHOT);
//create new variables to calculate the correct time for this to go off
long timeRightNow = System.elapsedRealTime() //use something else if you change AlarmManager type
long timeWhenIShouldGoOff = timeRightNow + interval;
//use the new timeWhenIShouldGoOff variable instead of interval
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.set(
AlarmManager.ELAPSED_REALTIME_WAKEUP,
timeWhenIShouldGoOff,
pendingIntent);
}
See my answer to a similar question.
I use postDelayed() instead of AlarmManager for the short time intervals (less than 1 minute), and AlarmManager for long.

Android notifications not getting posted when scheduled with AlarmManager

am trying to post notifications from my game after a certain interval. I call PostNotification() function from onReceive() method of my BroadcastReciever class to post the notification after 1 minute of starting the game.
BroadcastReceiver
public class NotificationReciever extends BroadcastReceiver
{
private static int count=0;
#Override
public void onReceive(Context context, Intent intent)
{
try
{
Bundle bundle = intent.getExtras();
String message = bundle.getString("message");
int id = bundle.getInt("id");
PostNotification(message, id);
}
catch (Exception e)
{
e.printStackTrace();
}
wl.release();
}
public void PostNotification(String notif, int id)
{
Notification notify=new Notification(R.drawable.icon,
notif,
System.currentTimeMillis());
Intent intent = new Intent(MyUtil.getInstance().context, MyActivity.class);
PendingIntent i=PendingIntent.getActivity(MyUtil.getInstance().context, 0, intent, 0);
notify.setLatestEventInfo(MyUtil.getInstance().context, "Title", notif, i);
MyActivity.notifyMgr.notify(id, notify);
}
}
}
I am calling ScheduleNotification() from onCreate() of MyActivity
public void ScheduleNotification()
{
Calendar cal = Calendar.getInstance();
Intent intent = new Intent(MyUtil.getInstance().context, NotificationReciever.class);
intent.putExtra("id", NOTIFY_ID);
intent.putExtra("message", "message");
PendingIntent sender = PendingIntent.getBroadcast(MyUtil.getInstance().context, NOTIFY_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), sender);
}
But i do not recieve any notification and get the following error in my logcat
01-11 19:28:32.455: W/System.err(20661): java.lang.NullPointerException
01-11 19:28:32.475: W/System.err(20661): at android.content.ComponentName.<init>(ComponentName.java:75)
01-11 19:28:32.475: W/System.err(20661): at android.content.Intent.<init>(Intent.java:2893)
01-11 19:28:32.475: W/System.err(20661): at com.games.TestGame.NotificationReciever.PostNotification(NotificationReciever.java:41)
01-11 19:28:32.475: W/System.err(20661): at com.games.TestGame.NotificationReciever.onReceive(NotificationReciever.java:27)
I know that i am doing something wrong when creating intent for notification. I get notification correctly when i call is directly from my activity but something goes wrong when i call it through alarm
Intent intent = new Intent(MyUtil.getInstance().context, MyActivity.class);
Can anyone please tell me where i am going wrong.
The when parameter to the Notification constructor used by you is simply for display purposes. It won't delay the display of your Notification.
How about using an Alarm? It'll only accept an Intent, though.
It is total mistake of understanding. Look at the details of public Notification (int icon, CharSequence tickerText, long when). It is like below:
icon The resource id of the icon to put in the status bar.
tickerText The text that flows by in the status bar when the notification first activates.
when The time to show in the time field. In the System.currentTimeMillis timebase.
That means that it is just for show in the Notification Massage, not for the time of notification. If you want to give the notification at certain future time, you have to set an AlermManager for that time. The AlermManager will call the BroadcastReceiver. So you have to create a BroadcastReceiver also, in which you have to set the Notification.You can go through this link.

Categories

Resources