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消息提醒)、短信拦截、消息监控等

  • 6
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android提供了NotificationListenerService类,可以用于读取通知中的通知。 首先,在AndroidManifest.xml文件中注册NotificationListenerService: ``` <service android:name=".MyNotificationListenerService" android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"> <intent-filter> <action android:name="android.service.notification.NotificationListenerService" /> </intent-filter> </service> ``` 然后创建一个继承自NotificationListenerService的类MyNotificationListenerService: ``` public class MyNotificationListenerService extends NotificationListenerService { @Override public void onNotificationPosted(StatusBarNotification sbn) { super.onNotificationPosted(sbn); // 获取通知所属应用的包名 String packageName = sbn.getPackageName(); // 获取通知的内容 Notification notification = sbn.getNotification(); if (notification != null && notification.extras != null) { String title = notification.extras.getString(Notification.EXTRA_TITLE); String text = notification.extras.getString(Notification.EXTRA_TEXT); // 对通知内容进行处理 // ... } } @Override public void onNotificationRemoved(StatusBarNotification sbn) { super.onNotificationRemoved(sbn); // 通知被移除时的处理逻辑 } } ``` 在MyNotificationListenerService类中的onNotificationPosted()方法可以获取到每个收到的通知,其中StatusBarNotification对象中包含了通知的相关信息,例如通知所属应用的包名、通知的标题和内容等。你可以根据自己的需求对通知进行处理。 请注意,使用NotificationListenerService需要添加BIND_NOTIFICATION_LISTENER_SERVICE权限,因此在注册服务时需要在AndroidManifest.xml中添加权限声明。另外,用户需要在系统设置中手动授权才能让应用读取通知,可以通过以下代码跳转到设置页面: ``` Intent intent = new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS); startActivity(intent); ``` 以上是使用NotificationListenerService读取通知通知的基本步骤,你可以根据自己的需求进一步处理通知内容或者监控通知的移除等操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值