たぼさんの部屋

いちょぼとのんびり

SECTION233 バインドを利用してサービスを起動する

f:id:donsuka_kk:20121211144723p:plainf:id:donsuka_kk:20121211144727p:plainf:id:donsuka_kk:20121211144730p:plain

バインドによってサービスを起動するには

AIDL(Android Interface Definition Language)というプロセス間で情報を交換の際の形式を
宣言し、定義しますが、実装の際には以下の手続きが必要です。

  • AIDLファイルを定義して作成(ファイル名の拡張子は.aidl)
  • AIDLファイルからインターフェースを生成
  • サービスにインターフェースの機能を実装する
  • アクティビティに ServiceConnection インターフェースを実装したクラスを作成
  • アクティビティにサービスへバインドする処理を記述

このサンプルでは、ISampleServiceというインターフェース名を持つAIDLファイルを作成し、
サービスであるBindService.javaにサービスの実体を実装しています。
次にアクティビティであるMain.javaにServiceConnectionインターフェースを実装したクラスを作成し、サービスをバインドしています。

ISampleService.aidl

package com.efolab.s233;

interface ISampleService{
	String setMessage(String message);
}

Main.java

package com.efolab.s233;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Toast;

public class Main extends Activity {
	Context context;
	LinearLayout base;
	EditText et;
	Button btn;
	//サービスの宣言
	private ISampleService service;
	@Override
	public void onCreate(Bundle savedInstanceState) {
	    super.onCreate(savedInstanceState);
	
	    context = getApplicationContext();
	    base = new LinearLayout(context);
	    base.setOrientation(LinearLayout.VERTICAL);
	    setContentView(base);
	    
	    et = new EditText(context);
	    btn = new Button(context);
	    btn.setOnClickListener(bindListener);
	    btn.setText("サービスへデータを送信");
	    
	    base.addView(et);
	    base.addView(btn);
	    
	    //サービスのバインド処理
	    Intent intent = new Intent(ISampleService.class.getName());
	    context.bindService(intent, conn , Context.BIND_AUTO_CREATE);
	    
	}
	//ServiceConnectionインターフェースを実装したクラスの作成
	private ServiceConnection conn = new ServiceConnection(){

		@Override
		public void onServiceConnected(ComponentName componentName, IBinder binder) {
			// TODO Auto-generated method stub
			//binder からサービスを取得
			service = ISampleService.Stub.asInterface(binder);
		}

		@Override
		public void onServiceDisconnected(ComponentName arg0) {
			// TODO Auto-generated method stub
			
		}
		
	};
	//サービスへのメッセージ送信処理
	private OnClickListener bindListener = new OnClickListener() {
		
		@Override
		public void onClick(View v) {
			// TODO Auto-generated method stub
			try{
				//サービスへのメッセージ送信とサービスkらの受信処理
				String response = service.setMessage(et.getText().toString());
				Toast.makeText(context, response, Toast.LENGTH_SHORT).show();
			}catch(RemoteException e){
				e.printStackTrace();
			}
		}
	};
	@Override
	protected void onDestroy(){
		super.onDestroy();
		//サービスをアンバインドする
		context.unbindService(conn);
	}

}

BindService.java

package com.efolab.s233;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.widget.Toast;

public class BindService extends Service {
	Context context;
	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		this.context = getApplication();
		Toast.makeText(context, "サービスを開始しました", Toast.LENGTH_SHORT).show();
		return mSampleService;
	}
	private final ISampleService.Stub mSampleService = new ISampleService.Stub() {
		
		@Override
		public String setMessage(String message) throws RemoteException {
			// TODO Auto-generated method stub
			//受け取ったメッセージを変更してアクティビティへ返す
			return "[受信]"+message;
		}
	};
	@Override
	public void onDestroy(){
		super.onDestroy();
		Toast.makeText(context, "サービスを終了しました", Toast.LENGTH_SHORT).show();
	}

}

Manifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.efolab.s233"
    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" >
        <activity android:name="Main">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <service android:name="BindService" android:process=":remote">
            <intent-filter>
                <action android:name="com.efolab.s233.ISampleService"/>
            </intent-filter>
        </service>
    </application>

</manifest>