ウィジェットの作り方

AndroidSDK 1.5より導入されたAppWidget frameworkを利用し、
Home Screen上にAppWidgetを作成するための基本的な方法を説明します。
(開発にはAndroidSDK 1.6を使用しています)

まずは、「HelloWorld!」と表示するだけの簡単なAppWidgetを作成してみます。


■AndroidSDKリファレンス(サイト)
http://developer.android.com/intl/ja/reference/packages.html

■AndroidSDKリファレンス
android-sdk-windows-1.6_r1.zip
解凍後のフォルダ内
docs/reference/packages.html

プロジェクトの作成

「ファイル」→「新規」→「Androidプロジェクト」

新規プロジェクト
プロジェクト名、アプリケーション名、パッケージ名を入力、ターゲット名を選択します。
デフォルトで「Create Activity」にチェックがされていますが、
今回は使用しないためチェックをはずします。

ファイルが自動生成され、ビルドが行われると、このようなファイルが作成されているのが確認できます。
「ウィンドウ」→「ビューの表示」→「ナビゲーター」で確認できるようにします。

ファイル構成
自動生成された各ファイルの詳細については、「HelloWorld!」のページを参考にしてください。
http://www.techfirm.co.jp/lab/android/helloworld.html

AppWidgetの作成

AppWidgetを作成するためには次の工程が必要になります。

・AppWidgetのレイアウト作成
・AppWidgetの設定ファイル作成
・AppWidgetの処理を記述
・AndroidManifest.xmlへの登録

AppWidgetのレイアウト作成

今回は「HelloWorld!」と表示するだけですので、 自動生成されたレイアウトをそのまま使用します。

HelloWorldWidget/res/layout/main.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"
    android:background="#000000">
<TextView  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/hello"
    />
</LinearLayout>
表示を分かりやすくするため、
 android:background="#000000"
で、背景色のみ新規に設定しています。

AppWidgetの設定ファイル作成

AppWidgetの設定を記述するXMLを作成します。

「HelloWorldWidget/res」以下に「xml」フォルダを作成し、
右クリックメニューより、「新規」→「Android XML file」を選択。

AppWidget設定ファイル作成
ファイル名:任意(ここではappwidget.xml)
リソースの種類:AppWidget Provider
を入力し、完了ボタンをクリックするとxmlの雛型が出来ますので、下記を参考に設定を記述します。

HelloWorldWidget/res/xml/appwidget.xml

<?xml version="1.0" encoding="UTF-8"?>
<appwidget-provider
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="72dip"
    android:minHeight="72dip"
    android:initialLayout="@layout/main"
    android:updatePeriodMillis="0"
    />
android:minWidth
 ウィジェットの幅(dip)
android:minHeight
 ウィジェットの高さ(dip)
android:initialLayout
 ウィジェットの初期レイアウト
android:updatePeriodMillis
 ウィジェットの更新間隔(ms)
 "0"の場合は更新しない

ウィジェットのサイズ

ウィジェットサイズは、自由には決められず、画面を4×4に分割したセル単位で指定します。
指定には、DIP(density-independent pixels)という単位を用い、これにより画面サイズの違う端末でも同じ様に表示することができます。

分割された1セルのサイズは74dipです。
ただし、実サイズ計算時に丸め誤差が発生するため、実際には次の計算式でdipを算出します。

dip = (セル数 * 74dip) - 2dip

今回は1×1セルのサイズで作成するため、72dipを指定します。

http://android-developers.blogspot.com/2009/04/introducing-home-screen-widgets-and.html

ウィジェットの更新間隔

AndroidSDK 1.6よりウィジェットの更新間隔に制限が掛かり、
30分以下は30分として扱われる様になりました。

updatePeriodMillisでの更新では、ウィジェットがバックグラウンドにいる場合にも更新が発生し、
他アプリの動作やバッテリー消費に影響があるための制限です。
時計やタイマー等、短い間隔での更新が必要な場合には、Serviceを使用した方法などがあります。

今回は表示するのみなので、0を指定します。

http://code.google.com/p/android/issues/detail?id=3990

AppWidgetの処理を記述

「src/android/sample」以下に、AppWidgetProviderクラスを継承した任意のクラスを作成します。
(ここではHelloAndroidWidgetProviderとします)

src/android/sample/HelloAndroidWidgetProvider.java

public class HelloAndroidWidgetProvider extends AppWidgetProvider {

	@Override
	public void onEnabled(Context context) {
		Log.v("HelloAndroidWidget", "onEnabled");
		super.onEnabled(context);
	}
	
	@Override
	public void onUpdate(Context context, AppWidgetManager appWidgetManager,
			int[] appWidgetIds) {
		Log.v("HelloAndroidWidget", "onUpdate");
		super.onUpdate(context, appWidgetManager, appWidgetIds);
	}
	
	@Override
	public void onDeleted(Context context, int[] appWidgetIds) {
		Log.v("HelloAndroidWidget", "onDeleted");
		super.onDeleted(context, appWidgetIds);
	}
	
	@Override
	public void onDisabled(Context context) {
		Log.v("HelloAndroidWidget", "onDisabled");
		super.onDisabled(context);
	}
	
	@Override
	public void onReceive(Context context, Intent intent) {
		Log.v("HelloAndroidWidget", "onReceive");
		super.onReceive(context, intent);
	}
}
AppWidgetProviderの以下の処理をオーバーライドすることで、AppWidgetの処理を記述できます。

onEnabled()
 AppWidgetが作成される際に呼ばれます。
 同じAppWidgetを複数起動した際には、初回のみ呼ばれます。
 全体的な初期化処理が必要な場合はここに記述します。
onUpdate()
 AppWidgetが更新される際に呼ばれます。
 updatePeriodMillis等で更新間隔を設定していれば、そのタイミングで呼ばれます。
 また、AppWidgetを起動した際にも一度呼ばれます。
onDeleted()
 AppWidgetが削除された際に呼ばれます。
 終了処理が必要な場合はここに記述します。
onDisabled()
 AppWidgetが全て削除された際に呼ばれます。
 全体的な終了処理が必要な場合はここに記述します。
onReceive()
 アクションを受け取り、AppWidgetProviderの各メソッドの呼び出しを処理します。

今回は特に処理はありませんが、動作確認のため各メソッドにログを入れています。

ログ

ログ表示にはLogクラスを使用します。
詳細はリファレンスを参照してください。
http://developer.android.com/intl/ja/reference/android/util/Log.html

Logの確認にはLogCatビューを使用します。
表示されていない場合は、eclipseの下記メニューより表示出来ます。
「ウィンドウ」→「ビューの表示」→「その他」→「Android」→「LogCat」

稀にログが出力されなくなることがありますが、eclipseの再起動もしくは
Android開発プラグインの再インストールで回避出来るようです。

AndroidManifest.xmlへの登録

AppWidgetをAndroidManifest.xmlへ登録します。
<application>タグ内に<receiver>タグを追加し、AppWidgetの情報を記述します。
AndroidManifest.xml

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

    </application>
    <uses-sdk android:minSdkVersion="4" />
</manifest> 
<reciver>
 android:nameにAppWidgetProviderを継承したクラスを”.(ドット)クラス名”で記述します。
<intent-filter>
 <action>タグにAPPWIDGET_UPDATEを記述し、更新イベントを受け取れることを示します。
<meta-data>
 android:resourceにAppWidgetの設定ファイルを指定します。

ウィジェットの実行

eclipseメニューより「実行」→「実行構成」を選択し、実行構成ダイアログを表示します。
「AndroidApplication」を右クリック、「新規」を選択し、名前とプロジェクトを指定します。

AppWidget実行
実行ボタンクリックでAndroidエミュレータが起動します。

AVD起動
MENUボタンでHomeScreenへ移動します。

ウィジェットをHomeScreenに登録

動作を確認するために、作成したウィジェットをHomeScreenに登録します。
HomeScreen画面を長押しすると、次のようなメニューが表示されます。

メニュー

Widgetsを選択し、ウィジェット選択画面を表示。
先程作ったウィジェットを選択します。
AppWidget選択

HomeScreenにウィジェットが表示されます。
AppWidget起動

eclipseのLogCatビューでは各処理が呼ばれていることが確認できます。
AppWidget起動ログ

ウィジェットの削除

ウィジェットを長押しすると、画面下部にゴミ箱アイコンが現れるので、
そこへドラッグ&ドロップします。

このページ「ウィジェットの作り方」の上へ