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读取通知栏消息数处理消息的主要内容,如果未能解决你的问题,请参考以下文章

Android系统实现应用角标未读消息数原理

OpenFire 或 XMPP 协议是不是支持消息通知(待处理、已交付、已读取),如 BBM(Blackberry Messenger)

Android学习笔记——Handler消息分发

适用于 Android 的 Azure 通知中心:如何使用后台服务处理数据消息?

在 Android Phonegap 应用程序中处理推送通知消息

读取超时的 Firebase 消息注销通知失败