I'm using an Alarm Manager to trigger an IntentService every hour. However, originally the alarm gets registered when the user runs the app. The problem is that when the user opens the app again it makes the manager create a new service run and if the current service is already running they trip over each other because of the database connection and everything dies!
Another problem is that the alarm service completely stops. Why? I thought the alarm should go on every hour no matter what!
at the very beginning check for a existing database . if it doesn't exist. make a database and start the alarm.
the next time the app start if it found a database it will not start the alarm again. or use any saved value like we use semaphores check for value 0 or 1.. rest functionality of a Alarm manager is supposed to work properly
Related
I have an app for creating and reminding routine tasks that uses sqlite database locally.
I want when a task reaches its time remind the user with a push notification.
I worked on a service to check the database if the data & time of the task matches the data & time of the device shows a push notification.
first I decided to uses Job scheduler. but the minimum time for checking the database is 15 minutes.
then I tried Alarm manager for checking the database every one minute. but it seemed a bad idea because of the load of work.
then I read about Content Observer and found out it doesn't tell the exact new data which doesn't work for me.
what should I do? Is there another way or should I stick with Alarm Manager?
Instead of setting a repeating alarm on an interval that checks the database, could you set one exact alarm when the task is scheduled? It executes just when the task is due. And upon a reboot, when your app receives the boot complete intent, it iterates through the database setting all the required one-time alarms?
I am developing an app that connects to and modifies data in a database by executing php files.
If I need to make changes to the database or php files, this may cause old versions of the app to behave unexpectedly and crash. For this reason, I want to force users to update the app when such changes are made.
Right now, I have a method that connects to the database and compares the apps version to the databases version. This works fine but I call it every time I access the database (very often) which significantly slows down the usage of the app. Is there a better way to do this? I have read that I could use an AlarmManager or BroadcastReceiver to check for updates every X amount of hours. But what if the user closes and doesn't use the app for a few days. Will these timers get called as soon as the user starts the app and thus be able to force an update?
The Android AlarmManager is an API that let you communicate and program alarm with the Android Alarm Service. Think of it as similar to a Linux Cron job. As soon as the alarm is programmed, then it'll be triggered even if your app isn't running, because the alarm is triggered by the alarm service and not by your app. For instance, the only thing you need to do is to program your alarm. It's important to note that when you restart your device then your alarms are cleared, so you need to reprogram then in every reboot. You can do this by capturing the BOOT_COMPLETED broadcast, so you can reprogram your alarm every time the device boots up. Check out the definition of the Android AlarmManager. A common pattern to do what you want is to program an alarm that sends a broadcast or starts a service, then in that service you can query your server. You need to consider that when the device is sleeping then the alarms couldn't be sent, so you need to work with wakelocks. This class will help you with that, check it out.
In my app, I have an alarm set that when run, launches a service that will perform a task (in my app, it is sending a text message without user interaction). This message can be set for 2 hours in the future, or a year in the future. Here is how I implement it.
In my main activity
user types message, choses a date and time (translated to milliseconds), and that alarm time (the milliseconds), is saved persistently. I then call a service, which i have set to be sticky, and boot on startup.
In my service.
When the service gets called (Which after the first time you schedule a message, it is now running, all the time), it creates the alarm with the saved alarm time. This is good, because if the phone reboots, the alarm will get recreated again.
Here is the problem
After the alarm time has passed, and the message is successfully sent, I don't see a way to shut down that service from always running. So as soon as the service gets killed and restarted (like when the phone reboots), it launches, sees the alarm time is in the past, and immediately launches the service that sends the message. So until I clear data on the app, I get random duplicate messages sent out, at random future times.
My solution (not elegant).
After the message sends the first time, i add 50 years (in milliseconds), to the alarm time, and resave it persistently. This way it won't trigger again until the user actually sets the time themselves. This seems to have worked, but IMO is a terrible solution.
There has to be a more proper way of setting a persistent alarm to only run once. Can someone who has more experience with AlarmManager advise me?
You can register an BroadcastReciever onBooted to start the Alarm again - but you definitly need to save the alarm-time in sharedpreferences or an sqlite database...
went through the same sooner
You'd be better off doing something like using an AlarmManager to deliver a PendingIntent at your set time which starts an IntentService that delivers your message and terminates when the message is sent. You'd reset the AlarmManager with the PendingIntent in your BroadcastReceiver that listens for BOOT_COMPLETED. It's not good to have your service running all the time, and it might get killed (and making it a foreground service to make it less likely to be killed would be wasteful of resources).
When the service gets called (Which after the first time you schedule a message, it is now running, all the time)
Please do not waste the user's memory by having a service running that is not doing anything but watching the clock tick.
it creates the alarm with the saved alarm time
I am assuming, from context, that "creates the alarm" means "schedules an event with AlarmManager". If you are using AlarmManager, there is no reason to have a service that is "always running".
I don't see a way to shut down that service from always running
It should not have been "always running" in the first place. That being said, to stop a service, a service can call stopSelf().
So as soon as the service gets killed and restarted (like when the phone reboots), it launches, sees the alarm time is in the past, and immediately launches the service that sends the message
Mark the message as having been sent in whatever persistent store that you are using for the rest of this.
After the message sends the first time, i add 50 years (in milliseconds), to the alarm time, and resave it persistently. This way it won't trigger again until the user actually sets the time themselves. This seems to have worked, but IMO is a terrible solution.
You are welcome to use a hasBeenDelivered boolean or the equivalent. Or, depending on your data structure, delete the entry entirely. Regardless, your persistent data model needs to reflect the sent/not-sent status of the message, however you choose to do it.
is there any way to stop an alarm at a given time, for example, i started an alarm on 7:45am and it repeats every 5 minutes and then, i wanted to stop that alarm when the time is already 8:00am?
How do i go about this algorithm since alarm manager's cancel() method only accepts an action (PendingIntent)
and Secondly, regarding services, i have an idea to put a checker or an if statement on service to check if its already 8:00a, but im not sure if service always run in the background and if so, does that mean to say that it always checks the time if its 8am? given that meaning of services that once it started i won't stop unless explicitly told to do so.
any of you guys know any way to do this please do share, im kinda confused right now
you will have to start the service when alarm start first time and this service will ring the alarm at 5 min and get the device time and compare it with the time to stop the time
at that (means at 8 AM )stop your service
Why dont you start whatever you need to do at 7:45am with AlarmManager#setRepeating and set another alarm with AlarmManager#set to stop the previous?
AlarmManager#set will be fired off just once, so you can use it cancel the repeating alarm
Edit:
In the implementation of AlarmManager#set, you would retrieve the repeating alarm(AlarmManager#setRepeating) and cancel() it
Is there a way to send a notification to the user that app has been downloaded but a certain task from the app is not yet complete even after certain period - say a month. One way is a background service which should come alive every month in this case, check the app state (in sharedprefs) and then send a notification. Is there some other easier way in Android without writing custom service.
Here's how I would do it. Schedule an alarm using the AlarmManager to go off a month from today. That alarm can trigger some code inside of a Receiver or otherwise to check whether the said event has occured. If it hasn't, you can then show a Dialog or whatever.
In order to wake up your app after some amount of time (in your example a month) you're going to have to set an alarm. You can use AlarmManager for that. If all you're going to do is check SharedPreferences, you can do that in a broadcast receiver. You can send your notification there.