株式会社八角研究所 > AppWidgetでWidgetを作る

エンジニア募集中!

独立心旺盛で、新しい技術で新しいWebサービスを作りたいと思っているけれど、ひとりでやることに限界を感じているフリーのエンジニアの方。あなたの期待にこたえられる仲間と環境を、八角研究所なら提供できると思います。社員としてではない関わり方も、あるかもしれません。

2009年08月07日 00:40

AppWidgetでWidgetを作る * * * *

by tomato

Tags: Androidアプリ作りたい Android

AppWidgetとは

Widgetを作るためのフレームワークで、好きな機能を実装して、ホームスクリーンに表示されるWidgetである。(※Android SDK 1.5から可能)

 

「Google Search」AppWidget

appwidget.png

MusicPlayer Widgetを作ってみよう

 

MusicPlayer Widget

musicplayer.png MusicPlayer Widget

  • SDCardからミュージックファイル(.mp3)を読み込む
  • playボタンを押すと、該当表示されているミュージックを再生する
  • nextボタンを押すと、次のミュージックを再生する
  • playボタンでミュージックの再生、一時停止することができる

AppWidgetのレイアウト

res/layout/my_musicer.xmlで二つのImageButton(play_button、next_button)とTextView(music_name)が定義される。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="horizontal"
	android:layout_width="fill_parent"
	android:layout_height="wrap_content"
	android:background="@drawable/background">
	<ImageButton android:id="@+id/play_button"
		android:layout_marginTop="20px"
		android:layout_marginLeft="15px"
		android:layout_width="40px"
		android:layout_height="40px"
		android:src="@drawable/play"
		android:background="@drawable/btnbg"/>
	<TextView android:id="@+id/music_name"
		android:width="200px"
		android:layout_marginTop="20px"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:textColor="@android:color/darker_gray"
		android:padding="5dp"
		android:textSize="20dp"
		android:gravity="center"
		android:singleLine="true"/>
	<ImageButton android:id="@+id/next_button"
		android:layout_marginTop="20px"
		android:layout_marginRight="15px"
		android:layout_width="40px"
		android:layout_height="40px"
		android:src="@drawable/next"
		android:background="@drawable/btnbg"/>
</LinearLayout>

AppWidgetの特徴

res/xml/musicer_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="0"
    android:initialLayout="@layout/my_musicer"> 
</appwidget>

ここでは、AppWidgetの

  • 高さ
  • 更新間隔
  • 参照するレイアウト

などをxmlで定義する。

AppWidgetの処理

まず、MyMusicerProviderクラスを作る。

MyMusicerProviderはAppWidgetProviderクラスを継承して、onUpdate()とonReceive()メソッドをオーバーライドしなければならない。

public class MyMusicerProvider extends AppWidgetProvider {
	@Override
	public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] 		appWidgetIds) {
             ....
	}
	@Override
	public void onReceive(Context context, Intent intent) {
             ....
	}
}

次に、onUpdate()メソッドを実装する。

....
	// Widget更新処理を呼ぶ
	final int length = appWidgetIds.length;
	for(int i = 0; i < length; i++) {
		int appWidgetId = appWidgetIds[i];
		updateAppWidget(context, appWidgetManager, appWidgetId);
	}
....

このメソッドはAppWidgetが更新されると呼ばれる。Widgetに一意なIDが振られ、引数のappWidgetIdsに格納される。同じWidgetが複数個配置されても、すべてのWidgetに更新処理を行う必要がある。

void updateAppWidget(Context context, AppWidgetManager appWidgetManager,int appWidgetId) {
	// Widgetのレイアウトを取得
	RemoteViews rv = new RemoteViews(context.getPackageName(),R.layout.my_musicer);
	Intent intentPlay = new Intent(PLAY_ACTION);
	Intent intentNext = new Intent(NEXT_ACTION);
	PendingIntent pendingIntentPlay = PendingIntent.getBroadcast(context, 0,intentPlay, 0);
	PendingIntent pendingIntentNext = PendingIntent.getBroadcast(context, 0,intentNext, 0);
	rv.setOnClickPendingIntent(R.id.play_button, pendingIntentPlay);
	rv.setOnClickPendingIntent(R.id.next_button, pendingIntentNext);
	rv.setCharSequence(R.id.music_name, "setText", player.getSongName());
	player.setRv(rv);
	player.setAppWidgetManager(appWidgetManager);
	player.setAppWidgetId(appWidgetId);
	// Widget更新
	appWidgetManager.updateAppWidget(appWidgetId, rv);
}

AppWidgetのレイアウトはViewではなくて、RemoteViewsで取得する。4行~9行はplayボタンとnextボタンのonClickイベントを自作のIntentでPendingIntentに発送して、setOnClickPendingIntent()メソッドでWidgetに設定する。10行目は、ミュージック名をWidgetのmusic_nameというTextViewに設定する。15行目のupdateAppWidget()メソッドを行わないと、Widgetの見た目が変わらない。

最後は、onReceive()メソッドを実装する。

	final String action = intent.getAction();
	super.onReceive(context, intent);

	if (action.equals(PLAY_ACTION)){
		player.playOnClick();
	}else if(action.equals(NEXT_ACTION)){
		player.nextOnClick();
	}

このメソッドはWidget自身のIntentを受けることである。IntentのgetAction()メソッドでAction名が取得できる。取得したAction名が自作のIntent名と同じ場合のみ、MusicPlayerクラスのplayOnClick()或いはnextOnClick()メソッドが呼ばれる。

MusicPlayerクラスの中でMediaPlayオブジェクトを使ってミュージックの再生、一時停止などの処理を行う。

まず、SDCardからミュージックファイルを取得する。

	private List getSongs(){

		if (songs.size() == 0){
			File home = new File("/sdcard/");
			if (home.listFiles(new Mp3Filter()).length > 0) {
				for (File file : home.listFiles(new Mp3Filter())) {
					songs.add(file.getName());
				}
				currentPosition = 0;
			}
		}

		return songs;
	}

該当ミュージックを再生する。

	private void playSong() {
		try {
			mp.reset();
			mp.setDataSource(MEDIA_PATH + songs.get(currentPosition));
			mp.prepare();
			mp.start();

			mp.setOnCompletionListener(new OnCompletionListener() {
				public void onCompletion(MediaPlayer arg0) {
					nextSong();
				}
			});

		} catch (IOException e) {
		}
	}

次のミュージックを再生する。

	private void nextSong() {
		if (++currentPosition >= songs.size()) {
			currentPosition = 0;
		}
		playSong();
	}

receiverを追記

AndroidManifest.xml

    <application android:icon="@drawable/icon" android:label="@string/app_name">
		<receiver android:name=".MyMusicerProvider" >
    		<intent-filter>
        		<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
        		<action android:name="appwidget.mymusicer.action.play">
        		<action android:name="appwidget.mymusicer.action.next">
        	</intent-filter>
        	<meta-data android:name="android.appwidget.provider"
        		android:resource="@xml/musicer_widget" />
		</receiver>
    </application>

applicationタグ内にreceiverタグを追加して、名前はMyMusicerProviderで定義する。receiverタグ内に、まずintentタグを追加して、APPWIDGET_UPDATEアクションと自作のplayボタン、nextボタンのアクションを定義する。次にmeta タグを追加して、resourceにmusicer_widget.xmlを指定する。

MusicPlayer Widgetを実行する

 

SDCardが持っているエミュレータを作る

emulator.PNG

 

ミュージックファイルをエミュレータに入れる

sdcard.PNG

AppWidgetをHome Screenに追加する。

 

Home Screenで長押し、リストからWidgetsを選択する

add-1.PNG

 

リストからMyMusicerを選択する

add-2.png

 

作成したMusicPlayer Widgetが表示される

musicplayer.png

ミュージックを聴こう

 

playボタンを押すと、該当のミュージックを再生して、pauseボタンのイメージとなる

run-1.png

 

nextボタンを押すと、次のミュージックを再生して、ミュージック名も変わる

run-2.png

 

またplayボタン(pauseボタンのイメージ)を押すと、該当ミュージックを一時停止して、playボタンのイメージに戻る

run-3.png

AppWidgetをHome Screenからを削除する方法

 

消したいWidgetを長押しして選択状態で、ドラッグ&ドロップして削除する

delete.png

以上です。

この記事の執筆者

tomato 1歳 入社2年目

この人の会社をみる この人関連のイベントをさがす この人と一緒にはたらく

この日記にコメントする

(メールアドレスは公開されません。メールで返答が欲しい場合などに入力してください)

このエントリへのトラックバックURL

コメント

コメントはありません

トラックバック

トラックバックはありません

メンバー紹介

tunakan

tunakan

内臓が全般的に弱いです。データベースは苦手なのに変なデーターベースに当たることが多い気がします。

sugimaru

sugimaru

すぎまるです。22時のシンデレラです。

boy

boy

少年です。 18歳以下(嘘)でも立派に社員です。 よろしくおねがいします。