2010年12月16日 星期四

Android 開發筆記 - 簡易的 Widget 實作

MyWidgetShow


除了要從選單點選來執行的應用程式外,還有另一種呈現的方式,那就 Widget 模式,也就是在廣告單上常常看到簡介某大廠 Android 手機時,其手機畫面正顯示的天氣資訊,有點像似待機時顯示在背景的資訊。這種程式實作上並沒有特別困難,但是我看了一些文章教學,反而很著重在介面設計,畢竟 Widget 的特色就是要美美的,結果對我這種介面沒經驗的人來說,往往第一步就卡住了,像是要用內建的 draw9patch 去弄圖片等,故在此就先完全不理會,連什麼背景框框都不要,純粹用來筆記實作 Widget 的流程。


實做 Widget 跟一般 project 的設定沒有差太多,但還是要多留意:



  1. 建立專案時,不見得要使用 Activity

  2. 編寫 AndroidManifest.xml 檔案

  3. 新增描述 Widget 的檔案

  4. 設定 Widget 排版

  5. 實作更新 Widget 的物件


建立一個 project


[Eclipse]->[File]->[New]->[Android Project]

Project name: MyWidget
Build Target: Android 2.2
Application name: MyWidget
Package name: com.test.widget
Min SDK Version: 8


留意的是在此不啟用 Create Activity,這並不是必須的選項。啟用 Activity 的好處,可以規劃使用者在新增 Widget 時,可以在過程中可以多加設定動作。在此僅學習建立 Widget 的流程,就不多提了。


MyWidgetStru


設定 AndroidManifest.xml 檔案


新增 <receiver> 等敘述標籤,別於以前的 <activity>。

<receiver android:name=".MyWidget" >
    <intent-filter>
        <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
    </intent-filter>
    <meta-data android:name="android.appwidget.provider"
        android:resource="@xml/widget" />
</receiver>


在此 reciever 的 name 代表之後會建立的 Class 名稱,也就用更新 Widget 資訊的。而 meta-data 中所描述的 resource 則是下一步要新增 Widget 的描述檔


完整描述:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.test.widget"
    android:versionCode="1"
    android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <receiver android:name=".MyWidget" >
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            </intent-filter>
            <meta-data android:name="android.appwidget.provider"
                android:resource="@xml/widget" />
        </receiver>

    </application>
    <uses-sdk android:minSdkVersion="8" />
</manifest>


建立 xml/widget.xml 檔案,用以描述 Widget 的資訊


在 res 目錄裡建立新的目錄,名為 xml,接著在 res/xml 目錄裡建立一個檔案,可從 xml 按右鍵->[News]->[Other]->[Android]->[Android XML File],並填寫 File 為 widget.xml 並勾選 AppWidget Provider 的型態,最後就可以按 Finish 結束,接著開啟 xml/widget.xml 檔案進行編輯


<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="294dp"
    android:minHeight="72dp"
    android:updatePeriodMillis="1800000"
    android:initialLayout="@layout/main"

>
</appwidget-provider>


在此 minWidth 和 minHeight 是設定 Widget 顯示的範圍,而 dp 的數值計算可參考官網的教學,在此不多談,而 updatePeriodMillis 代表此 Widget 更新的頻率,1000 代表 1 秒,所以 1800000 代表 30 分鐘更新一次,更新頻率不宜過高,容易使得手機沒電。然而,經測試發現,目前內定的情境,無論把更新頻率弄到多快,最少要等 30 分鐘才會更新一次,解決的方式也不是沒有,在此先不多談。


設定排版部份


在此使用預設的 main.xml 檔案,開啟 main.xml 檔案後,替已存在的 TextView 加上 android:id="@+id/now"、android:gravity="center"、android:textColor="@android:color/black" 和 android:textSize="18sp" ,另外,再把 layout_height 更新為 fill_parent 即可。


<?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/now"
    android:gravity="center"
    android:textColor="@android:color/black"
    android:textSize="18sp"
    android:layout_width="fill_parent"

    android:layout_height="fill_parent"
    android:text="@string/hello"
    />
</LinearLayout>


實做 Widget 的資訊更新


在 src/com.test.widget 裡,新增一個 Class 名為 MyWidget.java


package com.test.widget;

import java.text.SimpleDateFormat;
import java.util.Date;

import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.widget.RemoteViews;

public class MyWidget extends AppWidgetProvider {
    @Override
    public void onUpdate(Context context,AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        RemoteViews updateViews = new RemoteViews( context.getPackageName(), R.layout.main);
        updateViews.setTextViewText(R.id.now,  new SimpleDateFormat( "yyyy/MM/dd HH:mm:ss" ).format( new Date() ) );
        appWidgetManager.updateAppWidget(appWidgetIds, updateViews);
    }
}


最後,把程式 Run 起來,起初模擬器上不會顯示任何效果,因為 Widget 是要讓使用者自行設置的,需要透過模擬器鍵盤上的 [Menu]->[Add]->[Widgets] 就可以找到 MyWidget,點選下去才是真的安裝此 Widget 啦,成果就是螢幕上面多了一個時間囉!這也是 MyWidget.java 裡頭寫得東作,僅把 TextView 上的內容更新為時間。另外,若想要把已安裝的 Widget 刪除,僅需用滑鼠按住它,接著 Home 就會變成垃圾桶,拖進去就可以囉。


沒有留言:

張貼留言