Widget Intent Updates Example

This example shows how to update home screen widgets by broadcasting an intent after a period of time requesting that the widget be updated.

A screenshot of the widget.

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

See this Stack Overflow question for the hints and tips that led to this implementation.

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 update one of the views in the widget layout with a string containing the current time. Then we update each widget referred to by its IDs to use the updated view. We record each widget ID passed to the method to use later.

    def onUpdate(self, context, manager, ids):
    
        views = RemoteViews(context.getPackageName(), R.layout.main)
        dateString = SimpleDateFormat("HH:mm").format(Date())
        views.setTextViewText(R.id.widget_text, dateString)
        
        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)
            
            manager.updateAppWidget(app_widget_id, views)
        
        self.context = context
        self.handler = Handler()
        self.handler.postDelayed(self, long(self.DELAY))

After updating the widgets, we create a Handler and post an event for later delivery to the instance which is handled by the run method.

    def run(self):

        intent = Intent(self.context,
            Class.forName("com.example.widgetintentupdates.WidgetProvider"))
        intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE)
        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS,
                        array(self.widget_ids))
        self.context.sendBroadcast(intent)

In response to the event, we create an Intent to request another update, passing the widget IDs that we collected earlier, and broadcast it. The application will receive the intent and update the widget in the onUpdate method.

Files