So here’s the thing. I wanted my widget to run a task every 12 midnight. The attribute of Intent.ACTION_DATE_CHANGED does not work.
I had read posts in forums that say if you switch back and forth setting the date and time for experimentation to see if the task will run, nothing happens. So the only workaround left is to use an AlarmManager.
Yup, you have to use it rather than being forced to use Intent.ACTION_TIME_TICK which is battery draining as this event will occur every minute.
To set up your AlarmManager to send a broadcast every 12 midnight, do this:
Take note that you have to use getBroadcast() in the PendingIntent class if you want the task in the BroadcastReceiver to be executed. If it is code in a service that you want to run, then call getService().
This was a pain to find out. While my Android widget was working okay considering that I only set it to have only 1 size, it took me a very long time to find out that the same PendingIntent object is used by the Android system when certain attributes are created the same way e.g. class, action, request code.
The quickest and easiest solution is to use the appWidgetId as the value of the request code in the PendingIntent parameter when you either call the getActivity(), getBroadcast() or getService() methods.
That should make it unique in such a way that the PendingIntent object will be used only for that certain widget no matter which size or which instance it is.
Other options would be to give different values for its setData() and setAction() methods like adding a System.currentTimeMillis() but sometimes we may want our action value to be fixed so the best option in my opinion is to focus on the request code value having a unique value.
That should give make your multiple widget instances work.
And the answer is … you cannot. When Android wants to free up memory to cater other applications and/or services, the schedules in an AlarmManager also gets removed.
So your app or widget scheduled to run at some point may not run at all because the schedule is gone. From my experiencewhen I was still in the development process of my widget, the only possible way I made the same schedule running again in the AlarmManager was to take advantage of the updatePeriodMillis attribute in the XML file of the app widget provider file.
Since the minimum that the app widget provider updates the widget is 30 minutes, this was where I placed my code to add the same schedule to the AlarmManager.
Do not worry if you keep adding it because if there is an existing PendingIntent object in the AlarmManager, it will cancel it and replace it with the new one.
Reading through all forum posts that I came across, I may have to agree that there is no way to make it persistent as there may be a chance that users will uninstall your app if they find something in their phone that keeps on running even when they manually exited it (e.g. Service).