▼Androidメモ▼
ホームスクリーンウィジェット

ホームスクリーンウィジェットを作成する。


リソース
resフォルダの下にdrawable-hdpiに以下の画像を追加。
dice1.png

dice2.png

dice3.png

dice4.png

dice5.png

dice6.png


ホームスクリーンウィジェット設定
ホームスクリーンウィジェット設定「res/xml/appwidgetex_info.xml」を追加。
appwidgetex_info.xml
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider
xmlns:android="http://schemas.android.com/apk/res/android"
android:minHeight="40dp"
android:minWidth="40dp"
android:updatePeriodMillis="0"
android:previewImage="@drawable/preview"
android:initialLayout="@layout/appwidget"
android:resizeMode="horizontal|vertical">
</appwidget-provider>

設定項目 説明
minWidth
minHeight
初期のウィジェットサイズの最小値を指定。 "40dp"
minResizeWidth
minResizeHeight
リサイズ時にウィジェットサイズの最小値を指定。 "40dp"
updatePeriodMillis 更新メソッドを呼ぶ間隔をミリ秒単位で指定。
更新メソッドは
AppWidgetProvider.onUpdate()。
最小値は1800000(30分)で起動時のみ更新は"0"を指定。
"0"
initialLayout ウィジェットのレイアウトファイルを指定 "@layout/appwidget"
configure ウィジェットの設定アクティビティを指定 "net.npaka..MyConfigure"
previewImage ウィジェットのプレビュー画像を指定
Androidエミュレータ内の「Widget Preview」で
プレビュー画像作成できる
"@drawable/preview"
autoAdvanceViewId StackViewのIDを指定。
定期的にStackViewのページめくりを行う。
(Youtubeのウィジェット等)
"myViewId"
resizeMode ウィジェットのリサイズ規則を指定
"none" - 伸縮なし
"horizontal"
 - 横伸縮あり
"vertical" - 縦伸縮あり
"horizontal|vertical" - 縦横伸縮あり
widgetCategory ウィジェットのカテゴリを指定 "keyguard" - ロック画面
"home_screen"
 - ホームスクリーン
"keyguard|home_screen" - 両方 
initialKeyguardLayout ウィジェットが初期化中に表示するレイアウトを指定 "@layout/splash"

Android 4.0以降で指定すべきウィジェットサイズ(minWidth/minHeight)は次の通り。
マージンが自動的に付加されるので、ホームスクリーンウィジェットのレイアウト内にマージンは必要ない。
グリッド数 ウィジェットサイズ
140dp
2 110dp
3 180dp
4 250dp
n 70 x n - 30 dp

レイアウト
ウィジェットのレイアウト「res/layout/appwidget.xml」を追加。
appwidgex.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#33000000"
android:orientation="vertical">
<ImageView
android:id="@+id/imageview1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:contentDescription="@string/dice"
android:src="@drawable/dice1"/>
<Button
android:id="@+id/button1"
android:text="@string/roll"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="12sp"
/>
</LinearLayout>

文字リソース
文字列を文字リソース「res/values/strings.xml」に追加。
strings.xml
<resources>
<string name="app_name">AppWidgetEx</string>
<string name="dice">サイコロ</string>
<string name="roll">振る</string>
</resources>

ソースコード

AppWidgetEx.java
package net.npaka.appwidgetex;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;

//ホームスクリーンウィジェットを提供するブロードキャストレシーバー
public class AppWidgetEx extends AppWidgetProvider {
//ホームスクリーンウィジェット更新時に呼ばれる
@Override
public void onUpdate(Context context,
AppWidgetManager appWidgetManager,int[] appWidgetIds) {

//ホームスクリーンウィジェットのイベント処理を担当するサービスの起動
Intent intent=new Intent(context,AppWidgetService.class);
context.startService(intent);
}
}

AppWidgetService.java
package net.npaka.appwidgetex;
import java.util.Random;

import android.app.PendingIntent;
import android.app.Service;
import android.appwidget.AppWidgetManager;
import android.content.ComponentName;
import android.content.Intent;
import android.os.IBinder;
import android.widget.RemoteViews;

//ホームウィジェットを制御するサービス
public class AppWidgetService extends Service {
private static final String ACTION_BTNCLICK =
"net.npaka.appwidget.ACTION_BTNCLICK";

//サービス開始時に呼ばれる
@Override
public int onStartCommand(Intent intent,int flags,int startId) {
super.onStartCommand(intent,flags,startId);

//リモートビューの生成
RemoteViews view=new RemoteViews(getPackageName(),R.layout.appwidget);

//ペンディングインテントの設定
Intent newintent=new Intent();
newintent.setAction(ACTION_BTNCLICK);
PendingIntent pending=PendingIntent.getService(this,0,newintent,0);
view.setOnClickPendingIntent(R.id.button1,pending);

//振るボタンがクリックされた時の処理
if (ACTION_BTNCLICK.equals(intent.getAction())) {
btnClicked(view);
}

//ホームスクリーンウィジェットの画面更新
AppWidgetManager manager=AppWidgetManager.getInstance(this);
ComponentName widget=new ComponentName(
"net.npaka.appwidgetex",
"net.npaka.appwidgetex.AppWidgetEx");
manager.updateAppWidget(widget,view);
return START_STICKY;
}

//バインダを返す
@Override
public IBinder onBind(Intent intent) {
return null;
}

//振るボタンがクリックされた時の処理
public void btnClicked(RemoteViews view){
int[] ids={
R.drawable.dice1,R.drawable.dice2,R.drawable.dice3,
R.drawable.dice4,R.drawable.dice5,R.drawable.dice6};
int idx=rand(6);
view.setImageViewResource(R.id.imageview1,ids[idx]);
}

//乱数の取得
private static Random rand=new Random();
public static int rand(int num) {
return (rand.nextInt()>>>1)%num;
}
}


AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.npaka.appwidgetex"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="17" />

<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<receiver
android:name="AppWidgetEx"
android:exported="false"
android:label="AppWidgetEx" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>

<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/appwidgetex_info" />
</receiver>

<service
android:name="AppWidgetService"
android:exported="false" >
<intent-filter>
<action android:name="net.npaka.appwidget.ACTION_BTNCLICK" />
</intent-filter>
</service>
</application>

</manifest>




−戻る−