Android监听设备的通知栏消息 - xiaoniudonghe2015/Android-Java-Code-Style GitHub Wiki
我们可能需要监听通知栏,来获取系统通知,然后去得到通知的相关信息.
NotificationListenerService 是在 Android 4.3 (API 18)时被加入的,作用就是用来监听通知栏消息。并且官方建议在 Android 4.3 及以上使用 NotificationListenerService 来监听通知栏消息,以此取代 AccessibilityService。
方案是:在 Android 4.3 以下(API < 18)使用 AccessibilityService 来读取新通知,在 Android 4.3 及以上(API >= 18)使用 NotificationListenerService 来满足需求。
首先创建一个 MyNotificationListenerService 继承 NotificationListenerService 。然后在 AndroidManifest.xml 中进行声明相关权限和 :
<service android:name=".MyNotificationListenerService"
android:label="@string/app_name"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
<intent-filter>
<action android:name="android.service.notification.NotificationListenerService" />
</intent-filter>
</service>然后一般会重写下面这三个方法:
onNotificationPosted(StatusBarNotification sbn) :当有新通知到来时会回调;
onNotificationRemoved(StatusBarNotification sbn) :当有通知移除时会回调;
onListenerConnected:当 NotificationListenerService 是可用的并且和通知管理器连接成功时回调。
public class MyNotificationListenerService extends NotificationListenerService {
@Override
public void onNotificationPosted(StatusBarNotification sbn) {
super.onNotificationPosted(sbn);
//当有新通知到来时会回调;
if (!BuildConfig.APPLICATION_ID.equals(sbn.getPackageName())) {
return;
}
Notification notification = sbn.getNotification();
if (notification == null) {
return;
}
}
@Override
public void onNotificationRemoved(StatusBarNotification sbn) {
super.onNotificationRemoved(sbn);
//当有通知移除时会回调;
}
@Override
public void onListenerConnected() {
super.onListenerConnected();
//是可用的并且和通知管理器连接成功时回调。
}
}public boolean isNotificationListenerEnabled(Context context) {
Set<String> packageNames = NotificationManagerCompat.getEnabledListenerPackages(this);
if (packageNames.contains(context.getPackageName())) {
return true;
}
return false;
}public void openNotificationListenSettings() {
try {
Intent intent;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP_MR1) {
intent = new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS);
} else {
intent = new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");
}
startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
}
}AccessibilityService 支持的事件监听类型中有 TYPE_NOTIFICATION_STATE_CHANGED ,该事件类型就是用来监听通知栏消息状态改变的. 讲完了 NotificationListenerService 之后,按照前面说的那样,在 API < 18 的时候使用 AccessibilityService 。 同样,创建一个 MyAccessibilityService ,并且在 AndroidManifest.xml 中进行声明:
<service
android:name=".MyAccessibilityService"
android:label="@string/app_name"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="@xml/accessible_service_config" />
</service>声明之后,还要对 WeChatAccessibilityService 进行配置。需要在 res 目录下新建一个 xml 文件夹,在里面新建一个 accessible_service_config.xml 文件:
<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityEventTypes="typeNotificationStateChanged"
android:accessibilityFeedbackType="feedbackAllMask"
android:accessibilityFlags="flagIncludeNotImportantViews"
android:canRetrieveWindowContent="true"
android:description="@string/app_name"
android:notificationTimeout="100"
android:packageNames="com.mavericks.mynotificationlistenerservice"/>public class MyAccessibilityService extends AccessibilityService {
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
if (Build.VERSION.SDK_INT < 18) {
if (event != null) {
Notification notification = (Notification) event.getParcelableData();
}
}
}
@Override
public void onInterrupt() {
}
}
}accessibilityEventTypes:表示该服务对界面中的哪些变化感兴趣,即哪些事件通知,比如窗口打开,滑动,焦点变化,长按等.具体的值可以在AccessibilityEvent类中查到,如typeAllMask表示接受所有的事件通知.
accessibilityFeedbackType:表示反馈方式,比如是语音播放,还是震动
canRetrieveWindowContent:表示该服务能否访问活动窗口中的内容.也就是如果你希望在服务中获取窗体内容的化,则需要设置其值为true.
notificationTimeout:接受事件的时间间隔,通常将其设置为100即可.
packageNames:表示对该服务是用来监听哪个包的产生的事件
另外,在Android 6.0之后,也就是api23之后,官方在NotificationManager中添加了这一方法getActiveNotifications(),我们可以使用NotificationManager直接调用该方法来获取通知状态
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
StatusBarNotification[] nm = mgr.getActiveNotifications();
}