为什么这个NotificationListenerService没有工作?

17

我希望你能帮助翻译关于IT技术的内容。以下是需要翻译的内容,其中涉及到NotificationListenerService。

我一直在尝试使用NotificationListenerService,但是进展不顺利。我已经尝试了很多方法,特别是在so网站上找到的方法。但是它的工作效果并不稳定。

首先看一下代码:

清单文件:

<service
    android:name=".services.NLService"
    android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE" >
    <intent-filter>
        <action android:name="android.service.notification.NotificationListenerService" />
    </intent-filter>
</service>

然后是服务本身:
public class NLService extends NotificationListenerService {

    private String TAG = "NLService";

    // bind and unbind seems to make it work with Android 6...
    // but is never called with Android 4.4... 
    @Override
    public IBinder onBind(Intent mIntent) {
        IBinder mIBinder = super.onBind(mIntent);
        Log.i(TAG, "onBind");
        return mIBinder;
    }

    @Override
    public boolean onUnbind(Intent mIntent) {
        boolean mOnUnbind = super.onUnbind(mIntent);
        Log.i(TAG, "onUnbind");
        isNotificationAccessEnabled = false;
        try {
        } catch (Exception e) {
            Log.e(TAG, "Error during unbind", e);
        }
        return mOnUnbind;
    }

    // onCreate is called with Android 4.4 
    // because the service is explicitly started from the MainActivity.
    // Not on Android 6 where the system binds this service itself...

    @Override
    public void onCreate() {
        super.onCreate();
        Log.i(TAG, "**********  onCreate");

    @Override
    public void onNotificationPosted(StatusBarNotification sbn) {

        Log.i(TAG, "**********  onNotificationPosted");
        Log.i(TAG, "ID :" + sbn.getId() + "\t" + sbn.getNotification().tickerText + "\t" + sbn.getPackageName());
    }

    @Override
    public void onNotificationRemoved(StatusBarNotification sbn) {
        Log.i(TAG, "********** onNOtificationRemoved");
        Log.i(TAG, "ID :" + sbn.getId() + "\t" + sbn.getNotification().tickerText + "\t" + sbn.getPackageName());
    }
}

在主 Activity 中启动服务,或者如果需要,请求用户启用设置:

if (!Utilities.hasNotificationAccess(this)) 
{
     Intent intent = new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");
     startActivity(intent);
     Log.i(TAG,"hasNotificationAccess NO");
}
else
{
    Log.i(TAG,"hasNotificationAccess YES");

    // without this startService, it never works with Android 4.4...
    // but this is not needed in Android 6... 
    Intent mServiceIntent = new Intent(this, NLService.class);
    startService(mServiceIntent);
}

显然,通知的安全设置访问已启用...
在Android 6上:
在NLService本身上,添加onBind和onUnbind方法使其正常工作,我可以看到onBind日志,并且onNotificationPosted被成功触发。但是这只持续到下次启动应用程序,之后没有绑定,没有onNotificationPosted,什么都不会发生,除非我返回安全设置来取消选中-重新检查通知访问:在生产环境中每次启动应用程序都重复这样做是不可行的。
在Android 4.4上:
与Android 6相比,在MainActivity中,我需要明确启动NLService,否则它永远不会自己启动。但是同样地,它仅适用于第一次启动,永远不再起作用,直到取消选中-重新检查安全设置...
我错过了一些明显的东西吗?

你好,你找到根本原因了吗?我遇到了同样的问题,不知道该怎么解决。 - Caxton
2
我发现问题是在设备上重新编译应用程序导致的:第一次编译可以设置并且可以正常工作。第二次编译:除非您重新检查或重新启动手机,否则无法正常工作。但是,这是一个测试环境问题,当您不重新编译而只是重新启动应用程序时,似乎没有这样的问题,设置仍然存在……我不知道为什么重新编译会导致设置丢失……希望这可以帮到您! - JBA
@JBA 我在Oreo设备上遇到了同样的问题,你能帮我解决这个问题吗? - Raj Gohel
1个回答

32

Android缓存存在问题。当您在设备上上传应用程序时,操作系统会将您的服务连接到通知管理器。如果您之前运行过该应用程序,则Android会在缓存中找到此服务,因此不会重新连接。

解决方法:在将应用程序推送到设备之前,重命名您的服务(在Android Studio中的重构选项很有效)- Android将识别此服务为新服务并连接到通知管理器。

https://developer.android.com/reference/android/service/notification/NotificationListenerService.html#onListenerConnected() - 连接到通知管理器后,将调用此方法,因此您可以检查您的服务是否已连接。


1
这是一个不错的解决方法和问题的解释!你是否成功地创建了某种“自动”的服务来生成动态随机名称,还是每次迭代都手动完成? - JBA
1
不,我每次都是手动操作。我还找到了一段代码,应该可以重新加载这个服务,但对我来说没有用 -> https://gist.github.com/xinghui/b2ddd8cffe55c4b62f5d8846d5545bf9 - Konrad Sikorski
1
当我上传到Playstore时,这个解决方法有效吗? - EngineSense
2
我还没有尝试过。当我在寻找这个解决方案时,有些人说通过Play商店更新不会导致这个问题。根据这些信息,应用这个解决方法可能是不必要的(但我找不到链接来证明它)。 - Konrad Sikorski
我最终放弃了,将我的minimumSDK设置为27,并直接使用以下代码检查通知权限:aNotificationManager.isNotificationListenerAccessGranted。 - John Moore
显示剩余8条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接