I've followed the tutorial on widget at http://developer.android.com/guide/topics/appwidgets/index.html, and I also know how to create an AlarmManager to update the widget. What I'm wondering is how to effectively turn off the default onUpdate(). According to the guide lines (at that link), when I use AlarmManager I should set updatePeriodMillis to zero. But onUpdate() keeps being called (because 0 always lapses). If I set it to, say, 30 mins, it updates at that period. So practically it keeps using the value in updatePeriodMillis , which nullifies the effect of using AlarmManager. Am I missing anything?
Update: actually there's another code that triggers the update on another event, so never mind.
Cheers.
Related
I am trying to write to a file whenever the user has not interacted with the application for 2 minutes. Currently am having base activity in which I have overriden the onUserInteraction method. In this method the float time variable is reset and onResume I subtract the time with the current time to check if two minutes have passed. This works fine but sometimes acts crazy. Second approach was using the postDelayed method of the Handler and start a thread. This works perfectly but does not include the case when the app goes to background or the device goes to sleep.Is there a way to cover all these cases. ahve researched a lot. Also came across Wakeful Intent service but read that it is expensive.
Is there a way to cover all these cases.
Yes. ... and it is expensive. Waking the phone up, every 2 minutes is going to drain the battery like crazy.
That said, the answer to your question is that you need to use the AlarmManager, probably in concert with either the WakefulIntentService or the WakefulBroadcastReceiver. Create a PendingIntent and schedule it for delivery every 2 minutes.
I don't know a way of tracking inactivity but there is a way to track user activity. You can catch a callback called onUserInteraction() in your activities that is called every time the user does any interaction with the application. I'd suggest doing something like this:
#Override
public void onUserInteraction(){
MyTimerClass.getInstance().resetTimer();
}
If your app contains several activities, why not put this method in an abstract super class (extending Activity) and then have all you activities extending it.
I have an app which will give the user a bonus power up every 45 minutes. I managed to set a repeating alarm to do it but I have some questions:
1 - Where should I call setRepeating() method? - Having in mind that the alarm should be set automatically and NOT by an onClick event, for instance, I find it tricky to know where to set it. Now I am calling it on the onCreate method of my MainMenu activity. The problem is that everytime he user enters the app it is called. I thought about setting a SharedPreference variable to check if I already called it but it doesn't seem the right approach.
2 - How to the display the time left until next power up? - I would like to display to the user how much time is left until the next power up. The problem is that if the user closes the app and open it again I no longer have a reference to the alarm but it is still running. How can I do that?
Any help will be appreciated. Thanks in advance
I'd use shared preferences for both. When you set the alarm, write a shared preference that says when the next alarm is scheduled for. In onCreate, look at the alarm. If its in the future, no need to set it. If its in the past, set it again. The same answer solves problem 2- subtract the current time from the time in the shared preference, and that's the time left. When the alarm goes off, update the shared preference to the next time.
I am a newbie in Android development and I am faced with a problem which I can't figure out. I am following this link. It is a simple widget which has a listView which shows harcoded feed.
I wanted to make the widget interactive. So I came up with a solution as follows: I created a Intent, associated with it a Action and Broadcasted it with PendingIntent. Now I tried to catch that Intent in the onReceive() function of the WidgetProvider.java class.
I thought this approach is great except the fact that onUpdate function is called every 30 minutes. I am not sure even if it works after 30 minutes, haven't tried it. So I can't figure out how do I achieve this.
Basically I wanted to make it into widget, on which if clicked, it launches another activity. And can you also tell when is the onReceive function of the AppWidgetProvider called.
My Android app has a TextView telling the user the data age ("13 minute ago"). I currently update this every second using a Runnable to catch when the minute changes with a notifyDataSetChanged() to my adapter. But this is causing garbage collection every second...
Is there another method to trigger a TextView update (or take general action) when the system clock changes minute without checking every second for such a change?
Since you already set up a Runnable and callback, use modulo to calculate when the next update should happen:
handler.postDelayed(runnable,
DateUtils.MINUTE_IN_MILLIS - System.currentTimeMillis % DateUtils.MINUTE_IN_MILLIS);
This will run the callback when the next minute occurs whether it is 59, 30, or 1 second(s) away. As a note, if the Runnable only updates one TextView don;t forget to switch to DateUtils.HOUR_IN_MILLIS when the event is an hour old, no sense updating "1 hour ago" every minute.
You may find methods like DateUtils.getRelativeTimeSpanString() useful for creating the "x minutes ago" strings.
While Sam's answer is perfectly good, I'm just adding this because it fits the question so perfectly. There is actually a broadcast sent by the system every minute when the clock changes. It is Intent.ACTION_TIME_TICK and you can only receive it using a BroadCastReceiver that was registered manually in your code, not through the manifest. See the documentation here.
User the Timer object with fixed period.
The methods take a TimerTask object.
See the Timer documentation from google
REMEMEBER to cancel the timer when stopping the activity
There is prettier solution for this besides Sam's great answer.
Make use of http://developer.android.com/reference/android/text/format/DateUtils.html to find the time span and register for android.intent.action.TIME_TICK where you'll be updating the time in the listview.
Here is another same question and answer
I am developing an appwidget that uses the RemoteViews to display a ListView. For simplicity's sake, I will give an analogy of the appwidget's functionality:
The user will select to add the appwidget to the home screen. Upon selecting the widget, a configuration activity is launched and the user selects from one recipe from a list of recipes.
Upon selecting the recipe from the configuration activity, the configuration activity broadcasts the AppWidgetManager.ACTION_APPWIDGET_UPDATE intent. This intent received and handled in the onReceive method of my AppWidgetProvider class. From here the RemoteView is instantiated and passed into the AppWidgetManager.updateAppWidget() method. This proceeds to fill in the ListView of ingredients.
This all works as expected, except when I attempt to manually update the ListView from the appwidget. I have set a PendingIntent to re-launch the configuration activity, which also works. Unfortunately, the call to AppWidgetManager.updateAppWidget() does not get called instantly as it did when being launched upon adding it to the home screen and the ListView does not get updated. The update does get called, however, after scrolling down the list a ways (until it gets passed the number of rows it has loaded in its cache, I reckon). This fires off my FlightBoardAppWidgetService and ViewsFactory as it should. It is almost as if the updateAppWidget is getting put into some lazily-loaded queue. I tried to look at the Android source code to see how AppWidgetManager.updateAppWidget() is coded, but it appears to be hidden.
tl;dr: AppWidgetManager.updateAppWidget() does not always get called instantly, what gives?
Is there any way to get the ListView to update when it is actually called? What am I doing wrong? Thanks!
Well, I ended up solving the problem finally. It is somewhat of a hack, but I ended up solving the problem by declaring a refresh broadcast and an update broadcast. Each time I want to update the widget I call updateAppWidget(), and then from the function that receives and handles this broadcast, I launch another broadcast that calls notifyChanged. This works all of the time!