ページ

2014/04/27

[Android]AppWidgetを作成する

以下の記事を読めば AppWidget を作成する方法がわかります。ココはポインタ。
App Widgets | Android Developers
Widgets | Android Developers
App Widget Design Guidelines | Android Developers
AppWidgetManager | Android Developers
AppWidgetProvider | Android Developers
AppWidgetProviderInfo | Android Developers
RemoteViews | Android Developers

AndroidManifect.xml に AppWidgetProvider を宣言する

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

AppWidget のメタデータを設定する

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:initialLayout="@layout/appwidget"
    android:minHeight="40dp"
    android:minWidth="40dp"
    android:updatePeriodMillis="0" >
</appwidget-provider>
最低限必要なのはレイアウト指定とサイズ指定と更新間隔指定です。
サイズ指定は以下を参考に指定します。
App Widget Design Guidelines | Android Developers
# of Cells
(Columns or Rows)
Available Size (dp)
(minWidth or minHeight)
140dp
2110dp
3180dp
4250dp
n70 × n − 30
更新間隔は最短で30分です。
30分 = 30 * 60 * 1000 = 1800000 以下の値を設定しても 1800000 として処理されます。
デバイスがスリープ状態でもアウェイクしてしまうため頻度の高い更新をする場合は
updatePeriodMillis に 0 を指定し、 ELAPSED_REALTIME か RTC のどちらかを指定した AlarmManager で
PendingIntent を飛ばして BroadcastReciever から AppWidget を更新する方法で行うべきです。

AppWidgetProvider を作成する

public class ExampleAppWidgetProvider extends AppWidgetProvider {

    /**
     * 最初の1個目のAppWidgetが設置された時に呼ばれる
     */
    @Override
    public void onEnabled(Context context){
        super.onEnabled(context);
    }

    /**
     * AppWidget が設置された時/更新期間が来た時に呼ばれる
     */
    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds){
        super.onUpdate(context, appWidgetManager, appWidgetIds);
        for(int appWidgetId : appWidgetIds){
            updateAppWidget(context, appWidgetManager, appWidgetId);
        }
    }

    /**
     * AppWidget が削除された時に呼ばれる
     */
    @Override
    public void onDeleted(Context context, int[] appWidgetIds){
        super.onDeleted(context, appWidgetIds);
    }

    /**
     * 最後の AppWidget が削除された時に呼ばれる
     */
    @Override
    public void onDisabled(Context context){
        super.onDisabled(context);
    }

    /**
     * 上記のコールバックに振り分けるメソッド
     */
    @Override
    public void onReceive(Context context, Intent intent){
        super.onReceive(context, intent);
    }

    /**
     * AppWidget をリサイズした時に呼ばれる
     */
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    @Override
    public void onAppWidgetOptionsChanged(Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newOptions){
        super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions);
        updateAppWidget(context, appWidgetManager, appWidgetId);
    }

}
ただの BroadcastReceiver の拡張なので時間のかかる処理を行うと ANR が発生するので
Service を開始して Service で時間のかかる処理を行った方が良いです。

View を設定する

public static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId){
    RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget);
    // AppWidgetManager 
    appWidgetManager.updateAppWidget(appWidgetId, views);
}
Creating the App Widget Layout | App Widgets | Android Developersを参考に
RemoteViews で使える View を使って AppWidget を作りましょう!