Android系統開發 控制設備通知功能--INotificationManager的使用

前言

  INotificationManager是一個系統服務接口,它提供了訪問和管理 Android 系統中通知相關功能的方法。使用INotificationManager需要架framework包,另外應用需要系統簽名。

另外,你可能會被NotificationManager 與 NotificationManagerCompat 誤導。其實這2個是在應用開發中使用的通知管理服務,它們只支持當前開發應用的通知創建、通知權限查詢、通知取消。 它們與INotificationManager有本質的區別。

  而INotificationManager的實現類是NotificationManagerService(路徑:frameworks/base/services/core/java/com/android/server/notification/NotificationManagerService.java)。 利用INotificationManager可以在系統開發中控制設備全局的應用的通知顯示開關狀態、通知創建、全部通知查詢、通知取消。

在Android10原生設置中INotificationManager的代碼使用位置

  在具體瞭解INotificationManager的全部功能前,我們還是需要了解一下原生設置中INotificationManager的使用位置。我這裏拿出來舉例的是mtkSettings項目(聯發科的Android原生設置),其他原生設置可能會有些細微不同。

  首先在com.android.settings.notification目錄下,是設置處理通知相關類的全部目錄。

  在NotificationSettingsBase這個類是管理通知設置的基本類,包含了一些通知設置的基本方法。而它實例並且持有了關鍵的NotificationBackend,如下圖片:

而NotificationBackend持有了INotificationManager,圖片如下:

開啓關閉指定應用的通知

import android.app.INotificationManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.RemoteException;
import android.os.ServiceManager;

public class NotificationManagerUtil {

    /**
     * 設置通知啓用狀態
     * @param context
     * @param pkg
     * @param enabled
     */
    public static void setNotificationsEnabledForPackage(Context context, String pkg, boolean enabled) {
        try {
            getNotificationManager().setNotificationsEnabledForPackage(pkg, getUidForPackage(pkg, context), enabled);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    /**
     * 獲取uid
     * @param packageName
     * @param context
     * @return
     */
    public static int getUidForPackage(String packageName, Context context) {
        PackageManager pm = context.getPackageManager();
        try {
            ApplicationInfo appInfo = pm.getApplicationInfo(packageName, 0);
            return appInfo.uid;
        } catch (PackageManager.NameNotFoundException e) {
            // 應用程序未安裝
            return -1;
        }
    }

    private static INotificationManager getNotificationManager(){
        INotificationManager iNotificationManager = INotificationManager.Stub.asInterface(
                ServiceManager.getService(Context.NOTIFICATION_SERVICE));
        return iNotificationManager;
    }
}

查詢通知的啓用狀態


import android.app.INotificationManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.RemoteException;
import android.os.ServiceManager;

public class NotificationManagerUtil {

    /**
     * 查詢指定應用通知是否啓用(注意!此方法查詢結果存疑)
     */
    public static boolean areNotificationsEnabled(String pkg){
        try {
            return getNotificationManager().areNotificationsEnabled(pkg);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 查詢指定應用通知是否啓用
     */
    public static boolean areNotificationsEnabledForPackage(Context context, String pkg){
        try {
            return getNotificationManager().areNotificationsEnabledForPackage(pkg, getUidForPackage(pkg, context));
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 獲取uid
     * @param packageName
     * @param context
     * @return
     */
    public static int getUidForPackage(String packageName, Context context) {
        PackageManager pm = context.getPackageManager();
        try {
            ApplicationInfo appInfo = pm.getApplicationInfo(packageName, 0);
            return appInfo.uid;
        } catch (PackageManager.NameNotFoundException e) {
            // 應用程序未安裝
            return -1;
        }
    }

    private static INotificationManager getNotificationManager(){
        INotificationManager iNotificationManager = INotificationManager.Stub.asInterface(
                ServiceManager.getService(Context.NOTIFICATION_SERVICE));
        return iNotificationManager;
    }
}

獲取通知級別

/**
 * 獲取指定apk的通知級別,不同的級別可以讓通知的打擾程度不同
 */
public static void getPackageImportance(){
    try {
        int level = getNotificationManager().getPackageImportance("你的包名");
        Log.e("zh", "level = " + level);
    } catch (RemoteException e) {
        e.printStackTrace();
    }
}

獲取某個應用的全部通知數據

/**
 * 獲取指定apk的全部通知數據
 */
public static void getStatusBarNotifications(){
    try {
        StatusBarNotification[] statusBarNotification = getNotificationManager().getActiveNotifications("你的包名");
        for (StatusBarNotification item : statusBarNotification){
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                Log.e("zh", "getPackageImportance: " + item.getNotification().toString());
                Log.e("zh","item = " + item.toString());
                Log.e("zh","getKey = " + item.getKey());
                Log.e("zh","getTag = " + item.getTag());
            }
        }
    } catch (RemoteException e) {
        e.printStackTrace();
    }
}

 

待續....

 

end

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章