Android AlarmManager not working when set for longer time [closed] - android

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
In my app I have tried to set an alarm using this code:
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, 2016);
calendar.set(Calendar.MONTH, 1);
calendar.set(Calendar.DAY_OF_MONTH, 1);
calendar.set(Calendar.HOUR_OF_DAY, 15);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 1);
calendar.set(Calendar.MILLISECOND, 1);
Intent intent = new Intent(G.context, AlarmService.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext, 1010, intent, PendingIntent.FLAG_UPDATE_CURRENT);
G.alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
It works when I set the alarm for 1 minute or later, but not when I set the alarm for 30 or 40 minutes later. While I am not on the phone for 30 minutes, after 30 minutes the alarm did not work, and when the phone screen is on the alarm worked...
Any help would be appreciated.

Ok that's because after a long time (let's say more than 5 min) your app is Paused and then the phone is "asleep" with lock screen. When you unlock it then you get your Alarm because it was queued.
To solve this problem, you need to implement a Wake Lock and add it's permission to your manifest file.
According to Google Documentation "A wake lock is a mechanism to indicate that your application needs to have the device stay on."
This is the line you have to add in your manifest:
<uses-permission android:name="android.permission.WAKE_LOCK" />
You'll need to implement this object in your onReceive() method in your BroadcastReceiver. You can follow this tutorial that makes use of all you need.
https://www.javacodegeeks.com/2012/09/android-alarmmanager-tutorial.html
Also, note that you'll keep the device "awake" therefore you'll keep the phone processing affecting the battery life, but still you get to be able to get the alarm even if the screen is locked.
Hope it helps!

Since API 19 set() is treated as inexact and may be delayed. If you really need a precise alarm, you should use setExact() (available since API 19) instead :
Note: Beginning in API 19, the trigger time passed to this method is
treated as inexact: the alarm will not be delivered before this time,
but may be deferred and delivered some time later. The OS will use
this policy in order to "batch" alarms together across the entire
system, minimizing the number of times the device needs to "wake up"
and minimizing battery use. In general, alarms scheduled in the near
future will not be deferred as long as alarms scheduled far in the
future.
This change happen on 19+ device (obviously) but also only if the APK's target API is 19+, so you can
change the target API to 18
or use Build.VERSION.SDK_INT to know which method to use.
Additionnaly when you use a *_WAKE_UP alarm, the alarm manager garantees that the device will be awake long enough to execute the receiver's method, but not the service it may launch :
The Alarm Manager holds a CPU wake lock as long as the alarm
receiver's onReceive() method is executing. This guarantees that the
phone will not sleep until you have finished handling the broadcast.
Once onReceive() returns, the Alarm Manager releases this wake lock.
This means that the phone will in some cases sleep as soon as your
onReceive() method completes. If your alarm receiver called
Context.startService(), it is possible that the phone will sleep
before the requested service is launched.
The support v4 library provides a usefull helper class to handle this case : WakefulBroadcastReceiver
In you case, as you are using a service pending intent, I am not sure what wake garanties apply.

i use service
public class AlarmService extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onStart(Intent intent, int startid) {
//This is my Code and set Alarm
stopSelf();
}
}

Related

Periodic call in android every 90 seconds, even when app is closed

The requirement is to record the position every 90 seconds and write it to database(sqlite) and if network is available then call an api, even if the app is closed.
Which will be the best possible way to achieve this?
Should I start an intent service? Or I should go with an alarm Manager. I have read somewhere that alarm manager should only be used if the duration is more than 10 minutes.
I suggest to use AlarmManager since it can be run even Device is asleep.
Note that, for API v > 19, the alarm delivery is inexact and you have to use setExact api to achieve that .
See
Note: Beginning in API 19, the trigger time passed to this method is treated as inexact: the alarm will not be delivered before this time, but may be deferred and delivered some time later. The OS will use this policy in order to "batch" alarms together across the entire system, minimizing the number of times the device needs to "wake up" and minimizing battery use. In general, alarms scheduled in the near future will not be deferred as long as alarms scheduled far in the future.
With the new batching policy, delivery ordering guarantees are not as strong as they were previously. If the application sets multiple alarms, it is possible that these alarms' actual delivery ordering may not match the order of their requested delivery times. If your application has strong ordering requirements there are other APIs that you can use to get the necessary behavior; see setWindow(int, long, long, PendingIntent) and setExact(int, long, PendingIntent).
Alarm Manager would be the ideal choice for your situation. Registered alarms are retained while the device is asleep, but will be cleared if it is turned off and rebooted.
So, you can use this to run your job in 90 seconds interval. It may break the interval only first time after the device is rebooted.
Another way I found out was using the Firebase job dispatcher. That is the best option for devices running on marshmallow or further. It is easy to integrate and customizable.
https://github.com/firebase/firebase-jobdispatcher-android
A Service is an application component that can perform long-running
operations in the background and does not provide a user interface.
https://developer.android.com/guide/components/services.html
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.
The Alarm Manager holds a CPU wake lock as long as the alarm
receiver's onReceive() method is executing. This guarantees that the
phone will not sleep until you have finished handling the broadcast.
https://developer.android.com/reference/android/app/AlarmManager.html
Go with the service.
You go with Intent service and Broadcastreceiver componenst, because those components only listen continuously, even if you close the Application.
And you want to get something evry 90 seconds, so use Alarm Manager.
AlarmManager manager = (AlarmManager) (context)
.getSystemService(Context.ALARM_SERVICE);
Intent alarmIntent = new Intent(context, YourAlarmReceuver.class);
//alarmIntent.putExtra("syncData", favoritesArrayList);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,
alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
manager.setInexactRepeating(AlarmManager.RTC_WAKEUP,
System.currentTimeMillis(), 90*1000, pendingIntent);
Your Receiver class Like this
public class SyncAlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent stIntent = new Intent(context,
YourService.class);
context.startService(stIntent);
}
And Your Intent Service Class like this
public class DataSyncService extends IntentService {
public DataSyncService() {
super(DataSyncService.class.getName());
// TODO Auto-generated constructor stub
}
#Override
protected void onHandleIntent(Intent intent) {
//write your logic here
// get the location and update the database
}
}
You should instantiate the alarm manager boot completed also.

Android Alarm manager working, but delayed

I would like to make a delay(10 min) for user then after it, user can edit something.
to do this,I created a setAlarm function :
public void setAlarm(Context context,int user,int time) {
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, sef_time.class);
intent.putExtra(ONE_TIME, Boolean.FALSE);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
am.set(AlarmManager.RTC, 1000*60*time , pi);
}
everything works fine, but my alarm manager has a delay.
for example:
setAlarm(.....,int 10);
It has a delay : 00:10:03 second or 00:10:10 second 00:10:20 second !
where is my wrong ?
As you can see here:
Beginning in API 19, the trigger time passed to this method is treated
as inexact: the alarm will not be delivered before this time, but may
be deferred and delivered some time later. The OS will use this policy
in order to "batch" alarms together across the entire system,
minimizing the number of times the device needs to "wake up" and
minimizing battery use. In general, alarms scheduled in the near
future will not be deferred as long as alarms scheduled far in the
future.
With the new batching policy, delivery ordering guarantees are not as
strong as they were previously. If the application sets multiple
alarms, it is possible that these alarms' actual delivery ordering may
not match the order of their requested delivery times. If your
application has strong ordering requirements there are other APIs that
you can use to get the necessary behavior; see setWindow(int, long,
long, PendingIntent) and setExact(int, long, PendingIntent).
Applications whose targetSdkVersion is before API 19 will continue to
get the previous alarm behavior: all of their scheduled alarms will be
treated as exact.
If it's very important that the alarm be exact, use setExact (When the device's SDK is 19 or above).
The easiest way to make system have a delay and then sound an alarm at the exact specified time is using setExact(), and the code can be something like this.
am.setExact(AlarmManager.RTC_WAKEUP,System.currentTimeMillis() + (time_you_want_to_delay_in_milliseconds) ,pi);

Why is AlarmManager alarm delayed on first run?

Recently, in my timer app, running the timer for the first time causes it to fire an alarm approximately two or three seconds after it should. The strange this is, it only does this the first time I run the timer after installing the app via Android Studio. Every time after that, it runs as expected and the timer goes off after the expected time.
Here is the relevant code:
if(LOG) Log.v(TAG,"Starting the timer service: "+ TimerUtils.time2humanStr(context, mTime));
Intent intent = new Intent( this, TimerReceiver.class);
mPendingIntent = PendingIntent.getBroadcast( this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
mAlarmMgr.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + mTime, mPendingIntent);
The variable mTime is set properly each time, according to the logcat output:
Starting the timer service: 5 seconds
And it works fine every time after the initial run. It was working fine before; could it be a problem with Android or Android Studio? Or am I needing to initialize something? I know I can't expect precise answers without dumping all my code here, I'm just looking for hints (speculation?) as to why this behaviour might be occurring.
Are you using API 19? Check out this note in the documentation:
Note: Beginning in API 19, the trigger time passed to this method is
treated as inexact: the alarm will not be delivered before this time,
but may be deferred and delivered some time later. The OS will use
this policy in order to "batch" alarms together across the entire
system, minimizing the number of times the device needs to "wake up"
and minimizing battery use. In general, alarms scheduled in the near
future will not be deferred as long as alarms scheduled far in the
future.
Source: AlarmManager

Will AlarmManager work if my application is not running?

I have an alarm that works fine if i am interacting(using) with my application but it dose not works if I set it for next day and not interacting with my app.Therefore I am getting doubt is this because my application process is not running at that time.
here is what I am doing
Calendar calSet = Calendar.getInstance();
calSet.set(Calendar.HOUR_OF_DAY, selectedhour);
calSet.set(Calendar.MINUTE, selectedminute);
calSet.set(Calendar.YEAR, year);
calSet.set(Calendar.MONTH, monthOfYear);
calSet.set(Calendar.DATE, dayOfMonth);
alarm = new Intent(ActivityA.this, Service.class);
pendingIntent = PendingIntent.getService(getApplicationContext(), i++,alarm, 1);
alarmanager.set(AlarmManager.RTC_WAKEUP, calSet.getTimeInMillis(),pendingIntent);
From AlarmManager
AlarmManager provides access to the system alarm services. 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.
In simple way, it will work until your device has been rebooted.
You can read Android AlarmManager after reboot where #CommonsWare has been given a link of his sample application which persists Alarm even after device reboot.
Please ignore below section, it seems not valid. I will remove in future
You can read more about application kill at How to create a persistent AlarmManager, and How to save Alarm after app killing? can give you the idea about how to handle such issue (to persist alarm if application has been killed).
Yes it worked but proper understanding see doc.
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 here http://developer.android.com/reference/android/app/AlarmManager.html
Looking at the AlarmManager documentation..
http://developer.android.com/reference/android/app/AlarmManager.html
I don't see anywhere where it states that killing your app will remove all alarms that have been scheduled by that app. More specifically it states if your app is not started, it will start it for you.
I have done my own testing and can validate this by..
Setting an alarm 5 sec in the future.
Then closing app from recents.
Then watching logs for my broadcast to be received.
Keeping in mind this was done with a signed apk.
Calendar cal = Calendar.getInstance();
cal.add(Calendar.MILLISECOND, 5000);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
I would also keep in mind what Pankaj Kumar said about the restarting alarms on boot. That is the one place you need to cover yourself, because AlarmManager does clear all alarms on device restart.
We need to enable our app in autostart manager in app manager, some handsets like Vivo v5,
In Vivo v5, we can find out this menu in
iManager > App Manager > Auto Start Manager > Enable our app here.
Then your alarm / alarm manager will trigger alarm if the app is killed or closed.

How to set alarm when phone boot up in android?

I have a alarm function in my application. Alarm will work fine when the phone is ON. Problem is when i switch off or power off the phone(for example i will set alarm for 10.00AM, 10.05, 10.10) and i will switch on by 10.02. I am not getting any alarm notifications and all the alarms are cancelled. I have used Service for getting the alarm and i used permission reciever_boot_complete also. Still i am getting problem. please anybody help me.
1.As far as I know, Android system doesn't support alarms when the power is off. If you set an alarm and turn the phone off, the phone won't boot up when the alarm time comes.
2.When using AlarmManager to schedule an alarm, take care of the alram type in methods:
public void set (int type, long triggerAtTime, PendingIntent operation)
public void setRepeating (int type, long triggerAtTime, long interval, PendingIntent operation)
You should use ELAPSED_REALTIME_WAKEUPorRTC_WAKEUP, otherwise, when the screen is off, the alarm won't be triggered.
See here:

Categories

Resources