GVKun编程网logo

android使用NotificationListenerService监听通知栏消息(android notification监听)

12

如果您对android使用NotificationListenerService监听通知栏消息感兴趣,那么本文将是一篇不错的选择,我们将为您详在本文中,您将会了解到关于android使用Notific

如果您对android使用NotificationListenerService监听通知栏消息感兴趣,那么本文将是一篇不错的选择,我们将为您详在本文中,您将会了解到关于android使用NotificationListenerService监听通知栏消息的详细内容,我们还将为您解答android notification监听的相关问题,并且为您提供关于Android accessibility service detect notification、Android Notification 消息通知 相关资料.md、Android Notification 通知栏点击不能跳转、Android NotificationListenerService抛出DeadObjectException的有价值信息。

本文目录一览:

android使用NotificationListenerService监听通知栏消息(android notification监听)

android使用NotificationListenerService监听通知栏消息(android notification监听)

NotificationListenerService是通过系统调起的服务,在应用发起通知时,系统会将通知的应用,动作和信息回调给NotificationListenerService。但使用之前需要引导用户进行授权。使用NotificationListenerService一般需要下面三个步骤。

注册服务

首先需要在AndroidManifest.xml对service进行注册。

<service
  android:name=".NotificationCollectorService"
  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>

继承实现NotificationListenerService

自己实现一个继承NotificationListenerService的service,在onNotificationPosted中完成自己需要的操作。

public class NotificationCollectorService extends NotificationListenerService {
  @Override
  public void onNotificationPosted(StatusBarNotification sbn) {
    Log.i("xiaolong","open" + "-----" + sbn.getPackageName());
    Log.i("xiaolong","open" + "------" + sbn.getNotification().tickerText);
    Log.i("xiaolong","open" + "-----" + sbn.getNotification().extras.get("android.title"));
    Log.i("xiaolong","open" + "-----" + sbn.getNotification().extras.get("android.text"));
  }

  @Override
  public void onNotificationRemoved(StatusBarNotification sbn) {
    Log.i("xiaolong","remove" + "-----" + sbn.getPackageName());

  }
}

引导用户进行授权

由于此服务需要用户手动进行授权,所以使用前需要对用户进行引导设置。

public class MainActivity extends AppCompatActivity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    String string = Settings.Secure.getString(getContentResolver(),"enabled_notification_listeners");
    if (!string.contains(NotificationCollectorService.class.getName())) {
      startActivity(new Intent(
          "android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"));
    }
  }
}

用户授权后就可以对通知栏的所有信息进行监听了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。

Android accessibility service detect notification

Android accessibility service detect notification

0 down vote favorite

I''m trying to make my app detect whenever a notification is displayed. I''ve enabled it in the settings app andonServiceConnecteddoes get called, however when I create a notification or receive an e-mail through the gmail app nothing happens,onAccessibilityEventdoes not get called.

Android manifest:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.test.slide" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="15"/> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> <uses-permission android:name="android.permission.GET_TASKS"/> <application android:label="Slide" android:icon="@drawable/ic_launcher" android:theme="@style/AppTheme"> <activity android:name=".Settings" android:label="Slide"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <activity android:name=".Tools" android:label="Slide" android:theme="@android:style/Theme.Translucent.NoTitleBar"> </activity> <service android:name=".LocalService"/> <service android:name=".NotificationService" android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" android:label="Slide" android:enabled="true" android:exported="false"> <intent-filter> <action android:name="android.accessibilityservice.AccessibilityService"/> </intent-filter> </service> </application>

NotificationService.java

package com.test.slide; import android.accessibilityservice.AccessibilityService; import android.accessibilityservice.AccessibilityServiceInfo; import android.view.accessibility.AccessibilityEvent; public class NotificationService extends AccessibilityService { @Override public void onAccessibilityEvent(AccessibilityEvent event) { System.out.println("onAccessibilityEvent"); if (event.getEventType() == AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED) { System.out.println("notification: " + event.getText()); } } @Override protected void onServiceConnected() { System.out.println("onServiceConnected"); AccessibilityServiceInfo info = new AccessibilityServiceInfo(); info.eventTypes = AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED; info.notificationTimeout = 100; info.feedbackType = AccessibilityEvent.TYPES_ALL_MASK; setServiceInfo(info); } @Override public void onInterrupt() { System.out.println("onInterrupt"); } }

Thanks for any help.

android notifications accessibility
share | improve this question
edited Sep 26 ''12 at 12:20

asked Sep 23 ''12 at 17:18
ng93
396 1 4 20


Did you found the solution? i have exactly the same problem. –  Daniel Martinus Sep 25 ''12 at 17:24

alanv''s answer worked for me –  ng93 Sep 26 ''12 at 12:29

For what system version are you programming? ICS? jelly bean? –  Daniel Martinus Sep 27 ''12 at 11:33

Jelly bean 4.1.1 –  ng93 Oct 1 ''12 at 14:56

2 Answers

active oldest votes
up vote 2 down vote accepted

Accessibility services in Android 4.0 and above can behave strangely if there is no accessibility-service meta-data tag defined in the manifest. Try defining the meta-data as in the examples below. You should continue to use setServiceInfo() to maintain backward compatibility with pre-4.0 devices.

Also, I would recommend specifying a feedback type that is specific to your service, rather than using "all".

AndroidManifest.xml

 <service . . . android:name=".NotificationService" 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/accessibilityservice" /> </service>

res/xml/accessibilityservice.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:notificationTimeout="100" />

There was an error in your feedbackType. Corrected below. Still, consider using a more specific feedback type.

NotificationService.java

@Override protected void onServiceConnected() { AccessibilityServiceInfo info = new AccessibilityServiceInfo(); info.eventTypes = AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED; info.feedbackType = AccessibilityServiceInfo.FEEDBACK_ALL_MASK; info.notificationTimeout = 100; setServiceInfo(info); }
share | improve this answer
edited Sep 24 ''12 at 8:37

answered Sep 24 ''12 at 1:33
alanv
442 1 10


Now you are defining theserviceInfoin XML and code. You may leave out the code part of AccessibilityServiceInfo because the xml is defined in the manifest. –  Daniel Martinus Sep 24 ''12 at 5:57
1  
On the contrary, you must define it in both places for compatibility with pre-ICS devices. –  alanv Sep 24 ''12 at 8:01
up vote 1 down vote

The app using AccessibilityService needed to have a permission from settings>Accessibility in order to access the system events. Allow permission from settings . This may work

check this link

accessibility service is not started

Android Notification 消息通知 相关资料.md

Android Notification 消息通知 相关资料.md

@H_301_1@

目录

  • Android Notification 消息通知 相关资料
    • Android 5.0 Lollipop (API 21)无法正常显示通知图标,只能看到一个白色方块或灰色方块的问题
      • 解决方案
      • 参考资料
    • Android 8.0 Oreo(API 26) 及更高版本 如何更新 消息通知渠道 设置的问题
      • 解决方案:无!
      • 问题详情
      • 参考资料
    • Android 7.0 Nougat(API 24) 及更高版本 消息通知 设置的自定义铃声 无法正常播放问题
      • 解决方案
      • 问题详情
      • 参考资料

Android Notification 消息通知 相关资料

Android 5.0 Lollipop (API 21)无法正常显示通知图标,只能看到一个白色方块或灰色方块的问题

解决方案

详情见参考资料2.

  1. 使用在线PS 去掉原来图标的背景色,保留主题图标为白色
    Photopea | Online Photo Editor
  2. 打开 Android Asset Studio Notification icon generator 然后上传新logo
  3. 下载 处理好后的新图标即可.
    android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? R.mipmap.ic_launcher_white : R.mipmap.ic_launcher

参考资料

  1. Android 5.0 行为变更 | Android Developers

    在白色(或非常浅)的背景上使用深色文本绘制通知,以便与新的 Material Design 小部件匹配。请确保您的所有通知都与新的配色方案协调一致。如果您的通知看上去不协调,请进行修正:

    • 使用 setColor() 在您的图标图像后面的圆形中设置重点色彩。
    • 更新或移除使用色彩的资源。系统在操作图标和主要通知图标中忽略所有非阿尔法通道。您应假设这些图标仅支持阿尔法通道。系统用白色绘制通知图标,用深灰色绘制操作图标。
  2. Android Push Notifications: Icon not displaying in notification,white square shown instead - Stack Overflow

    • For 5.0 Lollipop "Notification icons must be entirely white".
    Notification notification = new NotificationCompat.Builder(this);
    if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        notification.setSmallIcon(R.drawable.icon_transperent);
       notification.setColor(getResources().getColor(R.color.notification_color));
    } else {
        notification.setSmallIcon(R.drawable.icon);
    }
    • I found a link where we can generate our own white icon,
      try this link to generate white icon of your launcher icon.
      Open this Link Android Asset Studio and upload your ic_launcher or notification icon
  3. android 5.0以上通知栏、状态栏图标变成白色 - 晕菜一员 - 博客园

    因为google在android5.0上面做了限制,为了统一系统风格。之后的状态栏icon就不能够随便用一张色彩丰富的图片了,只能够有白色和透明两个颜色出现。

    5.0以上(不包含5.0),系统默认通知栏图标为系统启动图标,会自动将通知栏的图标(有色区域)全部填充为白色,

  4. Android 的 notification 图标问题 - V2EX

    因为原先的那种形式的图标不好看,颜色太花,在状态栏上一点也不好看.
    并且这也是 Material Design 的规范了 ( https://www.google.com/design/spec/patterns/notifications.html) 实际上这样的改变在 Android 5.0 里好看了很多,
    如果你看到有些厂商还不知道的,那么就是他们菜或者是上班混日子.

Android 8.0 Oreo(API 26) 及更高版本 如何更新 消息通知渠道 设置的问题

解决方案:无!

谷歌官方文档说明了,一旦渠道创建完毕,那么最终管理权利就移交给用户了. 程序最多可以将其删除,想修改是不可能的了.

ByYe:间接解决方案=根据title或者sound的不同,创建不同的渠道.来间接实现.

问题详情

想重用一个渠道,只是修改不同的部分,比如提示声音铃声不同.

参考资料

  1. https://developer.android.com/guide/topics/ui/notifiers/notifications#limits

    发布限制
    从 Android 8.1(API 级别 27)开始,应用无法每秒发出一次以上的通知提示音。如果应用在一秒内发出了多条通知,这些通知都会按预期显示,但是每秒中只有第一条通知发出提示音。

    不过,Android 还对通知更新频率设定了限制。如果您过于频繁地发布有关某条通知的更新(不到一秒内发布多个),系统可能会放弃部分更新。

  2. How to properly update notification channel android oreo - Stack Overflow

    Once a notification channel is created,the user has ultimate control over it‘s settings.

    As the developer,you can only change the channel‘s title and description.

    If you want to recreate the channel,you have to use a different id.

    See: https://developer.android.com/training/notify-user/channels

  3. Create and Manage Notification Channels | Android Developers

    • Starting in Android 8.0 (API level 26),all notifications must be assigned to a channel
    • After you create a notification channel,you cannot change the notification behaviors—the user has complete control at that point. Though you can still change a channel‘s name and description.
    • But remember that once you create the channel,you cannot change these settings and the user has final control of whether these behaviors are active.
  4. Android Oreo 通知新特性,这坑老夫先踩了 - 简书

    其中“lockscreenVisibility”和“setBypassDnd”是无法生效的,因为从源码中来看,

    只能被系统或排序服务(Android Notification Ranking Service)更改。

Android 7.0 Nougat(API 24) 及更高版本 消息通知 设置的自定义铃声 无法正常播放问题

解决方案

  1. 详情参见 参考资料1
  2. 采用的是使用自定义ContentProvider The Axe: Use a Custom ContentProvider
  3. 实际测试效果: Android 8.1 + Android 4.4.4 版本都正常.

解决步骤:

  1. 下载最新版本的cwac-provider-0.5.3.jar并集成到项目中

    GitHub - commonsguy/cwac-provider: CWAC-Provider: Helping to Make Content Providers Sane

  2. 按文档要求在清单文件里AndroidManifest.xml添加了以下代码:

    <provider
              android:name="com.commonsware.cwac.provider.StreamProvider"
              android:authorities="${applicationId}.DataFilesSoundsstreamProvider"
              android:exported="true">
        <Meta-data
                   android:name="com.commonsware.cwac.provider.STREAM_PROVIDER_PATHS"
                   android:resource="@xml/data_files_sounds_paths" />
    </provider>
  3. 在项目资源目录里添加了res/xml/data_files_sounds_paths.xml文件

    <?xml version="1.0" encoding="utf-8"?>
    <paths>
        <files-path
                name="data_files_sounds"
                path="sounds"
                readOnly="true" />
    </paths>
  4. 将代码中原使用Uri.fromFile(file)的地方替换为com.commonsware.cwac.provider.StreamProvider.getUriForFile(mContext.getPackageName() + ".DataFilesSoundsstreamProvider",file)即可

问题详情

问题还原步骤:

  1. 使用 NotificationCompat.Builder.setSound 设置自定义铃声
  2. 自定义铃声 位于 SDCard外置存储卡Environment.getExternalStorageDirectory() 某个目录里.

结果:

  1. Android 6 之前的版本 正常 播放.

  2. Android 7 以后的版本 无法 播放.

    抛出异常:StrictMode: file:// Uri exposed through Notification.sound

参考资料

  1. java - Android 7.0 Notification Sound from File Provider Uri not playing - Stack Overflow

    If you were using file: Uri values,they no longer work on Android 7.0 if your targetSdkVersionis 24 or higher,as the sound Uri is checked for compliance with the ban on file: Uri values.
    假如你还在使用file:uri形式的路径值,那么Android 7.0以后的版本就不再支持了(只要targetSdkVersion > 24)

    However,if you try a content: Uri from,say,FileProvider,your sound will not be played... because Android does not have read access to that content.

    但是,假如你尝试使用content: 开头的Uri对象,例如通过FileProvider可以拿到这类对象,结果你的自定义通知铃声还是不能正常播放囧。原因是Android系统本身没有你指定的文件的读取权限

    解决方案有:

    1. 使用grantUriPermissions()授权,让其具有读取权限The Scalpel: grantUriPermissions()

      grantUriPermission("com.android.systemUI",soundUri,Intent.FLAG_GRANT_READ_URI_PERMISSION);
      缺点: 在于你不知道给授权,Android默认会是com.android.systemUI,至于其它厂商的系统是不是这个,就很难说了.

      Thanks a lot for the thorough answer. To verify the robustness of the grantUriPermission solution (‘The Scalpel‘),I‘ve tested it in different physical devices (including LG,Motorola,HTC,Samsung and Sony),from API 15 up to API 24. It works correctly on all of them,so the solution seems pretty solid (although certainly hacky). – jmart Sep 7 ‘16 at 18:24

    2. 不提供完全自定义的铃声,仅仅提供部分可选择的铃声 The Guillotine: No More User Files

      原因是:android.resource开头的Uri对象路径Android系统默认是支持直接读取的,所以只要将部分可供选择的铃声放在APP的RAW资源目录里即可.

      缺点:在于让用户无法完全自定义自己的铃声了,可能你的用户不一定会买账.

    3. 使用自定义ContentProvider The Axe: Use a Custom ContentProvider

      FileProvider 不能直接用,因为一旦设置成 exported 那么一启动APP就会崩溃.

      那么可用的方案就是自定义一个支持exported且具有读取权限的 ContentProvider了.

      可以参见: GitHub - commonsguy/cwac-provider: CWAC-Provider: Helping to Make Content Providers Sane

      Using a read-only ContentProvider (see "The Axe") is the better answer. I‘ll probably rig up my StreamProvider such that if you mark it as exported,it treats everything as read-only,which would handle this problem fairly cleanly. – CommonsWare

Android Notification 通知栏点击不能跳转

Android Notification 通知栏点击不能跳转

关于通知栏Notification的使用,不多讲,这里说的很清楚http://www.cnblogs.com/zenfly/archive/2012/02/09/2343923.html

先说下我遇到的问题:

在应用关闭的时候,发送通知到通知栏,点击通知栏能正常跳转到我想要的页面,代码如下

Intent msgIntent = new Intent();

msgIntent.addCategory(Intent.CATEGORY_LAUNCHER);
						msgIntent.setComponent(new ComponentName(context.getPackageName(), "com.test.FragmentActivity"));

msgIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);// 关键的一步,设置启动模式

UITools.showNotification(context, Notify.NORMAL, msgIntent, jsonBean.getMessageTitle());



在应用打开的情况下,发送通知,代码如下:

Intent msgIntent = new Intent();

msgIntent.setClass(context, FragmentActivity.class);

msgIntent.setFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);// 关键的一步,设置启动模式

UITools.showNotification(context, Notify.NORMAL, msgIntent, jsonBean.getMessageTitle());



以上这段代码,出现了不能跳转的情况,于是,做了如下操作解决上述问题

<activity
            android:name=".activity.FragmentActivity"
            android:taskAffinity="" >
        </activity>



设置栈,可以正常响应我的通知栏意图了,但是新的问题出现了,当我按下Home键回到桌面的时候,在回来,就不能打开按下之间的页面了,不同的栈,,,,,

-------问题总是有的,于是换了一种折中的解决方案

Intent msgIntent = new Intent();

msgIntent.setAction(IntentAction.ACTION_TRIP_APPROVE);

UITools.showNotificationBroadcast(context, Notify.NORMAL, msgIntent, jsonBean.getMessageTitle());  //这里是发送广播哦



设置通知栏的意图为发送广播

PendingIntent pendingIntent = PendingIntent.getBroadcast(this, count, intent, PendingIntent.FLAG_UPDATE_CURRENT);



当然,这带来了新的问题,如果我的通知栏需要传递参数怎么办,可以通过如下方式传递

intent.setData(Uri.parse("abc"));



这种可以传递结构化的数据,那我们所谓的bundle就不能使用了么,当然不是,如下

PendingIntent pendingIntent = PendingIntent.getBroadcast(this, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);

标红的地方是重点,为每个意图设置不同的requestCode,Flag设置为更新当前

Android NotificationListenerService抛出DeadObjectException

Android NotificationListenerService抛出DeadObjectException

我有一个简单的NotificationListenerService实现来测试新的4.3 API.服务本身曾经工作过.之后,我添加了在添加特定包的通知时发送广播.现在,只要我启动该服务,它就会抛出一个DeadobjectException.这是堆栈跟踪:
E/NotificationService﹕ unable to notify listener (posted): android.service.notification.INotificationListener$Stub$Proxy@42c047a0
    android.os.DeadobjectException
    at android.os.BinderProxy.transact(Native Method)
    at android.service.notification.INotificationListener$Stub$Proxy.onNotificationPosted(INotificationListener.java:102)
    at com.android.server.notificationmanagerService$NotificationListenerInfo.notifyPostedIfUserMatch(notificationmanagerService.java:241)
    at com.android.server.notificationmanagerService$2.run(notificationmanagerService.java:814)
    at android.os.Handler.handleCallback(Handler.java:730)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at android.os.Looper.loop(Looper.java:137)
    at com.android.server.ServerThread.run(SystemServer.java:1000)

这就是我启动服务的方式

@Override
public boolean onoptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.action_start_service:
            startService(new Intent(this,ConnectService.class));
            return true;
        default:
            return super.onoptionsItemSelected(item);
    }
}

我可以验证服务是否启动,因为我登录了onCreate()和onDestroy().
以下是如何处理通知发布的方式:

@Override
public void onNotificationPosted(StatusBarNotification sbn) {
    Log.i(TAG,sbn.getNotification().toString());
    if (sbn != null && sbn.getPackageName().equalsIgnoreCase(PKG)) {
        Intent intent = new Intent(ConnectService.NOTIFY);
        intent.putExtra("notification",sbn.getNotification().toString());
        bManager.sendbroadcast(intent);
    }
}

糟糕的是堆栈跟踪是没用的.出了什么问题?

解决方法

尽量不要自己启动服务.如果已在安全设置中启用NotificationListenerService,则系统应自动绑定到它.

或者,检查崩溃日志以查看服务是否崩溃或其进程是否已被终止.我相信有一个错误,如果您的NotificaitonListerService死亡,系统将不会重新绑定,直到您重新启动手机或在安全设置中切换通知权限.

我们今天的关于android使用NotificationListenerService监听通知栏消息android notification监听的分享已经告一段落,感谢您的关注,如果您想了解更多关于Android accessibility service detect notification、Android Notification 消息通知 相关资料.md、Android Notification 通知栏点击不能跳转、Android NotificationListenerService抛出DeadObjectException的相关信息,请在本站查询。

本文标签: