我有一个系统应用程序。在这个应用程序中我想捕获通知,所以我使用NotificationListenerService。但是要启动此服务,我们需要执行startActivity(新的Intent(“android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS”)),这将使我们获得通知访问权限,用户必须检查应用程序并授予权限。由于我的应用程序是系统应用程序,因此可以默认授予权限,而无需用户选中该框。我已经尝试过use-permission但是没有用。这里的任何帮助将不胜感激。
答案 0 :(得分:4)
很长一段时间你一直在寻求帮助,但无论如何我早些时候在你的情况下找到答案,我会在这里分享。
如果要绕过应用程序的通知访问设置,则需要使用类的隐藏方法 registerAsSystemService 注册NotificationListenerService。由于它是隐藏的,您必须通过NotificationListenerService类上的反射来调用它(有关反射的更多基本信息,请参阅here)
所以,你应该做的是:
我们称之为NotificationService。覆盖所需的方法(OnNotificationPosted / Removed)并提供一个空构造函数 - 随时随地进行实施(在后台服务或开始活动中)
NotificationService ns = new NotificationService();
我们称之为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:当然,这只适用于系统应用:)