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