I am trying to update a Widget more frequently than the 30 minute restriction imposed by the 1.6docs. After reading nearly every post in SO, and the developer docs, and various other sources, I thought I had got to a point where i could implement it. And so, I tried, and failed. Since then, I have trawled yet more forums and solutions, and I cannot seem to get it to update.
I have an Update class that sets the AlarmManager:
public class Update extends Service{
@Override
public void onStart(Intent intent, int startId) {
String currentTemp = Battery.outputTemp;
String currentLevel = Battery.outputLevel;
String currentCard = Battery.outputCard;
String currentInternal = Battery.memory;
String currentRam = String.valueOf(Battery.outputRam).substring(0, 3) + "MB";
// Change the text in the widget
RemoteViews updateViews = new RemoteViews(
this.getPackageName(), R.layout.main);
//update temp
updateViews.setTextViewText(R.id.batteryTemp, currentTemp);
//update %
updateViews.setTextViewText(R.id.batteryLevel, currentLevel);
//update level
updateViews.setTextViewText(R.id.sdCard, currentCard);
//update internal memory
updateViews.setTextViewText(R.id.internal, currentInternal);
//update ram
updateViews.setTextViewText(R.id.ram, currentRam);
ComponentName thisWidget = new ComponentName(this, Widget.class);
AppWidgetManager manager = AppWidgetManager.getInstance(this);
manager.updateAppWidget(thisWidget, updateViews);
}
@Override
public IBinder onBind(Intent intent) {
// no need to bind
return null;
}
}
This has caused my onReceive in my widget class to fire frequently (i have a toast to see when it fires), yet it carries no intent (the toast is meant to display this as they are received but it is blank).
I cannot figure it out (i'm a relative newb-2 months of slow android dev), and appreciate any insight you guys have.
heres my widget class for reference:
public class Widget extends AppWidgetProvider {
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
AlarmManager alarmManager;
Intent intent = new Intent(context, Update.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(System.currentTimeMillis());
cal.add(Calendar.SECOND, 10);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, cal
.getTimeInMillis(), 5 * 1000, pendingIntent);
String currentTemp = Battery.outputTemp;
String currentLevel = Battery.outputLevel;
String currentCard = Battery.outputCard;
String currentInternal = Battery.memory;
String currentRam = String.valueOf(Battery.outputRam).substring(0, 3)
+ "MB";
// Change the text in the widget
RemoteViews updateViews = new RemoteViews(context.getPackageName(),
R.layout.main);
// update temp
updateViews.setTextViewText(R.id.batteryTemp, currentTemp);
appWidgetManager.updateAppWidget(appWidgetIds, updateViews);
// update %
updateViews.setTextViewText(R.id.batteryLevel, currentLevel);
appWidgetManager.updateAppWidget(appWidgetIds, updateViews);
// update level
updateViews.setTextViewText(R.id.sdCard, currentCard);
appWidgetManager.updateAppWidget(appWidgetIds, updateViews);
// update internal memory
updateViews.setTextViewText(R.id.internal, currentInternal);
appWidgetManager.updateAppWidget(appWidgetIds, updateViews);
// update ram
updateViews.setTextViewText(R.id.ram, currentRam);
appWidgetManager.updateAppWidget(appWidgetIds, updateViews);
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
Toast
.makeText(context, intent.getAction() + context,
Toast.LENGTH_LONG).show();
Bundle extras = intent.getExtras();
if (extras != null) {
AppWidgetManager appWidgetManager = AppWidgetManager
.getInstance(context);
ComponentName thisAppWidget = new ComponentName(context
.getPackageName(), Widget.class.getName());
int[] appWidgetIds = appWidgetManager
.getAppWidgetIds(thisAppWidget);
onUpdate(context, appWidgetManager, appWidgetIds);
}
}
}
I have an Update class that sets the AlarmManager:
No, you don't. AlarmManager
appears nowhere in the code snippet.
You do have a reference to AlarmManager
in the second code snippet. Problems there include:
You are setting a new repeating alarm every time the app widget updates
You are setting a 5 second frequency on the alarm, which is utter insanity
You are setting a 5 second frequency on a _WAKEUP
alarm, which I think is grounds for your arrest in some jurisdictions
You have a pointless onReceive()
method, even ignoring the temporary Toast
You are assuming that there will be an action string on the Intent
in your Toast
, but you do not specify an action string when you create the Intent
that you put in the PendingIntent
for the alarm
Your code refers to what I presume are static data members on a Battery
class, but it is rather likely those are all empty/null... or at least they would be, if you had a sane frequency on the alarm
This is my solution, how to automatically update widget more frequently than the 30 minutes. I use AlarmManager. Before you use AlarmManager for refreshing appwidget, make sure you know what you do, because this technique could drain the device's battery.
Read more about widget update in Android doc - especially about updatePeriodMillis parameter.
This is part of my Manifest.xml. I define custom action AUTO_UPDATE.
<receiver android:name=".appwidget.AppWidget" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<intent-filter>
<action android:name="AUTO_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider" android:resource="@xml/appwidget_info" />
</receiver>
This is part of my AppWidget.java. In onReceive method, I handle my custom action AUTO_UPDATE. In onEnabled and onDisabled methods, I start/stop alarm.
public class AppWidget extends AppWidgetProvider
{
public static final String ACTION_AUTO_UPDATE = "AUTO_UPDATE";
@Override
public void onReceive(Context context, Intent intent)
{
super.onReceive(context, intent);
if(intent.getAction().equals(ACTION_AUTO_UPDATE))
{
// DO SOMETHING
}
...
}
@Override
public void onEnabled(Context context)
{
// start alarm
AppWidgetAlarm appWidgetAlarm = new AppWidgetAlarm(context.getApplicationContext());
appWidgetAlarm.startAlarm();
}
@Override
public void onDisabled(Context context)
{
// stop alarm only if all widgets have been disabled
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
ComponentName thisAppWidgetComponentName = new ComponentName(context.getPackageName(),getClass().getName());
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(thisAppWidgetComponentName);
if (appWidgetIds.length == 0) {
// stop alarm
AppWidgetAlarm appWidgetAlarm = new AppWidgetAlarm(context.getApplicationContext());
appWidgetAlarm.stopAlarm();
}
}
...
}
This is my AppWidgetAlarm.java, which starts/stops alarm. Alarm manager sends broadcast to AppWidget.
public class AppWidgetAlarm
{
private final int ALARM_ID = 0;
private final int INTERVAL_MILLIS = 10000;
private Context mContext;
public AppWidgetAlarm(Context context)
{
mContext = context;
}
public void startAlarm()
{
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.MILLISECOND, INTERVAL_MILLIS);
Intent alarmIntent=new Intent(mContext, AppWidget.class);
alarmIntent.setAction(AppWidget.ACTION_AUTO_UPDATE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, ALARM_ID, alarmIntent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
// RTC does not wake the device up
alarmManager.setRepeating(AlarmManager.RTC, calendar.getTimeInMillis(), INTERVAL_MILLIS, pendingIntent);
}
public void stopAlarm()
{
Intent alarmIntent = new Intent(AppWidget.ACTION_AUTO_UPDATE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, ALARM_ID, alarmIntent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With