Reputation: 7592
I'm trying to create my first AppWidget using the AlarmManager class so that I can update more frequently than every 30 minutes. I followed this tutorial as a basis for setting up my widget, but for some reason I cannot get the updates to begin properly. It appears as I am never receiving any APPWIDGET_ENABLED intents, which would fire off the onEnabled event callback in my AppWidgetProvider.
Here is the manifest definition for my AppWidgetProvider:
<receiver
android:name="com.myapp.android.appwidget.MarketTimingAppWidgetProvider"
android:label="@string/appwidget_markettiming_label">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="@string/appwidget_markettiming_updateintent" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/appwidget_markettiming_info" />
</receiver>
Here is the code for my AppWidgetProvider:
public class MarketTimingAppWidgetProvider extends AppWidgetProvider {
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
final int N = appWidgetIds.length;
Log.d("myLogger", "onUpdate");
// Perform this loop procedure for each App Widget that belongs to this provider
for (int i=0; i<N; i++) {
int appWidgetId = appWidgetIds[i];
Log.d("myLogger", "Updating Widget: " + appWidgetId);
updateWidget(context, appWidgetManager, appWidgetId);
}
}
@Override
public void onEnabled(Context context) {
super.onEnabled(context);
Log.d("myLogger", "onEnabled running");
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 1);
alarmManager.setRepeating(AlarmManager.RTC, calendar.getTimeInMillis(),
1000, createClockIntent(context));
}
public void onDisabled(Context context) {
super.onDisabled(context);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(createClockIntent(context));
}
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
Log.d("myLogger", "Intent Received " + intent.getAction());
String widgetIntent = context.getResources().getString(R.string.appwidget_markettiming_updateintent);
// This code fires when my custom intent is received
if(widgetIntent.equals(intent.getAction())) {
ComponentName thisAppWidget = new ComponentName(context.getPackageName(), getClass().getName());
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
int ids[] = appWidgetManager.getAppWidgetIds(thisAppWidget);
for(int appWidgetId: ids) {
updateWidget(context, appWidgetManager, appWidgetId);
}
}
}
private void updateWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget_markettiming);
views.setTextViewText(R.id.widget_text, "Update: " +
DateFormat.getDateTimeInstance(
DateFormat.LONG, DateFormat.LONG).format(new Date()));
// Tell the AppWidgetManager to perform an update on the current app widget
appWidgetManager.updateAppWidget(appWidgetId, views);
}
private PendingIntent createClockIntent(Context context) {
String updateIntent = context.getResources().getString(R.string.appwidget_markettiming_updateintent);
Log.d("myLogger", "my intent: " + updateIntent);
Intent intent = new Intent(updateIntent);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
return pendingIntent;
}
}
When I look in LogCat the only intent that is ever recieved by my onReceive method is the initial APPWIDGET_UPDATE intent, and the only callback ever executed is the onUpdate callback. I've tried including the APPWIDGET_ENABLED intent in my appwidget intent-filter (although the docs tell me that this should be automatically received by my widget). It didn't work. Is there just something I'm missing here?
Upvotes: 0
Views: 2413
Reputation: 3029
There is an error in your manifest. Action name in this element:
<action android:name="@string/appwidget_markettiming_updateintent" />
should be replaced by actual string, not the reference. So it should be something like this:
<action android:name="com.myapp.android.appwidget.action.MARKETTIMING_UPDATE" />
or whatever you have in your values/something.xml inside the <string name="appwidget_markettiming_updateintent">
element.
The problem is that the BroadcastReceiver does not receives the broadcasts from AlarmManager. I've created a project with your code, replaced only this string in manifest (and added the appropriate value to values/strings.xml of course) and all works fine.
In addition, you may want to replace the second parameter of alarmManager.setRepeating()
by just System.currentTimeMillis() + 1000
and remove all those extra Calendar-related stuff.
Upvotes: 2
Reputation: 7592
Apparently uninstalling it from the emulator and then re-installing it did the trick. Now when I add a widget the APPWIDGET_ENABLE intent is received, and when I remove it the APPWIDGET_DISABLED intent is fired like I would expect. I'm still having an issue where the alarm manager does not actually fire off my custom Intent like I expect, but that's a separate issue I'll need to research.
Upvotes: 0