Android 2.1/3.2 ステータスバー通知の取得

NotificatioinManagerからは現在の通知を取得できないが、AccessibilityServiceを使用すれば他のアプリケーションから通知されるNotifycationをイベントとして取得できる。

▼ステータスバー通知 Notification / NotificationManager の特徴
・NotificationMaganerにNotificationを追加するとステータスバーに通知される
・NotificationにはViewを指定できる
・NofiticationManagerでは追加/上書/削除のみを行える
他アプリの通知を取得できないように制限されている。

▼ユーザ補助サービス AccessibilityServiceの特徴
・他アプリでの操作の一部や通知内容の一部を取得できる
・テキスト入力内容まで取得できてしまうため安易に利用できない
・通常のアプリケーションとは別に設定→ユーザ補助からサービスを許可/実行する必要がある

▼AccessibilityServiceのサンプルコード
・必要最低限のサンプルコード (理解には最良のサンプル)
本家和訳サイト
・Android 3.2で実装したところ、Toastも Notificationとして受け取って自己ループに陥ったので修正

▼AccessibilityServiceからの受け渡し
・SharedPreferencesを介してStringで受け渡す例 (抜粋)
サービスとの通信が不要で、ユーザ補助のON/OFF切り替えを認識せずに受信可能。

public class StrAccessibilityService extends AccessibilityService {

	public static final String SHARED_ACCESS_PREFS="str_access";
	public static final String ACCESS_PREFS_KEY="access_key";

	private SharedPreferences mPrefAccess;
	public static final boolean DEBUG=true;	// 通知のToast表示フラグ

	@Override
	public void onCreate() {
		super.onCreate();
	}

	@Override
	public void onServiceConnected() {
		mPrefAccess = getSharedPreferences(SHARED_ACCESS_PREFS, MODE_PRIVATE);

		AccessibilityServiceInfo info = new AccessibilityServiceInfo();
		info.eventTypes = AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED;
		info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
		info.notificationTimeout = NOTIFICATION_TIMEOUT_MILLIS;
		info.flags = AccessibilityServiceInfo.DEFAULT;
		setServiceInfo(info);
	}

	@Override
	public void onAccessibilityEvent(AccessibilityEvent event) {
		int eventType = event.getEventType();
		switch (eventType) {
		case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED :
			if(DEBUG) Log.d("StrAccessibilityService", "Access NOTIFIFY:"+event.getText());
			putPreferences(event);
			break;
		}
	}

	private void putPreferences(AccessibilityEvent event){// Preferenceを変更
		SharedPreferences.Editor editor = mPrefAccess.edit();
		editor.putString(ACCESS_PREFS_KEY, ""+event.getText());
		editor.commit();
	}

}

取得側クラスは SharedPreferences.OnSharedPreferenceChangeListener を implement し、 onSharedPreferenceChanged で取得する。

	public static final String SHARED_ACCESS_PREFS="str_access";
	public static final String ACCESS_PREFS_KEY="access_key";
	private SharedPreferences mPrefAccess;

	@Override
	public void onCreate() {
		super.onCreate();
		mPrefAccess = getSharedPreferences(SHARED_ACCESS_PREFS, MODE_PRIVATE);
		mPrefAccess.registerOnSharedPreferenceChangeListener(this);
	}

	@Override	// StrAccessibilityService#putPreferencesによりコールされる
	public void onSharedPreferenceChanged(SharedPreferences prefs,String key) {
		String access_text = prefs.getString(ACCESS_PREFS_KEY,null);
		// (ここから処理)
	}