Based on this tutorial I created a widget that should show the time. The java way works, but the service way doesn't.
HelloWidget.java:
public class HelloWidget extends AppWidgetProvider {
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
Intent intent = new Intent(context, UpdateService.class);
context.startService(intent);
}
}
UpdateService.java:
public final class UpdateService extends Service {
@Override
public void onStart(Intent intent, int startId) {
RemoteViews updateViews = new RemoteViews(this.getPackageName(), R.layout.main);
Date date = new Date();
java.text.DateFormat format = SimpleDateFormat.getTimeInstance(
SimpleDateFormat.MEDIUM, Locale.getDefault());
updateViews.setTextViewText(R.id.widget_textview, "Current Time " + format.format(date));
ComponentName thisWidget = new ComponentName(this, HelloWidget.class);
AppWidgetManager manager = AppWidgetManager.getInstance(this);
manager.updateAppWidget(thisWidget, updateViews);
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
The hello_widget_provider.xml has this row: android:updatePeriodMillis="1000"
Problem:
The widget shows the current time but it's not updating (the java-way is).
My main goal is to update the widget at e.g. 18:56 every day. Idk if this is the good way, but i tried to modify the onUpdate method like below, but it has a problem with ALARM_SERVICE: ALARM_SERVICE cannot be resolved to a variable
public class HelloWidget extends AppWidgetProvider {
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
AlarmManager alarmManager;
Intent intent = new Intent(context, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 18);
cal.set(Calendar.MINUTE, 56);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 86400, pendingIntent);
}
}
Any help is appreciated.
Full update: Call AppWidgetManager. updateAppWidget(int, android. widget. RemoteViews) to fully update the widget.
Widgets are now in the Apps list. Open your app drawer and you'll see them. Some of the apps may not have ICS compatible apps. Just check for updates for your apps and see if that resolves it.
Looking back the time I asked this question makes me realize how much I learned in the past 1,5 years.
Since I have just been working with a widget in the last two weeks and I have just found this unanswered question of mine I decided to solve it. I hope it helps others.
The AppWidgetProvider should look like this:
public class MyWidget extends AppWidgetProvider {
public static String ACTION_WIDGET_CONFIGURE = "ConfigureWidget";
public static String ACTION_WIDGET_RECEIVER = "ActionReceiverWidget";
private PendingIntent service = null;
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
final AlarmManager m = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
final Calendar TIME = Calendar.getInstance();
TIME.set(Calendar.MINUTE, 0);
TIME.set(Calendar.SECOND, 0);
TIME.set(Calendar.MILLISECOND, 0);
final Intent i = new Intent(context, MyService.class);
if (service == null)
{
service = PendingIntent.getService(context, 0, i, PendingIntent.FLAG_CANCEL_CURRENT);
}
m.setRepeating(AlarmManager.RTC, TIME.getTime().getTime(), 1000 * 1, service);
}
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
super.onDeleted(context, appWidgetIds);
}
@Override
public void onDisabled(Context context) {
super.onDisabled(context);
final AlarmManager m = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
if (service != null)
{
m.cancel(service);
}
}
@Override
public void onEnabled(Context context) {
super.onEnabled(context);
}
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
}
}
The Service:
public class MyService extends Service
{
@Override
public void onCreate()
{
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
buildUpdate();
return super.onStartCommand(intent, flags, startId);
}
private void buildUpdate()
{
String lastUpdated = DateFormat.format("hh:mm:ss", new Date()).toString();
RemoteViews view = new RemoteViews(getPackageName(), R.layout.widget_layout);
view.setTextViewText(R.id.btn_widget, lastUpdated);
ComponentName thisWidget = new ComponentName(this, MyWidget.class);
AppWidgetManager manager = AppWidgetManager.getInstance(this);
manager.updateAppWidget(thisWidget, view);
}
@Override
public IBinder onBind(Intent intent)
{
return null;
}
}
Also, register the provider and the Service in the Manifest:
<receiver android:name="MyWidget" android:label="Tutorial_Widget 1x1">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="com.something.MyWidget.ACTION_WIDGET_RECEIVER"/>
</intent-filter>
<meta-data android:name="android.appwidget.provider" android:resource="@xml/widget_info"/>
</receiver>
<service android:enabled="true" android:name=".MyService" />
ALARM_SERVICE is a static field of the Context class. So type Context.ALARM_SERVICE or use a static import.
Remember that when you set updatePeriodMillis attribute value it's not guaranteed for your onUpdate method to be called with that period exactly.
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