------------------
因为近期商显项目需求,须要在侧边栏菜单中增长通知列表,就相似systemui中的通知同样。先上效果图
因而就去百度上查找如何监听通知消息的方法,大概是须要这么几个步骤
1 写一个服务MyNotificationListenService 继承 NotificationListenerService 而且重写三个方法 代码以下android
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 注册服务
安全
<service android:name=".service.MyNotificationListenerService" android:label="notification listener" android:persistent="true" android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"> <intent-filter> <action android:name="android.service.notification.NotificationListenerService" /> </intent-filter> </service>
启动服务 app
Intent intent =new Intent(this, MyNotificationListenerService.class); startService(intent);
到这里其实尚未结束,由于应用须要监听通知消息,须要去设置,安全,通知里面设置容许通知消息,可是因为我是商显项目,并无这一项设置,因此须要手动设置去设置打开监听通知消息的权限
ide
private final HashSet<ComponentName> mEnabledServices = new HashSet<ComponentName>(); 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上挪过来的代码,怎么判断是否设置成功呢?
post
private static boolean isNotificationListenerServiceEnabled(Context context) { Set<String> packageNames = NotificationManagerCompat.getEnabledListenerPackages(context); if (packageNames.contains(context.getPackageName())) { return true; } return false; }
经过这个方法能够判断是否开启通知权限,以上步骤都作完了以后经过命令串口命令 dumpsys notification查看结果
很明显已经设置成功,可是很奇怪的是接收通知的回调方法并无触发,前先后后花了大概一天的时间也没有找到缘由,无奈之下只好去SystemUI查看它是怎么作的。ui
首先建立一个NotificationListenerService 对象,重写NotificationListenerService 几个方法this
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 注册成系统服务
code
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 方法,而且注册成系统服务,
xml
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"); } };
代码很简单,看一下打印
对象
注册成功
以上就是监听系统通知的方法,目前仍是不清楚第一个方法为何没有做用,有兴趣的小伙伴能够研究一下,评论回复。感谢你们的支持。看完别忘了点赞哟。