【问题标题】:Notification Listener Service for System app without user intervention无需用户干预的系统应用通知侦听器服务
【发布时间】:2015-06-30 18:41:50
【问题描述】:

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

【问题讨论】:

    标签: android notifications


    【解决方案1】:

    很久以来你一直在寻求帮助,但无论如何,因为我之前遇到过你的情况并找到了答案,所以我会在这里分享。

    如果你想为你的应用绕过通知访问设置,你需要使用类的隐藏方法registerAsSystemService注册NotificationListenerService。由于它是隐藏的,您必须通过 NotificationListenerService 类上的 reflection 调用它(有关反射的更多基本信息,请参阅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:当然,这只适用于系统应用:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-11-02
      • 2017-04-27
      • 2015-07-26
      • 1970-01-01
      • 1970-01-01
      • 2018-05-09
      • 1970-01-01
      相关资源
      最近更新 更多