天天看點

Android通知監聽服務之NotificationListenerService使用篇

前言

本篇我們将介紹如何利用NotificationListenerService實作類似智能手表通知同步、微信自動搶紅包等功能。實作這些功能的原理其實就是監聽系統的通知服務,接下來我們來看該如何實作。

NotificationListenerService的使用

建立NotificationListenerService

在Android中如果我們想要監聽系統的通知,就需要實作一個服務,繼承自NotificationListenerService,建立NotificationMonitorService類,代碼如下所示。

class NotificationMonitorService : NotificationListenerService() {
    //收到通知時的回調
    override fun onNotificationPosted(sbn: StatusBarNotification) {
        super.onNotificationPosted(sbn)
    }

    //通知移除時的回調
    override fun onNotificationRemoved(sbn: StatusBarNotification?) {
        super.onNotificationRemoved(sbn)
    }
}      

這裡我們重寫onNotificationPosted方法和onNotificationRemoved方法,這兩個方法分别會在收到通知和通知被移除時調用。這裡我們着重來看onNotificationPosted方法。

在onNotificationPosted方法中有一個StatusBarNotification執行個體,通過這個執行個體我們可以擷取通知消息的包名、内容等。代碼如下所示。

class NotificationMonitorService : NotificationListenerService() {
    override fun onNotificationPosted(sbn: StatusBarNotification) {
        super.onNotificationPosted(sbn)
        val extras = sbn.notification.extras
        // 擷取接收消息APP的包名
        val notificationPkg = sbn.packageName
        // 擷取接收消息的擡頭
        val notificationTitle = extras.getString(Notification.EXTRA_TITLE)
        // 擷取接收消息的内容
        val notificationText = extras.getString(Notification.EXTRA_TEXT)
        Log.d("收到的消息内容包名:", notificationPkg)
        Log.d("收到的消息内容", "Notification posted $notificationTitle & $notificationText")
    }
}      

然後記得在配置檔案中添加這個Service的聲明,代碼如下所示。

<service android:name="com.example.myapplication.NotificationMonitorService"
    android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"
    android:exported="true">
    <intent-filter>
        <action android:name="android.service.notification.NotificationListenerService" />
    </intent-filter>
</service>      

建立好NotificationMonitorService之後,接下來我們就可以啟動這個服務了。

啟動服務

現在直接啟動服務,肯定是沒辦法監聽到系統通知的,在啟動服務前,我們應該授予App監聽系統通知的權限。

在AndroidManifest.xml中添權重限,代碼如下所示。

<uses-permission android:name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"/>      

啟動服務前判斷是否開啟了監聽通知的權限,如果沒有則跳轉到設定頁開啟,代碼如下所示。

if (NotificationManagerCompat.getEnabledListenerPackages(this).contains(packageName)){
    val intent = Intent(this,NotificationMonitorService::class.java)
    startService(intent)
 }else{
    startActivity(Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"))
 }      

如果沒有開啟,跳轉到的設定頁如下所示。

Android通知監聽服務之NotificationListenerService使用篇
Android通知監聽服務之NotificationListenerService使用篇

開啟了監聽通知權限,運作程式,列印日志如下所示。

Android通知監聽服務之NotificationListenerService使用篇

 對應的列印日志是,收到了來自微信的群聊消息,發了一個“強”。

當收到短信、來電等消息時,系統同樣會發送一個通知,我們可以根據收到的通知處理不同的業務。這裡感興趣的讀者可自行嘗試。接着我們來模拟實作自動搶紅包的功能。

實作自動搶紅包功能

這裡為了測試,曆盡千辛萬苦讓我老婆給我發了一個0.01的紅包,我們監聽到的内容為“[微信紅包]恭喜發财,大吉大利”。如下圖所示。

Android通知監聽服務之NotificationListenerService使用篇

 是以我們可以在收到消息時,通過監聽微信包名、以及消息内容來判斷是否收到了微信紅包來處理具體的操作。(不處理,别人故意發同樣的文字)。

if (notificationPkg.equals("com.tencent.mm")){
   if (notificationText.equals("[微信紅包]恭喜發财,大吉大利")){
      //收到微信紅包了
   }
}      

這樣我們隻需要在代碼處處理接下來的操作就可以了。其實我們的操作也很簡單,隻需要在監聽到有紅包時打開對應的微信頁面即可,代碼如下所示。

class NotificationMonitorService : NotificationListenerService() {
    override fun onNotificationPosted(sbn: StatusBarNotification) {
        super.onNotificationPosted(sbn)
        val extras = sbn.notification.extras
        // 擷取接收消息APP的包名
        val notificationPkg = sbn.packageName
        // 擷取接收消息的内容
        val notificationText = extras.getString(Notification.EXTRA_TEXT)
        if (notificationPkg.equals("com.tencent.mm")){
            if (notificationText.equals("[微信紅包]恭喜發财,大吉大利")){
                //收到微信紅包了
                val intent = sbn.notification.contentIntent
                intent.send()
            }
        }
    }
}      

這裡我們直接通過sbn拿到notification的intent,進行intent.send操作即可,運作程式,收到紅包後,頁面将自動跳轉到微信紅包頁面,結果如下圖所示。

寫在最後

繼續閱讀