1. 程式人生 > >Android使用NotificationListenerService獲取通知相關資訊

Android使用NotificationListenerService獲取通知相關資訊

前言

我們可能需要監聽通知欄,來獲取系統通知,然後去得到通知的相關資訊,或者我們可能需要知道某一個通知是否處於活動狀態還是已經被使用者處理了!

概況

在Android4.4之前,我們更多的是通過反射來獲取通知的相關資訊!NotificationListenerService是在Android4.3中新增的,當系統收到新的通知或者通知被刪除時,會觸發NotificationListenerService的回撥方法。而且在4.4中加入了Notification.extras欄位,可以用來獲取通知的具體資訊!

NotificationListenerService的使用

①新建NotificationMonitor繼承NotificationListenerService,然後重寫下邊兩個方法

public class NotificationMonitor extends NotificationListenerService {  
        @Override  
        public void onNotificationPosted(StatusBarNotification sbn) {
              //有新通知新增的時候呼叫  
              Log.e("onNotificationPosted","posted");  
        }  

        @Override  
        public void
onNotificationRemoved(StatusBarNotification sbn) { //通知被移除的時候呼叫 Log.e("onNotificationRemoved","posted"); } }

②在AndroidManifest.xml中註冊Service並宣告相關許可權

<service 
    android:name=".NotificationMonitor"
    android:label="給這個服務一個名字"
    android:permission
="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
<intent-filter> <action android:name="android.service.notification.NotificationListenerService" /> </intent-filter> </service>

③然後開啟通知監聽許可權
將程式安裝到手機上之後,然後在設定->安全->通知讀取許可權,找到你上邊服務對應的名字,把這個勾選上!

需要注意的是:如果你的手機上面沒有安裝需要NotificationListenerService這個許可權的應用的時候,設定中是不會出現通知讀取許可權這一選項的!

這樣就能監聽到手機中的通知了,當新通知彈出或者通知被移除都能被上面兩個方法監聽到!

如何知道許可權是否開啟

上邊說監聽通知必須開啟獲取通知許可權,這裡要說明的一點就是,如果你的應用是第一次安裝,那麼直到你把獲取通知許可權勾選上的那一秒才開始能夠監聽通知

獲取通知許可權是:enabled_notification_listeners
之前我們來看這一許可權是否開啟,可能是這樣:

private static final String ENABLED_NOTIFICATION_LISTENERS = "enabled_notification_listeners";

    private boolean isNotificationListenerEnabled() {
        String pkgName = getPackageName();
        final String flat = Settings.Secure.getString(getContentResolver(),
                ENABLED_NOTIFICATION_LISTENERS);
        if (!TextUtils.isEmpty(flat)) {
            final String[] names = flat.split(":");
            for (int i = 0; i < names.length; i++) {
                final ComponentName cn = ComponentName.unflattenFromString(names[i]);
                if (cn != null) {
                    if (TextUtils.equals(pkgName, cn.getPackageName())) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

現在,我們可以使用v4包中的NotificationManagerCompat來獲取,非常簡單:

 public boolean isNotificationListenerEnabled(Context context) {
        Set<String> packageNames = NotificationManagerCompat.getEnabledListenerPackages(this);
        if (packageNames.contains(context.getPackageName())) {
            return true;
        }
        return false;
    }

那麼如果檢測到沒有開啟這一許可權,能否在程式碼中跳轉到設定介面呢?答案是可以:
開啟獲取通知許可權的設定對應的action是:
android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS

private static final String ACTION_NOTIFICATION_LISTENER_SETTINGS = "android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS";

    private void openNotificationAccess() {
        startActivity(new Intent(ACTION_NOTIFICATION_LISTENER_SETTINGS));
    }

之後我們就能獲取通知的相關資訊了,比如label,icon等具體的內容:

可以參考這篇文章,裡邊有4.4使用Notification.extras,和4.4之前通過反射獲取的內容!
NotificationListenerService的那些事兒

可能出現的問題

有的時候,我們也使用上邊配置了,但是會出現監聽沒有反應的情況!可能就是我們這一個服務被幹掉了!
搜到這麼一個解決辦法,能有些幫助,它的方法是寫一個常駐服務,來確保我們這個監聽服務一直保持執行
Cannot get the NotificationListenerService class to work

獲取通知狀態

獲取通知狀態可以通過呼叫:getActiveNotifications()這個方法來實現,它返回一個StatusBarNotification[]的陣列,我們檢視原始碼可以發現,不僅NotificationListenerService中可以呼叫這個方法!其實之前的NotificationManagerService中也有這個方法,只不過這個方法外部無法呼叫!
其實追究到底,都是呼叫的INotificationManager#getActiveNotifications()中的方法,看名字可以看出是一個AIDL的服務介面,具體的實現都交給底層了!原始碼中涉及最多的IPC通訊!

另外,在Android 6.0之後,也就是api23之後,官方在NotificationManager中添加了這一方法getActiveNotifications(),我們可以使用NotificationManager直接呼叫該方法來獲取通知狀態!檢視其原始碼發現也是呼叫的底層的程式碼,跟上邊是一樣的!
當然,這樣就更加方便了!

相關推薦

Android使用NotificationListenerService獲取通知相關資訊

前言 我們可能需要監聽通知欄,來獲取系統通知,然後去得到通知的相關資訊,或者我們可能需要知道某一個通知是否處於活動狀態還是已經被使用者處理了! 概況 在Android4.4之前,我們更多的是通過反射來獲取通知的相關資訊!NotificationList

使用gethostname()函式和gethostbyname()函式獲取主機相關資訊

gethostname():返回本地主機的標準主機名 原型如下: #include <unistd.h> int gethostname(char *name, size_t len); 引數說明: 這個函式需要兩個引數: 接收緩衝區name,其長度必須為len位元組或是更長

JS獲取 URL相關資訊,引數

Location 物件包含有關當前 URL 的資訊。 Location 物件是 Window 物件的一個部分,可通過 window.location 屬性來訪問。 hash 設定或返回從井號 (

請教一個能在WinPE環境下獲取系統相關資訊的程式碼

來上海將近2年了,然而我已經換過了3家公司,也許很多人都很懵逼,這也太頻繁了吧!你有啥不滿足的?我想如果是一個面試官,一聽2年內換3家 ,肯定是不想要這個人的。所以我在面試第四家的時候,我就把我第三家的工作經歷去掉了,沒寫第三家,也許有人會站在道德的制高點說我了,說我造假什麼

獲取數字證書相關資訊,證書有效性驗證,RSA加密和解密功能之獲取證書相關資訊

//公鑰 private PublicKey pk; /** 後臺將證書以byte陣列的形式傳入 * @param bytes,數字證書crt傳入的byte陣列 * @return */ public InfoEntity getCertificateInfo(

獲取裝置相關資訊工具包

拿走不謝 在使用springboot獲取螢幕引數時,可能會報關於headless為NULL的錯誤,不要慌,這樣來:只需要在啟動的application中替換main函式內容為: @SpringBootApplication public class Ad

android--------根據檔案路徑使用File類獲取檔案相關資訊

Android通過檔案路徑如何得到檔案相關資訊,如 檔名稱,檔案大小,建立時間,檔案的相對路徑,檔案的絕對路徑等。如圖:public class MainActivity extends Activity { private String path = "/storage

iOS獲取裝置相關資訊

UIDevice *device = [UIDevicenew]; NSLog(@"%@ %@ %@ %@ %@",device.name,device.model,device.localizedModel,device.systemName,device.syste

iOS 獲取裝置相關資訊

//裝置相關資訊的獲取 NSString *IMEI = (NSString *)[[UIDevice currentDevice] identifierForVendor]; NSLo

獲取裝置相關資訊

// 獲取螢幕 DisplayMetrics dm2 = getResources().getDisplayMetrics(); float density = dm2.density; // 螢幕密度(畫素比例:0.75/1.0/1.5

java身份證合法性校驗並獲取並根據身份證號提取身份證相關資訊

原文地址:https://blog.csdn.net/ycb1689/article/details/52352147   /** * 身份證前6位【ABCDEF】為行政區劃數字程式碼(簡稱數字碼)說明(參考《GB/T 2260-2007 中華人民共和國行政區劃程式碼》): *

Windows資源管理器相關資訊獲取

原文連結 翻譯參考 有的時候,軟體開發是創造新的東西,不過更常見的是把現有的東西組合到一起。今天的難題就屬於後一種。 給定一個視窗控制代碼,你可以判定:(1)是否是一個資源管理器視窗,如果是,那麼(2)它正在顯示哪個資料夾,而且(3)當前焦點在哪一項上。 這其實不是一件難事。你只

25. 獲取員工其當前的薪水比其manager當前薪水還高的相關資訊

題目描述 獲取員工其當前的薪水比其manager當前薪水還高的相關資訊,當前表示to_date='9999-01-01', 結果第一列給出員工的emp_no, 第二列給出其manager的manager_no, 第三列給出該員工當前的薪水emp_salary, 第四列給該員工對應的manager

Android獲取手機版本號、品牌等 相關資訊工具類

主要有,獲取手機系統版本,獲取手機品牌、獲取軟體版本資訊、獲取螢幕尺寸寬高(包含和不包含虛擬鍵)以及獲取手機ip地址 public class DeviceUtils { /** * 品牌 */ public static String getDevic

資料庫SQL實踐25:獲取員工其當前的薪水比其manager當前薪水還高的相關資訊

思想: 題目要求獲取員工其當前的薪水比其manager當前薪水還高的相關資訊,當前表示to_date='9999-01-01', 結果第一列給出員工的emp_no, 第二列給出其manager的manager_no, 第三列給出該員工當前的薪水emp_salary, 第四列給該員工對應的mana

django views.py檢視 獲取使用者請求相關資訊以及請求頭

    請求的其他資訊 使用者發來請求時候,不僅發來資料,也把請求頭也發過來       在views.py 怎麼找請求資料? request是一個物件,這個物件封裝很多資訊,可以先查這個物件的類   print(type(r

列舉pc硬體裝置並獲取相關資訊

#include <windows.h> #include <setupapi.h> #include <devguid.h> #pragma comment(lib, "setupapi") void GetDeviceInfo(

獲取本機中python模組相關資訊

不同於 C++、Java、C# namespace 僅作為符號隔離字首,Python 模組是執行期物件。模組對應同名原始碼檔案,為成員提供全域性名字空間。 模組物件 模組物件有幾個重要屬性: name: 模組名 .,在 sys.modules 中以此為主鍵。 fil

資料庫SQL實戰 --10.獲取所有部門中當前員工薪水最高的相關資訊

題目描述 獲取所有部門中當前員工薪水最高的相關資訊,給出dept_no, emp_no以及其對應的salary CREATE TABLE `dept_emp` ( `emp_no` int(11) NOT NULL, `dept_no` char(4) NOT

資料庫SQL實戰12:獲取所有部門中當前員工薪水最高的相關資訊

思想: 題目要求獲取所有部門中當前員工薪水最高的相關資訊,給出dept_no, emp_no以及其對應的salary。首先通過條件d.to_date = '9999-01-01'找出所有部門當前員工,然後通過條件s.to_date = '9999-01-01'找出各員工當前