无法获取BIND_NOTIFICATION_LISTENER_SERVICE权限以使用NotificationListenerService

6

我创建了一个应用程序并添加了一个扩展了 `NotificationListenerService` 的 Java 类。一切都应该正常工作,但我无法获得 `BIND_NOTIFICATION_LISTENER_SERVICE` 权限。我已在清单中添加了它,但是当我检查权限时:

        if (ContextCompat.checkSelfPermission(this,
            Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE)
            != PackageManager.PERMISSION_GRANTED)
    {
        Log.d(TAG, "permission denied");
    }
    else
        Log.d(TAG, "permission granted");

但我一直收到“权限被拒绝”的消息。我知道这个权限不是一个“危险权限”,所以我不需要向用户请求它。 在清单文件中,我声明了以下内容:

        <service android:name=".PcNotification"
        android:label="PCNotificationService"
        android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
        <intent-filter>
            <action android:name="android.service.notification.NotificationListenerService" />
        </intent-filter>
    </service>

但它仍然无法工作。我还实现了onListenerConnected函数,但从未被调用,这意味着我的服务从未与通知管理器连接,可能是因为我没有权限。

我只想知道如何将此权限授予我的应用程序。

3个回答

5
我只是无法获得BIND_NOTIFICATION_LISTENER_SERVICE权限。
您不需要请求该权限。您需要在元素中通过android:permission属性保护您的服务。
我知道这个权限不是“危险权限”,所以我不需要向用户请求它。
然后删除请求用户权限的代码。这是不必要的,也不会起作用。

@EldarAzulay:请详细解释一下“它仍然不起作用”的含义。你应该在<service>元素上保留android:permission属性。你应该删除checkSelfPermission()相关内容。 - CommonsWare
我从清单文件中删除了 checkSelfPermission()uses-permission。正如您在主要问题中所看到的,我正在使用 android:permission。但是,在我完成您告诉我的一切之后,它仍然无法正常工作。我在 NotificationListenerService 上使用了 onListenerConnected() 函数,但是该函数从未被调用,因为监听器从未连接到通知管理器。 也许问题出在我如何启动服务上?我是这样启动的:Intent intent = new Intent(this, NotificationListener.class); startService(intent); - Eldar Azulay
@EldarAzulay:检查LogCat以获取来自系统的有关连接到您的服务的问题的消息。还请参阅此问题及其答案 - CommonsWare
2
@EldarAzulay:这将取决于您的Android操作系统版本。在Android 7.1上,请尝试设置>应用程序>(齿轮图标)>特殊访问>通知访问。 - CommonsWare
1
它起作用了!但现在我又有另一个问题。用户不应该知道去哪里做那件事。如果我将他引用到设置页面中的该页面,那就更简单了,所以我制作了一个意图来为他打开此页面。 意图如下: Intent intent = new Intent(); intent.setAction(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS); Uri uri = Uri.fromParts("package", getPackageName(), null); intent.setData(uri); startActivity(intent);但是我得到了 android.content.ActivityNotFoundException: No Activity found to handle Intent - Eldar Azulay
显示剩余5条评论

3

这应该是对原问题的直接回答。 然而,如果您需要以下方法,则误解了此类服务的使用(就像我一样)。 您不应该自己启动通知侦听器,而是应该简单地测试您的服务是否正在运行,如果没有,则已经知道未授予权限,并且可以将用户指向首选项面板,网址为android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS

将此方法添加到NotificationListenerClass中,它将返回true(权限已授予)或false(权限未授予):

public Boolean VerifyNotificationPermission() {
    String theList = android.provider.Settings.Secure.getString(getContentResolver(), "enabled_notification_listeners");
    String[] theListList = theList.split(":");
    String me = (new ComponentName(this, YourNotificationListenerClass.class)).flattenToString();
    for ( String next : theListList ) {
        if ( me.equals(next) ) return true;
    }
    return false;
}

“enabled_notification_listeners”这个字符串似乎在Settings.Secure.ENABLED_NOTIFICATION_LISTENERS中定义,但我无法解决它,因此我使用可能不太易维护的字面字符串。如果有人知道如何通过引用获取它,请添加/编辑!


2

在安卓设置中,必须由用户手动授权这个特定的权限,然后你需要在AndroidManifest.xml中将该权限与你的服务绑定,之后你的服务才能被执行。

<service android:name=".PcNotification"
    android:label="PCNotificationService"
    android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
    <intent-filter>
        <action android:name="android.service.notification.NotificationListenerService" />
    </intent-filter>
</service>

问题在于大多数用户不知道如何授予权限(例如在Android设置中),因此您可以使用以下方法为他们打开:

startActivity(new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"));

当用户与您的应用程序交互时 - 例如点击按钮 - 您可以运行此操作,并最好解释为什么需要此权限。

我发现特别好的是有一张卡片,上面有解释和一个按钮,可以打开设置,以便用户启用权限。


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