AlarmManager repeating constantly once triggered - java

I need my Service to do tasks every night at 02:00, and if failed in task then schedule itself to start again after 30min, but if succeeded then stop itself and start again the other night at 02:00. I managed to get it start at 02:00 but after it is triggered it just triggeres itself continiously.
My code is in Service, and here is the code itself:
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
//doTasks();
MediaPlayer player = MediaPlayer.create(this,
Settings.System.DEFAULT_NOTIFICATION_URI);
player.start();
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 2);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),AlarmManager.INTERVAL_DAY, pendingIntent);
}
doTasks() is the tasks I need to run but because they are slow I use notification sound for testing purposes. And pendingIntent is this Service itself.
Any ideas what is it that makes my AlarmManager trigger constantly?

If your pendingIntent is set to start the Service then basically you're repeatedly creating a new alarm each time in the onStart(...) method.
AlarmManager has a mechanism where it will trigger an alarm "late" if the device was asleep when it should have triggered. In your case, because you constantly re-create the alarm, AlarmManager constantly thinks it should be triggered immediately even if the time is past 02:00:00.
Create the alarm somewhere else to prevent it being constantly re-created each time the Service starts.

Related

How do I create an alarm clock like Alertmanager?

The alarm clock must start by itself, even if the app has been closed and the smartphone restarts.
Is there a safe way to program such an alarm clock?
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent startServiceIntent = new Intent(context, MyService.class);
PendingIntent startServicePendingIntent =
PendingIntent.getService(context,0,startServiceIntent,0);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
if(alarmManager != null)
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,System.currentTimeMillis()
+ 1000 * 60,1000 * 30,startServicePendingIntent);
you can do it easily but you need add some Property to your app like :
1-set first method for set alarm
2-save and handle value for alarm (Room ، Sql or etc) // if you want make loop alarm
3-use broadcastreceiver for two reason(set notification or handle background and close app or restart or somethings like that)
4- some custom method for better handle data streaming in app
i hope this link will can help you
link refrences
have fun :)

AlarmManager not always executing

I'm developing an android app that sends every 5 minutes a post to a server so this way, the server can check if the phone has or not connection.
I'm using AlarmManager, sending a broadcast PendingIntent to a BroadcastReceiver which sends a post to a server. The issue is that it is not always executing:
Intent myIntent = new Intent(Inicio.this, NetworkStatusReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(Inicio.this,
0,
myIntent,
0);
AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
int interval = 60000*5;
manager.setRepeating(AlarmManager.RTC_WAKEUP,
System.currentTimeMillis(),
interval,
pendingIntent);
Is the AlarmManager class the right way to do this?
Because I've been researching about 5.0+ android versions and the power management is different from the earlier android versions. Maybe the AlarmManager.RTC_WAKEUP option is not working on 5.0+ android versions.
I have done some research and I've found something that seems to work. Since this morning, I implemented it and the behavior has improved very much. I realized that having a BroadcastReceiver I could just set the alarm once and set another alarm again on the BroadcastReceiver itself when the alarm was being triggered.
I also used the flag PendingIntent.FLAG_UPDATE_CURRENTfor the PendingIntent(since the alarm PendingIntent can be triggered from different activities)
The code for the Activity would be something like this:
Intent myIntent = new Intent(context, NetworkStatusReceiver.class);
final PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
final AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
manager.set(AlarmManager.RTC_WAKEUP,System.currentTimeMillis() + timeInMillis, pendingIntent);
And the code for the BroadcastReceiver.OnReceive() method would be the same code so the alarm triggers every System.currentTimeMillis() + timeInMillis again (creating this way the setRepeating() method)
This way it seems that the alarm is always triggered since (I think) set() method from AlarmManager works fine with any android version.

AlarmManager Android SDK

I have a problem executing the following code:
Intent myIntent = new Intent(MedicineEntry.this, DisplaySchedule.class);
PendingIntent pendingIntent = PendingIntent.getActivity(MedicineEntry.this, 0, myIntent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 17);
calendar.set(Calendar.MINUTE, 25);
calendar.set(Calendar.SECOND, 0);
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 1);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
Toast.makeText(MedicineEntry.this, "Alarm Will Start In A Second", Toast.LENGTH_LONG).show();
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_FIFTEEN_MINUTES, pendingIntent);
To elucidate my problem, the app should fire up according to the values set for HOUR_OF_DAY, MINUTE and SECOND - even if the device is in sleep mode. I've tried testing the code, but the app does not seem to work. I've tried replacing AlarmManager.INTERVAL_FIFTEEN_MINUTES with 5*1000 which worked fine. Please go easy with the terminologies. I've just started to program with Android this semester at college.
EDIT: This app I am creating is a 'reminder' app. The user is expected to enter the time which the app should execute.
There are basically two ways of interacting with the AlarmManager. Your post is somewhat vague about which will suit your needs.
Anyway, if you want an "Do every 15 minutes" type of alarm, use the ELAPSED mode:
long firstActivation = SystemClock.elapsedRealtime(); // and not System.currentTimeMillis()
mgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstActivation, INTERVAL_MILLISECS, intent);
But, if you're looking for an "Do every day at 15:30" semantics, use RTC mode, like this:
long activationTime = calendar.getTimeInMillis();
long TWENTY_FOUR_HRS = 24 * 60 * 60* 1000;
mgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, activationTime, TWENTY_FOUR_HRS, intent);
Two things to note at the above code:
A. I am using a waking up type of alarms. These are potentially expensive as they would wake up a sleeping device. Are you sure this is what you need (hint: most apps do not)?
B. I am using setInexactRepeating() instead of setRepeating() so to allow the alarm manager to batch together several alarms thus saving resources. If you do not have a good reason not to do so, stick to using setInexactRepeating()

How to run a function when Alarm Manager finishes?

I want to run the function foo() when the alarm manager runs off, but I have not understood how do I do it. I saw you pass an Intent to the alarm manager, are there other ways to do that?
public void SetAlarm()
{
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 19);
cal.set(Calendar.MINUTE, 03);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
AlarmManager alarmMgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
alarmMgr.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
}
As you can see, I'm not sure how to use the alarmMgr.set function correctly. Also, do I need to run it as a service, so if the application will be exited, then it'll still work ?
Thanks!
I saw you pass an Intent to the alarm manager
You pass a PendingIntent to AlarmManager.
are there other ways to do that?
The only way you can use AlarmManager is with a PendingIntent. The purpose of AlarmManager is to give your app control at points in time in the future when your app is no longer running.
Also, do I need to run it as a service, so if the application will be exited, then it'll still work ?
No. The goal of AlarmManager specifically is to allow your process to be terminated, yet give you control again some time in the future, so you are not tying up memory all that time.

How to delay Trigger(starting time) of repeating alarm?

The problem is that I want to delay the repeating-alarm's first fire.
for example I want this pending intent work after 10 mins of the click not right away, how to do that?
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Main.this, ReportService.class);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
Calendar c = Calendar.getInstance();
PendingIntent pendingIntent = PendingIntent.getService(Main.this, 0, intent, 0);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), 112500, pendingIntent);
}
the 2nd paramater in this setInexactRepeating called triggerAtMillis
From Android developer guide:
triggerAtMillis time in milliseconds that the alarm should first go off, using the appropriate clock (depending on the alarm type). This is inexact: the alarm will not fire before this time, but there may be a delay of almost an entire alarm interval before the first invocation of the alarm.
Iam changing it and it always start on the click and does no delay, any help?
Check the
developer link here. The second parameter is triggerAtMillis. It used as time in milliseconds that the alarm should first go off
So in your case, add the extra milliseconds to c.getTimeInMillis(), after which you want to first run your pending intent. :)
check into handler.postDelayed function where you can specify a delay
If using the ELAPSED_REALTIME clock, do this
manager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime()+180000,
180000,
pendingIntent);
Do not use zero or System.currentTimeMillis() as an offset for the ELAPSED clock.

Categories