------------------
    由于近期商显项目需求,需要在侧边栏菜单中增加通知列表,就类似systemui中的通知一样。先上效果图

于是就去百度上查找如何监听通知消息的方法,大概是需要这么几个步骤
    1 写一个服务MyNotificationListenService 继承 NotificationListenerService 并且重写三个方法 代码如下

package com.protruly.floatwindowlib.service;import android.service.notification.NotificationListenerService;import android.service.notification.StatusBarNotification;import android.util.Log;public class MyNotificationListenerService extends NotificationListenerService {    @Override    public void onNotificationPosted(StatusBarNotification sbn) {        super.onNotificationPosted(sbn);        Log.i("gyx","onNotificationPosted");    }    @Override    public void onListenerConnected() {        Log.i("gyx","onListenerConnected");        super.onListenerConnected();    }        @Override    public void onNotificationRemoved(StatusBarNotification sbn) {        super.onNotificationRemoved(sbn);        Log.i("gyx","onNotificationRemoved");    }            }

Mainfest.xml 注册服务
 

                                                        

启动服务 

Intent intent =new Intent(this, MyNotificationListenerService.class);startService(intent);

到这里其实还没有结束,因为应用需要监听通知消息,需要去设置,安全,通知里面设置允许通知消息,但是由于我是商显项目,并没有这一项设置,所以需要手动设置去设置打开监听通知消息的权限
 

private final HashSet mEnabledServices = new HashSet();mConfig = getNotificationListenerConfig();mEnabledServices.add(new ComponentName(this,  MyNotificationListenerService.class));saveEnabledServices();    private void saveEnabledServices() {        StringBuilder sb = null;        for (ComponentName cn : mEnabledServices) {            if (sb == null) {                sb = new StringBuilder();            } else {                sb.append(':');            }            sb.append(cn.flattenToString());        }        Settings.Secure.putString(getContentResolver(), mConfig.setting,                sb != null ? sb.toString() : "");    }    private static Config getNotificationListenerConfig() {        final Config c = new Config();        c.tag = "gyx";        c.setting = "enabled_notification_listeners";        c.intentAction = NotificationListenerService.SERVICE_INTERFACE;        c.permission = android.Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE;        c.noun = "notification listener";        return c;    }    protected static class Config {        String tag;        String setting;        String intentAction;        String permission;        String noun;    }        

这部分代码是去原生的setting上挪过来的代码,怎么判断是否设置成功呢?
 

 private static boolean isNotificationListenerServiceEnabled(Context context) {        Set packageNames =                 NotificationManagerCompat.getEnabledListenerPackages(context);        if (packageNames.contains(context.getPackageName())) {            return true;        }        return false;    }

通过这个方法可以判断是否开启通知权限,以上步骤都做完了之后通过命令串口命令 dumpsys notification查看结果
 

很明显已经设置成功,但是很奇怪的是接收通知的回调方法并没有触发,前前后后花了大概一天的时间也没有找到原因,无奈之下只好去SystemUI查看它是怎么做的。

首先创建一个NotificationListenerService 对象,重写NotificationListenerService 几个方法

private final NotificationListenerService mNotificationListener =            new NotificationListenerService() {        @Override        public void onListenerConnected() {            if (DEBUG) Log.d(TAG, "onListenerConnected");            final StatusBarNotification[] notifications = getActiveNotifications();            final RankingMap currentRanking = getCurrentRanking();            mHandler.post(new Runnable() {                @Override                public void run() {                    for (StatusBarNotification sbn : notifications) {                        addNotification(sbn, currentRanking, null /* oldEntry */);                    }                }            });        }        @Override        public void onNotificationPosted(final StatusBarNotification sbn,                final RankingMap rankingMap) {            if (DEBUG) Log.d(TAG, "onNotificationPosted: " + sbn);            if (sbn != null) {                mHandler.post(new Runnable() {                    @Override                    public void run() {                        String key = sbn.getKey();                        boolean isUpdate = mNotificationData.get(key) != null;                        // In case we don't allow child notifications, we ignore children of                        // notifications that have a summary, since we're not going to show them                        // anyway. This is true also when the summary is canceled,                        // because children are automatically canceled by NoMan in that case.                        if (!ENABLE_CHILD_NOTIFICATIONS                            && mGroupManager.isChildInGroupWithSummary(sbn)) {                            if (DEBUG) {                                Log.d(TAG, "Ignoring group child due to existing summary: " + sbn);                            }                            // Remove existing notification to avoid stale data.                            if (isUpdate) {                                removeNotification(key, rankingMap);                            } else {                                mNotificationData.updateRanking(rankingMap);                            }                            return;                        }                        Bundle extras =sbn.getNotification().extras;                        if(extras==null){                           // Log.i("gyx","extras==null");                        }else{                            //Log.i("gyx","extras!=null");                            String notificationText = extras.getString(Notification.EXTRA_TEXT);                            if(notificationText==null){                                //Log.i("gyx","notificationText==null");                                return;                            }else{                               // Log.i("gyx","notificationText="+notificationText);                            }                        }                        if (isUpdate) {                          //  Log.i("gyx","isUpdate");                            updateNotification(sbn, rankingMap);                        } else {                          //  Log.i("gyx","not Update");                            addNotification(sbn, rankingMap, null /* oldEntry */);                        }                    }                });            }        }        @Override        public void onNotificationRemoved(StatusBarNotification sbn,                final RankingMap rankingMap) {            if (DEBUG) Log.d(TAG, "onNotificationRemoved: " + sbn);            if (sbn != null) {                final String key = sbn.getKey();                mHandler.post(new Runnable() {                    @Override                    public void run() {                        removeNotification(key, rankingMap);                    }                });            }        }        @Override        public void onNotificationRankingUpdate(final RankingMap rankingMap) {            if (DEBUG) Log.d(TAG, "onRankingUpdate");            if (rankingMap != null) {            mHandler.post(new Runnable() {                @Override                public void run() {                    updateNotificationRanking(rankingMap);                }            });        }                            }    };

然后把这个实例通过系统API  registerAsSystemService 注册成系统服务
 

        try {            mNotificationListener.registerAsSystemService(mContext,                    new ComponentName(mContext.getPackageName(),                      getClass().getCanonicalName()),UserHandle.USER_ALL);        } catch (RemoteException e) {            Log.e(TAG, "Unable to register notification listener", e);        }

就这样实现了监听系统通知消息的方法,既然SystemUI可以这样做,那么我也尝试这种办法,创建NotificationListenerService  实例,通过反射拿到registerAsSystemService 方法,并且注册成系统服务,
 

 try {        Class clazz =            Class.forName("android.service.notification.NotificationListenerService");        Method registerAsSystemService = clazz.getDeclaredMethod("registerAsSystemService",            Context.class, ComponentName.class, int.class);        registerAsSystemService.invoke(mNotificationListener,this,new             ComponentName(getPackageName(), getClass().getCanonicalName()),-1); } catch (Exception e) {        e.printStackTrace();        Log.i("gyx","e.printStackTrace()="+e.getMessage()); } NotificationListenerService mNotificationListener =            new NotificationListenerService(){                @Override                public void onNotificationPosted(StatusBarNotification sbn) {                    super.onNotificationPosted(sbn);                    Log.i("gyx","onNotificationPosted");                }                @Override                public void onNotificationRemoved(StatusBarNotification sbn) {                    super.onNotificationRemoved(sbn);                    Log.i("gyx","onNotificationRemoved");                }            };

代码很简单,看一下打印

注册成功

以上就是监听系统通知的方法,目前还是不清楚第一个方法为什么没有作用,有兴趣的小伙伴可以研究一下,评论回复。感谢大家的支持。看完别忘了点赞哟。

更多相关文章

  1. Android反挂钩技术-Java层
  2. android 隔几秒再执行
  3. Handler部分原理
  4. EditText 的setKeyListener()方法的用法是输入某些特殊的字符
  5. [置顶] Canvas开篇之drawBitmap方法讲解
  6. android实战项目五做一个倒计时的button
  7. Android开发本地及网络Mp3音乐播放器(二十)歌曲下载完成后通知主
  8. 据说程序员是最爱学习的群体,IT男都知道,这个行业日新月异,必须不断
  9. android Studio与数据库SQLserver连接实现登录

随机推荐

  1. android 视频通话 项目 源码
  2. android利用websocket协议与服务器通信
  3. Android(安卓)TTS学习(补充)--我能说中文
  4. android测试之monkey
  5. Android平台一日游
  6. 最简单的基于FFmpeg的移动端例子:Android(
  7. android webview的代替品
  8. Android(安卓)CPU架构
  9. 实现Launcher的抽屉效果
  10. Android(安卓)进程回收之LowMemoryKiller