免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 924 | 回复: 0

Introducing home screen widgets and the AppWidget [复制链接]

论坛徽章:
0
发表于 2009-05-12 11:46 |显示全部楼层


Introducing home screen widgets and the AppWidget framework
(翻译)
Posted by Jeff Sharkey on 20 April 2009 at 6:43 PM
One exciting new feature in the Android 1.5 SDK is the AppWidget framework which allows developers to write "widgets" that people can drop onto their home screen and interact with. Widgets can provide a quick glimpse into full-featured apps, such as showing upcoming calendar events, or viewing details about a song playing in the background.
一个比较激动的新功能将会在Android1.5SDK中提供,就是AppWidgetk框架,这个框架允许开发者在编写widgets时提供一个不在主应用程序桌面而与其交互的功能。如显示即将来临的日历事件或者显示后台播放音乐的信息。
When widgets are dropped onto the home screen, they are given a reserved space to display custom content provided by your app. Users can also interact with your app through the widget, for example pausing or switching music tracks. If you have a background service, you can push widget updates on your own schedule, or the AppWidget framework provides an automatic update mechanism.
当widgets退出其界面,我们将给一个保留的空间去显示应用程序的自定内容,用户也可以通过它与你的应用程序交互。例如暂停或选择音乐。如果是后台服务,你可以根据自己的计划去更新你的widget,AppWidget也提供了一个自动更新的机制。
At a high level, each widget is a BroadcastReceiver paired with XML metadata describing the widget details. The AppWidget framework communicates with your widget through broadcast intents, such as when it requests an update. Widget updates are built and sent using
在更高的级别,任何widget都是一对BroadcastReceiver通过XML元数据描述widget的详细信息。AppWidget框架通过广播与你的widget通讯。例如当一个请求被更新,widget更新将建立。
RemoteViews which package up a layout and content to be shown on the home screen.
信息将会显示在桌面,如下图:
You can easily add widgets into your existing app, and in this article I'll walk through a quick example: writing a widget to show the Wiktionary "Word of the day." The
full source code is available
, but I'll point out the AppWidget-specific code in detail here.
你可以很容把这个功能加入你已经有的程序中,在下面的内容中,我们将通过一个例子:写一个widget去显示Wiktionary “Word of he day” 源码可以点英文中的那个full source code is available链接,但我需要指出的这个功能的特别处将会在这里讲述。
First, you'll need some
XML metadata to describe the widget
, including the home screen area you'd like to reserve, an initial layout to show, and how often you'd like to be updated. The default Android home screen uses a cell-based layout, so it rounds your requested size up to the next-nearest cell size. This can be a little confusing, so here's a quick equation to help:
第一步:你需要用XML的元数据描述一下widget.包括你在桌面保留的区域,初始化一个布局去显示,还有你多久就更新一下其中的内容。Android桌面默认的布局是cell-based.,你可以申请一个相邻的单元格。在申请时可能有些麻烦,可以通过下面的公式来计算。
Minimum size in dip = (Number of cells * 74dip) - 2dip
In this example, we want our widget to be 2 cells wide and 1 cell tall, which means we should request a minimum size 146dip x 72dip. We're also going to request updates once per day, which is roughly every 86,400,000 milliseconds. Here's what our widget XML metadata looks like:
在这个例子中,我们分别给widget2个单元格的宽度和一个单元格的高度,我们应该申请最小的大小为146dip x 72dip,我们也将要求每天更新一次。这大概是每八千六百四十〇点〇 〇 〇万毫秒,XML的元数据配置如下:
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="146dip"
    android:minHeight="72dip"
    android:initialLayout="@layout/widget_message"
    android:updatePeriodMillis="86400000"
    />
Next, let's pair this XML metadata with a
BroadcastReceiver in the AndroidManifest
:
接下来是下一对
BroadcastReceiver in the AndroidManifest
:XML元数据
   
        
   
   

Finally, let's write the BroadcastReceiver code to actually handle AppWidget requests. To help widgets manage all of the various broadcast events, there is a helper class called AppWidgetProvider, which we'll use here. One very important thing to notice is that we're launching a background service to perform the actual update. This is because BroadcastReceivers are subject to the
Application Not Responding
(ANR) timer, which may prompt users to force close our app if it's taking too long. Making a web request might take several seconds, so we use the service to avoid any ANR timeouts.
最后,我们写一下BroadcastReceiver 代码处理AppWidget请求,去帮助widget管理所以类型的广播消息。我们需要继承的类名为AppWidgetProvider,一个需要注意的是我们需要一个后台程序去执行widget的更新,这是因为BroadcastReceivers取决于ANR时间,它可能关闭我们的程序当它运行时间比较长的时候,一个WEB请求可以需要几分钟,所以我们使用后台服务去避免任何的ANR超时。
/**
* Define a simple widget that shows the Wiktionary "Word of the day." To build
* an update we spawn a background {@link Service} to perform the API queries.
*/
public class WordWidget extends AppWidgetProvider {
    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager,
        int[] appWidgetIds) {
        // To prevent any ANR timeouts, we perform the update in a service
        context.startService(new Intent(context, UpdateService.class));
    }

    public static class UpdateService extends Service {
        @Override
        public void onStart(Intent intent, int startId) {
            // Build the widget update for today
            RemoteViews updateViews = buildUpdate(this);

            // Push update for this widget to the home screen
            ComponentName thisWidget = new ComponentName(this, WordWidget.class);
            AppWidgetManager manager = AppWidgetManager.getInstance(this);
            manager.updateAppWidget(thisWidget, updateViews);
        }

        /**
         * Build a widget update to show the current Wiktionary
         * "Word of the day." Will block until the online API returns.
         */
        public RemoteViews buildUpdate(Context context) {
            // Pick out month names from resources
            Resources res = context.getResources();
            String[] monthNames = res.getStringArray(R.array.month_names);

            // Find current month and day
            Time today = new Time();
            today.setToNow();

            // Build today's page title, like "Wiktionary:Word of the day/March 21"
            String pageName = res.getString(R.string.template_wotd_title,
                monthNames[today.month], today.monthDay);
            RemoteViews updateViews = null;
            String pageContent = "";

            try {
                // Try querying the Wiktionary API for today's word
                SimpleWikiHelper.prepareUserAgent(context);
                pageContent = SimpleWikiHelper.getPageContent(pageName, false);
            } catch (ApiException e) {
                Log.e("WordWidget", "Couldn't contact API", e);
            } catch (ParseException e) {
                Log.e("WordWidget", "Couldn't parse API response", e);
            }

            // Use a regular expression to parse out the word and its definition
            Pattern pattern = Pattern.compile(SimpleWikiHelper.WORD_OF_DAY_REGEX);
            Matcher matcher = pattern.matcher(pageContent);
            if (matcher.find()) {
                // Build an update that holds the updated widget contents
                updateViews = new RemoteViews(context.getPackageName(), R.layout.widget_word);
   
                String wordTitle = matcher.group(1);
                updateViews.setTextViewText(R.id.word_title, wordTitle);
                updateViews.setTextViewText(R.id.word_type, matcher.group(2));
                updateViews.setTextViewText(R.id.definition, matcher.group(3).trim());
   
                // When user clicks on widget, launch to Wiktionary definition page
                String definePage = res.getString(R.string.template_define_url,
                        Uri.encode(wordTitle));
                Intent defineIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(definePage));
                PendingIntent pendingIntent = PendingIntent.getActivity(context,
                        0 /* no requestCode */, defineIntent, 0 /* no flags */);
                updateViews.setOnClickPendingIntent(R.id.widget, pendingIntent);
   
            } else {
                // Didn't find word of day, so show error message
                updateViews = new RemoteViews(context.getPackageName(), R.layout.widget_message);
                CharSequence errorMessage = context.getText(R.string.widget_error);
                updateViews.setTextViewText(R.id.message, errorMessage);
            }
            return updateViews;
        }

        @Override
        public IBinder onBind(Intent intent) {
            // We don't need to bind to this service
            return null;
        }
    }
}
And there you have it, a simple widget that will show the Wiktionary "Word of the day." When an update is requested, we read the online API and push the newest data to the surface. The AppWidget framework automatically requests updates from us as needed, such as when a new widget is inserted, and again each day to load the new "Word of the day."
到现在你已经完成了,一个简单的显示Wiktionary”Word of the day”的widget,当有一个更新请求,我们使用在线API推送新的数据给他。AppWidget框架的自动更新机制可以满足我们的需求。例如当一个新的widget插入,每天再次加载”Word of the day”

Finally, some words of wisdom. Widgets are designed for longer-term content that doesn't update very often, and updating more frequently than every hour can quickly eat up battery and bandwidth. Consider updating as infrequently as possible, or letting your users pick a custom update frequency. For example, some people might want a stock ticker to update every 15 minutes, or maybe only four times a day. I'll be talking about additional strategies for saving battery life as part of a session I'm
giving at Google I/O
.
One last cool thing to mention is that the AppWidget framework is abstracted in both directions, meaning alternative home screens can also contain widgets. Your widgets can be inserted into any home screen that supports the AppWidget framework.
最后一个很酷的事情提的是AppWidget框架在两个方向都是抽象的。意思是你可以任选其一,是桌面包含widgets ,,你的widget也可以插入一个桌面。这些都是AppWidget框架所支持的。
We've already written several widgets ourselves, such as the Calendar and Music widgets, but we're even more excited to see the widgets you'll write!
我已经写好了一些widget,例如日历,音乐,但我们更高兴看到你写的。


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/94235/showart_1925248.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP