Widget Updates Example

This example shows one way to update home screen widgets by repeatedly posting events to keep the widget provider active.

A screenshot of the widget.

See the following guides in Android's documentation for information about implementing App Widgets:

from java.lang import Class, Runnable
from java.text import SimpleDateFormat
from java.util import Date, List
from android.appwidget import AppWidgetManager, AppWidgetProvider
from android.content import Intent
from android.os import Handler
from android.widget import RemoteViews

from app_resources import R

The WidgetProvider class is derived from the standard AppWidgetProvider class and represents the application. Android will create an instance of this class when the user runs it.

We indicate that the class implements the Runnable interface so that its instance can use a Handler to post and handle events.

class WidgetProvider(AppWidgetProvider):

    __interfaces__ = [Runnable]
    __fields__ = {"widget_ids": List(int)}
    
    DELAY = 30000 # ms
    
    def __init__(self):
    
        AppWidgetProvider.__init__(self)
        self.widget_ids = []

In this method we record each widget ID passed to the method to use later before storing the context and widget manager.

    def onUpdate(self, context, manager, ids):
    
        for app_widget_id in ids:
        
            # Record the widget IDs so that we can ask for them to updated later.
            if len(self.widget_ids) < len(ids):
                self.widget_ids.add(app_widget_id)
            
        self.context = context
        self.manager = manager
        self.handler = Handler()
        self.run()

We create a Handler and call the run method, which updates a TextView in the widget then updates all the widget whose IDs were stored earlier.

    def run(self):
    
        views = RemoteViews(self.context.getPackageName(), R.layout.main)
        dateString = SimpleDateFormat("HH:mm").format(Date())
        views.setTextViewText(R.id.widget_text, dateString)
        
        for app_widget_id in self.widget_ids:
            self.manager.updateAppWidget(app_widget_id, views)
        
        self.handler.postDelayed(self, long(self.DELAY))

Finally, we post an event to ensure that this method is called again after a delay.

Files