我有一个Android应用程序正在尝试使用api 18中的新NotificationListenerService类。我创建了自己的服务类,它继承自这个类并覆盖了onNotificationPosted和onNotificationRemoved事件,尽管我的服务似乎开始很好这些当我收到或删除通知时,似乎永远不会调用2个事件。
有没有人在这个课程上取得任何成功,或者他们可能分享的任何源代码是否会成功展示如何使用这个课程?
答案 0 :(得分:27)
根据我的经验,几乎所有这些答案都非常接近正确的解决方案!
CORE 问题似乎在开发期间发生;当您正在开发代码时,"通知访问"当您在调试会话之间更新您的应用时,设置将不再受到尊重。
如果您的APK /二进制文件发生更改且NotificationListenerService停止:
希望通过Google Play更新您的应用时不会出现问题。
作为最佳做法,对于我的应用程序,我添加了一个溢出菜单选项,该选项仅显示在非发布版本中,以便我轻松访问设置:
NotificationListener.java:
public class NotificationListener
extends NotificationListenerService
implements RemoteController.OnClientUpdateListener
{
private static final int VERSION_SDK_INT = VERSION.SDK_INT;
public static boolean supportsNotificationListenerSettings()
{
return VERSION_SDK_INT >= 19;
}
@SuppressLint("InlinedApi")
@TargetApi(19)
public static Intent getIntentNotificationListenerSettings()
{
final String ACTION_NOTIFICATION_LISTENER_SETTINGS;
if (VERSION_SDK_INT >= 22)
{
ACTION_NOTIFICATION_LISTENER_SETTINGS = Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS;
}
else
{
ACTION_NOTIFICATION_LISTENER_SETTINGS = "android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS";
}
return new Intent(ACTION_NOTIFICATION_LISTENER_SETTINGS);
}
...
}
menu_my_activity.xml:
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MyActivity"
>
<item
android:id="@+id/action_application_info"
android:title="@string/action_application_info"
app:showAsAction="never"
/>
<item
android:id="@+id/action_notification_settings"
android:title="Notification Settings"
app:showAsAction="never"
/>
</menu>
MyActivity.java:
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.menu_my_activity, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onPrepareOptionsMenu(Menu menu)
{
MenuItem menuItem;
menuItem = menu.findItem(R.id.action_application_info);
if (menuItem != null)
{
menuItem.setVisible(BuildConfig.DEBUG);
}
menuItem = menu.findItem(R.id.action_notification_settings);
if (menuItem != null)
{
menuItem.setVisible(BuildConfig.DEBUG && NotificationListener.supportsNotificationListenerSettings());
}
return super.onPrepareOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case R.id.action_application_info:
startActivity(new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:" + getPackageName())));
return true;
case R.id.action_notification_settings:
startActivity(NotificationListener.getIntentNotificationListenerSettings());
return true;
default:
return super.onOptionsItemSelected(item);
}
}
答案 1 :(得分:14)
安装正确配置的应用后,您应该授予它。
您可以在“设置&gt;安全性&gt;通知访问权限”中找到该应用的名称,然后确保该复选框已填写。 :)
答案 2 :(得分:8)
private void toggleNotificationListenerService() {
PackageManager pm = getPackageManager();
pm.setComponentEnabledSetting(new ComponentName(this, com.xinghui.notificationlistenerservicedemo.NotificationListenerServiceImpl.class),
PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
pm.setComponentEnabledSetting(new ComponentName(this, com.xinghui.notificationlistenerservicedemo.NotificationListenerServiceImpl.class),
PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
}
adb shell dumpsys通知
检查哪个服务正在生活。
com.android.server.notification.ManagedServices#rebindServices
toggleNotificationListenerService()触发系统调用此方法。
答案 3 :(得分:4)
答案 4 :(得分:2)
经过几个小时的研究,我终于找到了实际可行的示例代码:
https://github.com/yihongyuelan/NotificationListenerServiceDemo
答案 5 :(得分:1)
多次调试到设备后,重命名NotificationListener类有助于解决问题。重命名它并不重要,只需将其更改为与以前名称不同的内容即可。我一直都要一遍又一遍地做这件事。
答案 6 :(得分:0)
有时删除构建和重建源可能是个问题。
我挣扎了3天,这就是我所做的:
<强>的AndroidManifest.xml 强>
仅从类示例更改服务名称:
4
Sheet 1
到
<service
android:name=".NotificationListener"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
<intent-filter>
<action android:name="android.service.notification.NotificationListenerService" />
</intent-filter>
</service>
导航到您的根目录&gt; android,然后删除build文件夹,允许你的项目重建。
答案 7 :(得分:0)
NLService会一直按照android docs运作,但在某些情况下,它将与您的特定应用解除绑定,并且可能会重新启动您的手机,并再次绑定。但是从更安全的角度来看,您可以在每次启动时进行检查,
// check NLsettings
private void checkNLSettings() {
//check notification access
if (!NotificationUtils.isNotificationServiceEnabled(this)) {
//start NLsetting activity
Intent intent = new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");
startActivityForResult(intent, REQUEST_ACCESSIBLITYCODE);
finish();
}
//check isNLservice running
if (!isNLServiceRunning()) {
enableNotificationListenerService(this);
}
Toast.makeText(this, "NLS == " + isNLServiceRunning(), Toast.LENGTH_SHORT).show();
}
private boolean isNLServiceRunning() {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service :
manager.getRunningServices(Integer.MAX_VALUE)) {
if (NLService.class.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
/**
* enable notification service.
*
* @param context context
*/
public static void enableNotificationListenerService(Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
NotificationListenerService.requestRebind(new ComponentName(context.getPackageName(),
COMPONENT_NLSERVICE));
} else {
PackageManager pm = context.getPackageManager();
pm.setComponentEnabledSetting(new ComponentName(context.getPackageName(),
COMPONENT_NLSERVICE),
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
}
}
答案 8 :(得分:-1)
我刚刚参加了这个班级的一个很好的例子:
http://www.kpbird.com/2013/07/android-notificationlistenerservice.html
我从以下示例中学到的一件事是,我创建的通知服务在通过新的通知访问屏幕授予权限时自动启动,这意味着我的应用程序不必手动启动服务。