很久以来你一直在寻求帮助,但无论如何,因为我之前遇到过你的情况并找到了答案,所以我会在这里分享。
如果你想为你的应用绕过通知访问设置,你需要使用类的隐藏方法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:当然,这只适用于系统应用:)