Android系统开发 控制设备通知功能--INotificationManager的使用

发布时间 2023-05-06 18:12:36作者: 观心静

前言

  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();
    }
}
  1. 发送通知:INotificationManager 提供了 enqueueNotification() 方法,该方法用于向系统发送一个新的通知。该方法接受多个参数,包括通知的包名、通知 ID、通知对象等。例如,以下代码演示了如何使用 INotificationManager 发送一个简单的通知:
java
INotificationManager notificationManager = INotificationManager.Stub.asInterface(ServiceManager.getService("notification")); Notification notification = new NotificationCompat.Builder(context, "channel_id") .setContentTitle("This is title") .setContentText("This is content") .setSmallIcon(R.drawable.ic_notification) .build(); notificationManager.enqueueNotification("com.example.packageName", "app_name", notification, null, null, 0);
  1. 取消通知:INotificationManager 提供了 cancelNotification()cancelAllNotifications() 方法,分别用于取消指定 ID 的通知和取消所有通知。例如,以下代码演示了如何使用 INotificationManager 取消指定 ID 的通知:
java
INotificationManager notificationManager = INotificationManager.Stub.asInterface(ServiceManager.getService("notification")); notificationManager.cancelNotification("com.example.packageName", notificationId, 0, UserHandle.USER_CURRENT);
 
  1. 清除通知:INotificationManager 提供了 cancelNotificationWithTag()cancelNotificationsFromListener() 方法,分别用于清除指定标签的通知和清除指定监听器注册的所有通知。例如,以下代码演示了如何使用 INotificationManager 清除指定标签的通知:
java
INotificationManager notificationManager = INotificationManager.Stub.asInterface(ServiceManager.getService("notification")); notificationManager.cancelNotificationWithTag("com.example.packageName", "tag", 0, UserHandle.USER_CURRENT);
  1. 获取通知渠道:INotificationManager 提供了 getNotificationChannel()getNotificationChannels() 方法,用于获取指定 ID 或包名的通知渠道。例如,以下代码演示了如何使用 INotificationManager 获取指定 ID 的通知渠道:
java
INotificationManager notificationManager = INotificationManager.Stub.asInterface(ServiceManager.getService("notification")); NotificationChannel channel = notificationManager.getNotificationChannel("channel_id", "com.example.packageName", UserHandle.USER_CURRENT);
  1. 修改通知渠道:INotificationManager 提供了 createNotificationChannel()deleteNotificationChannel()updateNotificationChannel() 等方法,用于创建、删除和更新通知渠道。例如,以下代码演示了如何使用 INotificationManager 创建一个新的通

 

end