たぼさんの部屋

いちょぼとのんびり

T312 AppWidget 起動されたサービス側でリモートビューを制御(基本のみ)

f:id:donsuka_kk:20121217181428p:plain

Point

widgetはonUpdateでサービスを起動するだけ
サービス側でリモートビューを生成してウィジェット画面を制御する
ボタンのイベントをセットしてから、ウィジェット画面の「更新処理」は必須。
明示的インテントを使えば、マニフェストへのフィルタ追記が不要。

MWidget.java

package com.efolab.t312;

import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;

public class MWidget extends AppWidgetProvider {
	Intent intent;
	@Override
	public void onUpdate(Context context, AppWidgetManager appWidgetManager,
			int[] appWidgetIds) {
		// TODO Auto-generated method stub
		super.onUpdate(context, appWidgetManager, appWidgetIds);
		intent = new Intent(context , MService.class);
		intent.setAction("INIT");	//サービスクラスで初期処理を実行させるフラグをセット
		context.startService(intent);
	}

}

MService.java

package com.efolab.t312;

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

public class MService extends Service {
	private final String TAG ="MService::";
	private final String FILTER_BTN1 = "com.efolab.t312.BTN1_CLICK";
	private final String FILTER_BTN2 = "com.efolab.t312.BTN2_CLICK";
	private RemoteViews remoteviews;
	private Context context;
	@Override
	public IBinder onBind(Intent arg0) {
		// TODO Auto-generated method stub
		return null;
	}
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		//初期にだけ、INIT処理を実行する
		if(intent.getAction().equals("INIT")){
			init();
		}
		Toast.makeText(context,TAG+intent.getAction() , Toast.LENGTH_SHORT).show();
		/*
		 * イベント受信処理をここに記述する
		 */
		
		//ウィジェット画面の更新処理 : 必須
		AppWidgetManager manager = AppWidgetManager.getInstance(context);
		ComponentName widget = new ComponentName(context, MWidget.class);
		manager.updateAppWidget(widget, remoteviews);
		
		return super.onStartCommand(intent, flags, startId);
	}
	/*
	 * 初期化処理
	 * 一度だけ実行すればいい処理を記述しておく。
	 */
	private void init(){
		this.context = getApplicationContext();
		remoteviews = new RemoteViews(getPackageName(),R.layout.mwidget);
		/*
		 * 暗黙的インテント
		 * manifest.xmlへのfilter/action追記必要
		 */
		Intent intentBtn1 = new Intent();	//クラス指定なし
		intentBtn1.setAction(FILTER_BTN1);
		PendingIntent pendingBtn1 = PendingIntent.getService(context, 0, intentBtn1, 0);
		remoteviews.setOnClickPendingIntent(R.id.button1, pendingBtn1);
		/*
		 * 明示的インテント
		 * マニフェストへの記述不要
		 */
		Intent intentBtn2 = new Intent(context , this.getClass());	//明示的インテント
		intentBtn2.setAction(FILTER_BTN2);
		PendingIntent pendingBtn2 = PendingIntent.getService(context, 0, intentBtn2, 0);
		remoteviews.setOnClickPendingIntent(R.id.button2, pendingBtn2);	
		
	}

}

Manifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.efolab.t312"
    android:versionCode="1"
    android:versionName="1.0" >

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

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <receiver android:name="MWidget">
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
            </intent-filter>
            <meta-data android:name="android.appwidget.provider" android:resource="@xml/mwidget_info"/>
        </receiver>
        <service android:name="MService">
            <intent-filter>
                <action android:name="com.efolab.t312.BTN1_CLICK"/>
            </intent-filter>
        </service>
    </application>

</manifest>

mwidget_info.xml

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

</appwidget-provider>

mwidger.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#000000"
    android:orientation="horizontal" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="T312" />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button1" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button2" />

</LinearLayout>