アンドロイド - NotificationListenerを利用して、ノー情報取得

By JS | Last updated: November 10, 2018

NotificationListenerService

NotificationListenerServiceは、Notificationの情報を得ることができるオブジェクトです。 AndroidのSDKには、NotificationManagerに直接listenerを登録するコードは提供していません。情報を受けたい場合はNotificationListenerServiceを継承した新しいサービスを実装しなければします。

サービスの実装

以下のようにNotificationListenerServiceを継承して、次の二つのメソッドを実装する必要があります。

  • onNotificationPosted:新しいノフィケーションが追加されるときに呼び出されます。
  • onNotificationRemoved:ノーフィケーションが削除されるときに呼び出されます。

次のコードのように二つのメソッドが呼び出されると、ログが出力されるようにしました。

public class MyNotificationListener extends NotificationListenerService {
    public final static String TAG = "MyNotificationListener";

    @Override
    public void onNotificationRemoved(StatusBarNotification sbn) {
        super.onNotificationRemoved(sbn);

        Log.d(TAG, "onNotificationRemoved ~ " +
                " packageName: " + sbn.getPackageName() +
                " id: " + sbn.getId());
    }

    @Override
    public void onNotificationPosted(StatusBarNotification sbn) {
        super.onNotificationPosted(sbn);

        Notification notification = sbn.getNotification();
        Bundle extras = sbn.getNotification().extras;
        String title = extras.getString(Notification.EXTRA_TITLE);
        CharSequence text = extras.getCharSequence(Notification.EXTRA_TEXT);
        CharSequence subText = extras.getCharSequence(Notification.EXTRA_SUB_TEXT);
        Icon smallIcon = notification.getSmallIcon();
        Icon largeIcon = notification.getLargeIcon();

        Log.d(TAG, "onNotificationPosted ~ " +
                " packageName: " + sbn.getPackageName() +
                " id: " + sbn.getId() +
                " postTime: " + sbn.getPostTime() +
                " title: " + title +
                " text : " + text +
                " subText: " + subText);
    }

}

AndroidManifest設定

AndroidManifest.xmlは上記の実装したサービスを登録する必要があります。アンドロイドフレームワークのみアクセスできるようにサービスのパーミッションに BIND_NOTIFICATION_LISTENER_SERVICEを設定し、 下記のようなインテントフィルタを設定する必要があります。

<service android:name=".MyNotificationListener"
    android:label="My Notification Listener"
    android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
    <intent-filter>
        <action android:name="android.service.notification.NotificationListenerService" />
    </intent-filter>
</service>

パーミッションを設定する理由は...私パーミッションはSystemServer(system)のみ持つことができます。したがって3rd partyがそのサービスを実行することができず、ただNotificationManagerのみアクセスすることができます。

インテントフィルタを設定する理由は、そのactionにNotificationManagerが端末に登録されたサービスの検索に使用するためです。もしインテントフィルタをあのように登録しなければノーを通知されません。

ユーザーからの権限取得

これまでのサービスを実装しAndroidManifestに登録しました。最後には通知に関する情報を受信するユーザーの同意が必要です。

たまに3rd party appがノーフィケーションにidとpwを見せてくれたりします。 このようには通知は、個人情報に関連する部分ですのでノーフィケーション情報を受信するユーザーからの権限を与える必要があります。

実装方法は...まず、権限があることをチェックして、権限を受けるUIを実行して、ユーザーが自分のアプリに権限を与えるようにしてください。

次のコードは、現在、このアプリが権限を持っているかどうかチェックするためのコードです。

private boolean permissionGrantred() {
    Set<String> sets = NotificationManagerCompat.getEnabledListenerPackages(this);
    if (sets != null && sets.contains(getPackageName())) {
        return true;
    } else {
        return false;
    }
}

getEnabledListenerPackagesは、内部的にSettingsに保存されたstringを取得します。 そのstringは権限を持っているpackageNameを並べあり、Setオブジェクトにreturnされます。私たちは、リターンされたSetで、私のアプリのpackageNameがあるだけチェックします。

実装したアプリを起動する試みる

アプリを起動してみると、最初は権限がないため、権限を受けることができるActivityが実行されます。

notification-listener

UIで、私のアプリに権限を与えるNotificationManagerは私の実装したサービスを実行して、ノーフィケーションについての情報をサービスとして伝えてくれます。

ノフィケーションが登録されたり削除される以下のようログが出力されます。

11-10 14:23:51.579 3100-3100/com.codechacha.notificationlistener D/MyNotificationListener: onNotificationRemoved ~  packageName: com.google.android.setupwizard id: 5
11-10 14:23:51.692 3100-3100/com.codechacha.notificationlistener D/MyNotificationListener: onNotificationPosted ~  packageName: android id: 40 postTime: 1541827431588 title: Android Setup is using battery text : Tap for details on battery and data usage subText: null
11-10 14:23:51.703 3100-3100/com.codechacha.notificationlistener D/MyNotificationListener: onNotificationPosted ~  packageName: com.google.android.setupwizard id: 6 postTime: 1541827431588 title: Preparing for setup… text :  subText: null

まとめ

例としてNotificationListenerServiceを実装したアプリを作ってみました。二つのメソッドのみ実装みまし、NotificationListenerServiceはより多くの情報をcallback受ける関数が定義されています。必要な情報があれば追加で実装して使用ください。

メソッドの詳細については、Android developersで確認することができます。

参考

Related Posts

codechachaCopyright ©2019 codechacha