スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Android Serviceに独自Interfaceを実装

『Serviceに独自Interface実装』	
・バックグラウンドで処理しているServiceを、ActivityのUIで操作します。
例として、音楽プレーヤーのようにバックグラウンドで動作している処理を、
「再生・一時停止」等のUIで操作します。


■バックグラウンドで処理するServiceで、現在時刻をステータスバー・通知へ表示。
また、テキストにフォーマットを指定することで、現在時刻の表示フォーマットを変更する。
1.Serviceを拡張するinterfaceクラスの生成
・Serviceを拡張するためには「.aidl」ファイルを作成します。
以下のように実装するメソッドを記述します。
○IDatetimeService.aidl
1:
2: package android.datetime.now; ①
3:
4: interface IDatetimeService{
5:
6: void start(); ②
7: void stop();
8: void change(String line);
9: }
10:
①実装するクラスとパッケージ文を同じにすること
②独自実装するメソッドを記述する。今回はstart、stop、changeとする
・「.aidl」ファイルを保存すると「IDatetimeService.java」ファイルが作成されます。
○IDatetimeService.java
1:
2: ・・・省略・・・
3:
4: public void start() throws android.os.RemoteException;
5: public void stop() throws android.os.RemoteException;
6: public void change(java.lang.String line) throws android.os.RemoteException;
7:
8: ・・・省略・・・
9:



自動生成されたInterfaceクラスに定義したメソッドが作成されます。
2.独自メソッドを外部Activityから利用する
・Serviceに独自メソッドを外部で利用できるようする
○DatetimeServiceクラス(Service)
1: package android.datetime.now;
2:
3: import java.text.SimpleDateFormat;
4: import java.util.Date;
5: import android.app.Notification;
6: import android.app.NotificationManager;
7: import android.app.PendingIntent;
8: import android.app.Service;
9: import android.content.Intent;
10: import android.os.Handler;
11: import android.os.IBinder;
12: import android.os.Message;
13: import android.os.RemoteException;
14: import android.util.Log;
15:
16: public class DatetimeService extends Service {
17: private static final int ID = 0; // Notificationの識別子
18: private static final int UPDATE = 1; // Handlerの識別子
19: private NotificationManager mNotifMan; // ステータスバー
20: private long mInterval = 1000; // =10秒
21: private boolean mRunning = false;
22:
23: private String DATE_FORMAT = "";
24:
25: @Override
26: public void onCreate() {
27: super.onCreate();
28: Log.d("Datetime", "onCreate");
29: mRunning = true;
30: // getSystemServiceはシステムレベルのサービスのハンドルを返す
31: mNotifMan = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
32: }
33:
34: @Override
35: public void onStart(Intent it, int id) {
36: super.onStart(it, id);
37: Log.d("Datetime", "onStart");
38: if (!mHandler.hasMessages(UPDATE))
39: startCountDown();
40: }
41:
42: @Override
43: public void onDestroy() {
44: super.onDestroy();
45: Log.d("Datetime", "onDestroy");
46: mNotifMan.cancel(ID);
47: mHandler.removeMessages(UPDATE);
48: mRunning = false;
49: }
50:
51: // マルチスレッド化に必要
52: private Handler mHandler = new Handler() {
53: public void handleMessage(Message msg) { // HandlerのhandleMessageをオーバーライド
54: Log.d("Datetime", "handleMessage");
55: // 現在の時刻を渡す
56: showNotification();
57: // 再帰的にhandleMessageメソッドを呼出す
58: if (mRunning)
59: mHandler.sendEmptyMessageDelayed(UPDATE, mInterval); // 一定期間ごとに処理を実行
60: }
61: };
62:
63: private void startCountDown() {
64: Log.d("Datetime", "startCountDown");
65: mHandler.sendEmptyMessage(UPDATE); // sendEmptyMessageはhandleMessageメソッドを呼び出す
66: }
67:
68: public void stopCountDown() {
69: mNotifMan.cancel(ID); // 通知領域から削除
70: mHandler.removeMessages(UPDATE);
71: }
72:
73: private void showNotification() {
74: Log.d("Datetime", "showNotification");
75: String lastSec = today(DATE_FORMAT); // 日付生成
76: // 1.アイコン2.表示文字列3.通知時間
77: Notification notif = new Notification(R.drawable.icon, lastSec, 0); // 通知情報
78: // DatetimeNow Activityクラスを設定
79: Intent it = new Intent(this, DatetimeNow.class);
80: // Activityをペンディングする
81: PendingIntent pit = PendingIntent.getActivity(this, 0, it, 0);
82: // 通知領域の表示の設定
83: // 1.Context 2.アプリ名 3.説明文 4.実行PendingIntent
84: notif.setLatestEventInfo(this, "現在時刻", lastSec, pit);
85: mNotifMan.notify(ID, notif);// 通知
86: }
87:
88: // Service接続があると呼ばれる
89: @Override
90: public IBinder onBind(Intent intent) {
91: Log.d("Datetime", "onBind");
92: // return null;
93: return mServiceIF; // 操作オブジェクト(Stubオブジェ)を返す ①
94: // 外部のActivityでServiceを操作できる
95: }
96:
97: // 操作オブジェクトの生成
98: private IDatetimeService.Stub mServiceIF = new MyStub(); ②
99:
100: private class MyStub extends IDatetimeService.Stub { ③
101: // aidlファイルのメソッドを実装する
102: public void start() throws RemoteException {
103: Log.d("Datetime", "MyStubstart()");
104: if (!mHandler.hasMessages(UPDATE)) {
105: startCountDown();
106: }
107: }
108:
109: public void stop() throws RemoteException {
110: Log.d("Datetime", "MyStubstop()");
111: stopCountDown();
112: }
113:
114: public void change(String line) throws RemoteException {
115: Log.d("Datetime", "MyStubchange()");
116: DATE_FORMAT = line;
117: }
118: }
119:
120: public static String today(String format) {
121: Date date1 = new Date();
122: if (format == null || format.equals("")) {
123: format = "yyyy/MM/dd";
124: }
125: SimpleDateFormat sdf = new SimpleDateFormat(format);
126: return sdf.format(date1);
127: }
128 }



3.外部Activityでの実装
1: package android.datetime.now;
2:
3: import android.app.Activity;
4: import android.content.ComponentName;
5: import android.content.Intent;
6: import android.content.ServiceConnection;
7: import android.os.Bundle;
8: import android.os.IBinder;
9: import android.util.Log;
10: import android.view.View;
11: import android.view.View.OnClickListener;
12: import android.widget.Button;
13: import android.widget.EditText;
14:
15: public class DatetimeNow extends Activity {
16: private IDatetimeService mServiceIF; // Serviceオブジェクト
17: private ServiceConnection mServiceConn; // リスナーオブジェクト
18:
19: @Override
20: public void onCreate(Bundle savedInstanceState) {
21: super.onCreate(savedInstanceState);
22: setContentView(R.layout.main);
23:
24: Button start = (Button) findViewById(R.id.start_btn);
25: Button end = (Button) findViewById(R.id.stop_btn);
26: final Intent it = new Intent(this, DatetimeService.class); ①
27: start.setOnClickListener(new OnClickListener() {
28: @Override
29: public void onClick(View v) {
30: Log.d("Datetime", "startonClick()");
31:
32: // テキスト内容
33: final String line = ((EditText) findViewById(R.id.edittext))
34: .getText().toString();
35:
36: if (mServiceIF == null) {
37: // Serviceに接続していない
38: startService(it); // Service起動 ②
39: mServiceConn = new ServiceConnection() { ③
40:
41: @Override
42: public void onServiceDisconnected(ComponentName name) {
43: Log.d("Datetime", "onServiceDisconnected()");
44: mServiceIF = null;
45: }
46:
47: // ActivityがServiceへ接続完了時にCall
48: @Override
49: public void onServiceConnected(ComponentName name, ⑤
50: IBinder service) {
51: Log.d("Datetime", "onServiceConnected()");
52: mServiceIF = IDatetimeService.Stub
53: .asInterface(service);
54: startDatetimeService(line);
55: }
56: };
57: // 1.接続するIntent 2.ActivityがServiceと接続したときにCallされるリスナー
58: // 3.BIND_AUTO_CREATE
59: Log.d("Datetime", "bindService()"); ④
60: bindService(it, mServiceConn, BIND_AUTO_CREATE); // ActivityからServiceに接続
61: } else {
62: startDatetimeService(line);
63: }
64:
65: }
66: });
67: end.setOnClickListener(new OnClickListener() {
68: @Override
69: public void onClick(View v) {
70: Log.d("Datetime", "endonClick()");
71: try {
72: if (mServiceIF != null) {
73: // stopService(it);
74: mServiceIF.stop(); // 処理停止
75: mServiceIF = null;
76: unbindService(mServiceConn); // Service切断
77: }
78: } catch (Exception ex) {
79:
80: }
81: Log.d("Datetime", "stopService()");
82: stopService(it); // Service終了
83: }
84: });
85: }
86:
87: public void startDatetimeService(String line) {
88: try {
89: Log.d("Datetime", "startDatetimeService()");
90: mServiceIF.change(line); ⑥
91: mServiceIF.start();
92: } catch (Exception ex) {
93:
94: }
95: }
96:
97: public void onStart() {
98: super.onStart();
99: Log.d("Datetime", "onStart()");
100: }
101:
102: public void onStop() {
103: super.onStop();
104: Log.d("Datetime", "onStop()");
105: if (mServiceIF != null) {
106: unbindService(mServiceConn);
107: }
108: }
109 }



①Intentで接続クラス(Service)を指定
②Serviceを開始します
③ServiceConnectionを生成。2つのメソッドをオーバーライド
④bindServiceを利用し、ActivityからServiceに接続します。
第一引数はCallするServiceを実装したIntent
第二引数はActivityとServiceが接続されたときにCallされるServiceConnectionリスナー
第三引数の「BIND_AUTO_CRERATE」は接続先のServiceが存在しない場合、自動でServiceを起動する設定です。
⑤ActivityとServiceが接続されると呼ばれるメソッド
IDatetimeService.Stub.asInterface(service)でonBindメソッドが返すMyStubオブジェを受け取り
mServiceIFに格納。この後はこのmServiceIFを通して「start・stop・change」のメソッドを
呼び出すことができます。
⑥mServiceIFを通してメソッドを実行する。


○main.xml
1: <?xml version="1.0" encoding="utf-8"?>
2: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3: android:orientation="vertical"
4: android:layout_width="fill_parent"
5: android:layout_height="fill_parent"
6: >
7: <EditText android:id="@+id/edittext"
8: android:layout_width="fill_parent"
9: android:layout_height="wrap_content"
10: android:text=""
11: />
12: <Button android:id="@+id/start_btn"
13: android:layout_width="fill_parent"
14: android:layout_height="wrap_content"
15: android:text="start"
16: />
17: <Button android:id="@+id/stop_btn"
18: android:layout_width="fill_parent"
19: android:layout_height="wrap_content"
20: android:text="stop"
21: />
22: </LinearLayout>
23:


■実行結果
ステータスバーに現在日時が表示
image002 (8)


出力フォーマットを変更して表示
image004 (4)


スポンサーサイト

コメントの投稿

非公開コメント

おすすめアプリ
カテゴリ
最新記事
リンク
アクセスカウンター
アクセス解析
imobile
i-mobile
i-mobile
i-mobile
i-mobile
i-mobile
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QR
Amazon
Androidお勧め参考書
EC studio
商品
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。