實(shí)現(xiàn)一個(gè)用于顯示當(dāng)前時(shí)間的Google Android 窗口小部件(AppWidget)
本文為原創(chuàng),如需轉(zhuǎn)載,請(qǐng)注明作者和出處,謝謝!
Android不用我多說了,這是Google在2007年推出的一款主要用于移動(dòng)設(shè)備的操作系統(tǒng)。google在android sdk1.5中加入了appwidget api。通過這項(xiàng)技術(shù),可以在android手機(jī)的主界面(Home界面)顯示可以拖動(dòng)的窗口,用于顯示各種用戶需要的信息。至于顯示什么,就完全依靠開發(fā)人員的想象力了。OK,廢話少說。我們先來體驗(yàn)一下如何開發(fā)一個(gè)顯示當(dāng)前時(shí)間的appwidget。這個(gè)appwidget每秒刷新一次,顯示時(shí)、分和秒。這個(gè)appwidget的效果如圖1所示。
步驟2:編寫AppWidgetProvider類
appwidget需要一個(gè)AppWidgetProvider類的子類,該類的代碼如下:
當(dāng)創(chuàng)建每一個(gè)appwidget的實(shí)例時(shí)AppWidgetManager都會(huì)調(diào)用該appwidget的onUpdate方法。要想使更新有效,必須調(diào)用updateAppWidget方法更新相應(yīng)的appwidget中的view。
步驟3:配置<appwidget-provider>元素
appwidget還需要一個(gè)<appwidget-provider>元素來描述appwidget的大小、布局、更新頻率等信息。在res目錄下建立一個(gè)xml目錄,在res\xml目錄下建立一個(gè)appwidget_provider.xml,并輸入如下的代碼:
其中android:minWidth和android:minHeight表示appwidget的最小寬度和高度,android:updatePeriodMillis表示更新頻率,單位是毫秒。也就是說,AppWidgetManager每秒都會(huì)調(diào)用該appwidget的onUpdate方法。因此,onUpdate方法在兩種情況下被調(diào)用,第一種是添加appwidget時(shí),第二種是每一個(gè)更新周期結(jié)束時(shí)調(diào)用一次onUpdate方法。
步驟4:進(jìn)行最后的配置
appwidget需要在appwidget_provider.xml文件中配置receiver,從這一點(diǎn)可以看出,android是通過Broadcast來通知每一個(gè)appwidget的。appwidget_provider.xml文件的配置代碼如下:
在上面的配置代碼中使用<intent-filter>元素的<action>子元素來指定appwidget接收的動(dòng)作。使用<meta-data>元素指定appwidget的layout。
將這個(gè)程序安裝在android模擬器中,我們會(huì)發(fā)現(xiàn)appwidget并沒有出現(xiàn)。實(shí)際上,appwidget需要手工去添加。通過模擬器的menu,進(jìn)入“添加”列表,選擇“widgets”,我們就會(huì)找到本文實(shí)現(xiàn)的appwidget,名稱為“顯示當(dāng)前時(shí)間”。如圖2所示。
新浪微博:http://t.sina.com.cn/androidguy 昵稱:李寧_Lining
Android不用我多說了,這是Google在2007年推出的一款主要用于移動(dòng)設(shè)備的操作系統(tǒng)。google在android sdk1.5中加入了appwidget api。通過這項(xiàng)技術(shù),可以在android手機(jī)的主界面(Home界面)顯示可以拖動(dòng)的窗口,用于顯示各種用戶需要的信息。至于顯示什么,就完全依靠開發(fā)人員的想象力了。OK,廢話少說。我們先來體驗(yàn)一下如何開發(fā)一個(gè)顯示當(dāng)前時(shí)間的appwidget。這個(gè)appwidget每秒刷新一次,顯示時(shí)、分和秒。這個(gè)appwidget的效果如圖1所示。

圖1
圖1上方“當(dāng)前時(shí)間:03:34:34”就是我們要實(shí)現(xiàn)的appwidget。這個(gè)appwidget是可以拖動(dòng)的。如果在真機(jī)或android模擬器中這個(gè)時(shí)間是變化的。
我們可按如下四步來實(shí)現(xiàn)這個(gè)appwidget:
步驟1:實(shí)現(xiàn)appwidget的layout
在android上編程的人都知道,android的界面離不開layout,appwidget也不例外。建立appwidget layout的方式與建立其他layout的方式相同。在res\layout目錄中建立一個(gè)firstappwidget.xml文件,代碼如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:id="@+id/tvMsg" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:textSize="20dp"
android:textColor="#F00" />
</LinearLayout>
tvMsg用于顯示applwidget中的文字,也就是類似“當(dāng)前時(shí)間:03:34:34”的字符串。<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:id="@+id/tvMsg" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:textSize="20dp"
android:textColor="#F00" />
</LinearLayout>
步驟2:編寫AppWidgetProvider類
appwidget需要一個(gè)AppWidgetProvider類的子類,該類的代碼如下:
package net.blogjava.nokiaguy.appwidget;
import java.util.Date;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.widget.RemoteViews;
public class MyAppWidgetProvider extends AppWidgetProvider
{
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds)
{
final int N = appWidgetIds.length;
for (int i = 0; i < N; i++)
{
int appWidgetId = appWidgetIds[i];
RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.firstappwidget);
java.text.DateFormat df = new java.text.SimpleDateFormat("hh:mm:ss");
views.setTextViewText(R.id.tvMsg, "當(dāng)前時(shí)間:" + df.format(new Date()));
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
}
import java.util.Date;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.widget.RemoteViews;
public class MyAppWidgetProvider extends AppWidgetProvider
{
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds)
{
final int N = appWidgetIds.length;
for (int i = 0; i < N; i++)
{
int appWidgetId = appWidgetIds[i];
RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.firstappwidget);
java.text.DateFormat df = new java.text.SimpleDateFormat("hh:mm:ss");
views.setTextViewText(R.id.tvMsg, "當(dāng)前時(shí)間:" + df.format(new Date()));
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
}
當(dāng)創(chuàng)建每一個(gè)appwidget的實(shí)例時(shí)AppWidgetManager都會(huì)調(diào)用該appwidget的onUpdate方法。要想使更新有效,必須調(diào)用updateAppWidget方法更新相應(yīng)的appwidget中的view。
步驟3:配置<appwidget-provider>元素
appwidget還需要一個(gè)<appwidget-provider>元素來描述appwidget的大小、布局、更新頻率等信息。在res目錄下建立一個(gè)xml目錄,在res\xml目錄下建立一個(gè)appwidget_provider.xml,并輸入如下的代碼:
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="200dp"
android:minHeight="30dp"
android:updatePeriodMillis="1000"
android:initialLayout="@layout/firstappwidget"/>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="200dp"
android:minHeight="30dp"
android:updatePeriodMillis="1000"
android:initialLayout="@layout/firstappwidget"/>
其中android:minWidth和android:minHeight表示appwidget的最小寬度和高度,android:updatePeriodMillis表示更新頻率,單位是毫秒。也就是說,AppWidgetManager每秒都會(huì)調(diào)用該appwidget的onUpdate方法。因此,onUpdate方法在兩種情況下被調(diào)用,第一種是添加appwidget時(shí),第二種是每一個(gè)更新周期結(jié)束時(shí)調(diào)用一次onUpdate方法。
步驟4:進(jìn)行最后的配置
appwidget需要在appwidget_provider.xml文件中配置receiver,從這一點(diǎn)可以看出,android是通過Broadcast來通知每一個(gè)appwidget的。appwidget_provider.xml文件的配置代碼如下:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.blogjava.nokiaguy.appwidget" android:versionCode="1" android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<receiver android:name=".MyAppWidgetProvider">
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/appwidget_provider" />
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
</receiver>
</application>
<uses-sdk android:minSdkVersion="3" />
</manifest>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.blogjava.nokiaguy.appwidget" android:versionCode="1" android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<receiver android:name=".MyAppWidgetProvider">
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/appwidget_provider" />
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
</receiver>
</application>
<uses-sdk android:minSdkVersion="3" />
</manifest>
在上面的配置代碼中使用<intent-filter>元素的<action>子元素來指定appwidget接收的動(dòng)作。使用<meta-data>元素指定appwidget的layout。
將這個(gè)程序安裝在android模擬器中,我們會(huì)發(fā)現(xiàn)appwidget并沒有出現(xiàn)。實(shí)際上,appwidget需要手工去添加。通過模擬器的menu,進(jìn)入“添加”列表,選擇“widgets”,我們就會(huì)找到本文實(shí)現(xiàn)的appwidget,名稱為“顯示當(dāng)前時(shí)間”。如圖2所示。

圖2
當(dāng)然,只要Home頁有地方,我們也可以添加多個(gè)appwidget,如圖3所示。
圖3
《Android開發(fā)完全講義(第2版)》(本書版權(quán)已輸出到臺(tái)灣)
http://product.dangdang.com/product.aspx?product_id=22741502
《Android高薪之路:Android程序員面試寶典 》http://book.360buy.com/10970314.html
新浪微博:http://t.sina.com.cn/androidguy 昵稱:李寧_Lining
posted on 2009-07-22 16:05 銀河使者 閱讀(2747) 評(píng)論(2) 編輯 收藏 所屬分類: java 、 原創(chuàng) 、移動(dòng)(mobile)