Android读取通知栏消息数处理消息
Posted Vigibord
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android读取通知栏消息数处理消息相关的知识,希望对你有一定的参考价值。
概况
简介
android在4.3的版本中(即API 18)加入了NotificationListenerService,根据SDK的介绍可以知道,当系统收到新的通知或者通知被删除时,会触发NotificationListenerService的回调方法。同时在Android 4.4 中新增了Notification.extras 字段,也就是说可以使用NotificationListenerService获取系统通知具体信息,这在以前是需要用反射来实现的。
主要类介绍
对于系统通知,第三方APP使用NotificationListenerService主要目的是为了获取系统通知相关信息,主要包括:通知的新增和删除,获取当前通知数量,通知内容相关信息等。这些信息可以通过NotificationListenerService类提供的方法以及StatusBarNotification类对象来获取。
NotificationListenerService主要方法(成员变量):
cancelAllNotifications() :删除系统中所有可被清除的通知;
cancelNotification(String pkg, String tag, int id) :删除具体某一个通知;
getActiveNotifications() :返回当前系统所有通知到StatusBarNotification[]数组;
onNotificationPosted(StatusBarNotification sbn) :当系统收到新的通知后出发回调;
onNotificationRemoved(StatusBarNotification sbn) :当系统通知被删掉后出发回调;StatusBarNotification主要方法(成员变量):
getId():返回通知对应的id;
getNotification():返回通知对象;
getPackageName():返回通知对应的包名;
getPostTime():返回通知发起的时间;
getTag():返回通知的Tag,如果没有设置返回null;
getUserId():返回UserId,用于多用户场景;
isClearable():返回该通知是否可被清楚,FLAG_ONGOING_EVENT、FLAG_NO_CLEAR;
isOngoing():检查该通知的flag是否为FLAG_ONGOING_EVENT;
读取消息数步骤
(1)新建一个通知消息监听类
新建一个类并继承自NotificationListenerService,override其中重要的两个方法:
public class MyNotificationListenerService extends NotificationListenerService
@Override
public void onNotificationPosted(StatusBarNotification sbn)
Log.i("NotificationListener","Notification posted");
@Override
public void onNotificationRemoved(StatusBarNotification sbn)
Log.i("NotificationListener","Notification removed");
(2)在AndroidManifest.xml中注册Service并声明相关权限
<service android:name=".NotificationListenerService"
android:label="@string/service_name"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
<intent-filter>
<action android:name="android.service.notification.NotificationListenerService" />
</intent-filter>
</service>
(3)开启权限
A.判断权限是否已开启
使用NotificationListenerService的应用如果开启了Notification access,系统会将包名等相关信息写入SettingsProver数据库中,因此可以从数据库中获取相关信息并过滤,从而判断应用是否开启了Notification access,代码如下:
private static final String ENABLED_NOTIFICATION_LISTENERS = "enabled_notification_listeners";
private boolean isNotificationListenersEnabled ()
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;
B.跳转通知访问权限开启界面
在程序中检查用户有无访问Notification的权限,若没有可以弹窗提示用户去开启,跳转通知访问权限开启界面的代码如下,做了一定的适配:
public static boolean gotoNotificationAccessSetting(Context context)
try
Intent intent = new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
return true;
catch (ActivityNotFoundException e) //普通情况下找不到的时候需要再特殊处理找一次
try
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
ComponentName cn = new ComponentName("com.android.settings", "com.android.settings.Settings$NotificationAccessSettingsActivity");
intent.setComponent(cn);
intent.putExtra(":settings:show_fragment", "NotificationAccessSettings");
context.startActivity(intent);
return true;
catch (Exception e1)
e1.printStackTrace();
Toast.makeText(context, "对不起,您的手机暂不支持", Toast.LENGTH_SHORT).show();
e.printStackTrace();
return false;
C.针对apk被清理重启后NotificaitonListenerService失效
apk被杀死,重启apk后,需要让系统重新执行授权(也就是改变数据库的状态),可以在apk启动的时候使用该方法:
public static void toggleNotificationListenerService(Context context)
Log.e(tag, "toggleNotificationListenerService");
PackageManager pm = context.getPackageManager();
pm.setComponentEnabledSetting(new ComponentName(context, MyNotificationListenerService .class),
PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
pm.setComponentEnabledSetting(new ComponentName(context, MyNotificationListenerService .class),
PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
让系统重新绑定服务
(4)统计通知栏消息数
在MyNotificationListenerService服务中的onCreate方法中调用getActiveNotifications获取StatusBarNotification消息数组时,需要延时获取,因为这个service还没有创建成功,StatusBarNotification数组的lenth即当前通知栏的消息数
@Override
public void onCreate()
super.onCreate();
new Handler().postDelayed(new Runnable()
@Override
public void run()
Log.e(TAG, " NotificationListenerService onCreate, notification count :" + getActiveNotifications().length);
,1000);
在接收到新消息或者移除消息时,即在MyNotificationListenerService服务中的onNotificationPosted,onNotificationRemoved方法中统计消息数,或者处理StatusBarNotification消息
public class MyNotificationListenerService extends NotificationListenerService
@Override
public void onNotificationPosted(StatusBarNotification sbn)
Log.e(TAG,,"Notification posted");
Log.e(TAG, " NotificationListenerService onCreate, notification count :" + getActiveNotifications().length);
//处理sbn通知消息
@Override
public void onNotificationRemoved(StatusBarNotification sbn)
Log.e(TAG,,"Notification removed");
Log.e(TAG, " NotificationListenerService onCreate, notification count :" + getActiveNotifications().length);
//处理sbn通知消息
PS:这里也可以对收到的消息进行处理加工,比如消息管理(消息盒子)、消息加工后跳转(微信、QQ消息提醒)、短信拦截、消息监控等
以上是关于Android读取通知栏消息数处理消息的主要内容,如果未能解决你的问题,请参考以下文章
OpenFire 或 XMPP 协议是不是支持消息通知(待处理、已交付、已读取),如 BBM(Blackberry Messenger)
适用于 Android 的 Azure 通知中心:如何使用后台服务处理数据消息?