AlarmManager not always executing - java

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.

Related

how to make my AlarmManager work on all phones && How do I get permission to schedule my alarms without ever deleting them

I tried a lot of codes and examples but I didn't find a solution to make my alarms work on all phones because on some phones when the app is destroyed the alarms are completely destroyed, some when I open the app again all the existing alarms start over
Is it true that my app should be in the whitelist? What is the solution?
However, there are apps on the Play Store that work well
#RequiresApi(api = Build.VERSION_CODES.M)
private void setAlarm() {
alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this,AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(this,0,intent,0);
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
Toast.makeText(this,"Alarm set Seccussfely",Toast.LENGTH_SHORT).show();
}
Instead of AlarmManager, need to use WorkManager. AlarmManager is old mechanizm for Android version till 6.0

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 :)

Android alarm manager fire at the exact moment

I have an app which needs to do task at the exact time provided just like the stock android alarm clock I have used setExactAndAllowWhileIdle() / setExact(). But BroadcastReciever fires after some minutes and sometimes after opening the app, is there any workaround for it?
Alarm Setter code
// set Alarm
Intent intent = new Intent(this.context, AlarmReceiver.class);
intent.putExtra("alarmInfo", extraInfo);
intent.setAction(Long.toString(System.currentTimeMillis()));
PendingIntent pendingIntent = PendingIntent.getBroadcast(this.context, 123456, intent, 0);
AlarmManager alarmManager = (AlarmManager) this.context.getSystemService(Context.ALARM_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, finalTime - 400, pendingIntent);
} else {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, finalTime - 400, pendingIntent);
}
BroadcastReciever
setNextAlarm();
Log.d("RESULT", "fired");
Intent alarmIntent = new Intent(context, AlarmSoundService.class);
// Log.d("extra", "alarmInfo: " + intent.getStringExtra("alarmInfo"));
alarmIntent.putExtra("alarmInfo", intent.getStringExtra("alarmInfo"));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(alarmIntent);
} else {
context.startService(alarmIntent);
}
setNextAlarm() is the previous code I provided which sets the alarm for the future task.
EDIT
Ok so I have solved my problem the first is getting my alarm to fire at the exact moment so setExactAndAllowWhileIdle() / setExact() are both kind of exact so if I need to show user something and have to be accurate
I used the setAlarmClock() as the android doc explains
The system may also do some prep-work when it sees that such an alarm
coming up, to reduce the amount of background work that could
happen if this causes the device to fully wake up
The second problem was that the alarm wasn't firing up unless I open the app this was due to the fact that two alarms were firing between the interval of 5 minutes and since I was using setExactAndAllowWhileIdle()
and the android doc explains
Under normal system operation, it will not dispatch these alarms more
than about every minute (at which point every such pending alarm is
dispatched); when in low-power idle modes this duration may be
significantly longer, such as 15 minutes.
And that was it.

Is it possible to set an Android Notification or a later date and time that will fire when the app is not running?

From what I have read it seems that code like this would require the app to be running in a thread until the notification fires. I need the notification to fire at a later date and time so the user sees the notification just like any other notification and then clicks it and it opens of an activity, passing in some data so the app knows what to do.
How can I make this notification fire days later without the app running the whole time?
Do I use wait to accomplish this?
long millis = 60000;
myNotification.wait(millis);
Here is my code which fires immediately
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(getActivity())
.setSmallIcon(R.drawable.star)
.setContentTitle("How was " + me.getString("EventTitle") + "?")
.setContentText("Click here to leave your review");
Intent resultIntent = new Intent(getActivity(), SetupActivity.class);
PendingIntent resultPendingIntent =
PendingIntent.getActivity(
getActivity(),
0,
resultIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
mBuilder.setContentIntent(resultPendingIntent);
int mNotificationId = me.getInt("EventID");
// Gets an instance of the NotificationManager service
NotificationManager mNotifyMgr =
(NotificationManager) getActivity().getSystemService(getActivity().NOTIFICATION_SERVICE);
// Builds the notification and issues it.
mNotifyMgr.notify(mNotificationId, mBuilder.build());
As A--C wrote, use AlarmManager to schedule a PendingIntent to be invoked at your desired time. You will probably use an RTC_WAKEUP alarm, meaning "the time is based on System.currentTimeMillis(), like Calendar uses" and "let's wake up the device out of sleep mode". Use a broadcast PendingIntent, and your Notification code can go into the onReceive() method, if you do not need to do any disk or network I/O to get the information to use for the Notification itself.
Note that in Android 4.4 the rules for AlarmManager changed a bit. You will want to use setExact() on Android 4.4+ and set() on earlier Android versions.

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.

Categories