Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Widget update

Tags:

android

widget

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.

like image 585
erdomester Avatar asked Feb 01 '11 18:02

erdomester


People also ask

How do you update Android widgets?

Full update: Call AppWidgetManager. updateAppWidget(int, android. widget. RemoteViews) to fully update the widget.

What happened to Android widgets?

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.


2 Answers

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" />
like image 182
erdomester Avatar answered Sep 24 '22 04:09

erdomester


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.

like image 28
Roman Mazur Avatar answered Sep 21 '22 04:09

Roman Mazur