系统应用程序的通知侦听器服务,无需用户干预

时间:2015-06-30 18:41:51

标签: android notifications

我有一个系统应用程序。在这个应用程序中我想捕获通知,所以我使用NotificationListenerService。但是要启动此服务,我们需要执行startActivity(新的Intent(“android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS”)),这将使我们获得通知访问权限,用户必须检查应用程序并授予权限。由于我的应用程序是系统应用程序,因此可以默认授予权限,而无需用户选中该框。我已经尝试过use-permission但是没有用。这里的任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:4)

很长一段时间你一直在寻求帮助,但无论如何我早些时候在你的情况下找到答案,我会在这里分享。

如果要绕过应用程序的通知访问设置,则需要使用类的隐藏方法 registerAsSystemService 注册NotificationListenerService。由于它是隐藏的,您必须通过NotificationListenerService类上的反射来调用它(有关反射的更多基本信息,请参阅here

所以,你应该做的是:

  • 创建一个扩展NotificationListenerService
  • 的子类

我们称之为NotificationService。覆盖所需的方法(OnNotificationPosted / Removed)并提供一个空构造函数   - 随时随地进行实施(在后台服务或开始活动中)

NotificationService ns = new NotificationService();
  • 创建一个类,该类将对NotificationListenerService执行反射,以达到"到达" registerAsSystemService方法

我们称之为NotificationProxy。在其中创建一个公共静态方法如下:

public static void registerAsSystemService(NotificationService ns, Context ctx) {
    String className = "android.service.notification.NotificationListenerService";
    try {

        @SuppressWarnings("rawtypes")
        Class NotificationListenerService = Class.forName(className);

        //Parameters Types
        //you define the types of params you will pass to the method
        @SuppressWarnings("rawtypes")
        Class[] paramTypes= new Class[3];
        paramTypes[0]= Context.class;
        paramTypes[1]= ComponentName.class;
        paramTypes[2] = int.class;

        Method register = NotificationListenerService.getMethod("registerAsSystemService", paramTypes);

        //Parameters of the registerAsSystemService method (see official doc for more info)
        Object[] params= new Object[3];
        params[0]= ctx;
        params[1]= new ComponentName(ctx.getPackageName(), ctx.getClass().getCanonicalName());
        params[2]= -1; // All user of the device, -2 if only current user
        // finally, invoke the function on our instance
        register.invoke(ns, params);

    } catch (ClassNotFoundException e) {
        Log.e(TAG, "Class not found", e);
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        Log.e(TAG, "No such method", e);
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        Log.e(TAG, "InvocationTarget", e);
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        Log.e(TAG, "Illegal access", e);
        e.printStackTrace();
    }

}
  • 调用方法

从您定义NotificationService实例的地方,请调用:

NotificationProxy.registerAsSystemService(ns, this.getApplicationContext());

希望这会有所帮助!

PS:您不应该像在简单实施通知服务时那样在您的清单中设置服务。

PS2:当然,这只适用于系统应用:)