Kivy/Pyjnius实现通知监听服务的AndroidManifest配置方法
Kivy+Python 通知监听服务的AndroidManifest正确配置方案
核心前提说明
安卓系统绑定NotificationListenerService的硬要求是必须识别到可被系统实例化的Java类服务——你通过Pyjnius编写的Python版监听逻辑属于Python层运行时代码,无法直接被安卓系统加载、绑定,不能直接把Python类路径写进Manifest,必须加一层极简的Java桥接中转,才能完成系统识别。
分步实现流程
1. 编写适配打包的Java桥接服务类
这个类是系统能直接识别的原生Java服务,唯一作用是把系统的回调事件转发到你已经写好的notification_listener.py逻辑里,不需要额外复杂实现:
// 文件路径要匹配打包规则:src/org/kivy/android/NotificationListenerBridge.java package org.kivy.android; import android.service.notification.NotificationListenerService; import android.service.notification.StatusBarNotification; import android.util.Log; import org.kivy.android.PythonActivity; public class NotificationListenerBridge extends NotificationListenerService { private Object pythonListenerInstance; @Override public void onCreate() { super.onCreate(); try { // 类加载器拿到你Python层写好的NotificationListener类 Class<?> listenerCls = PythonActivity.mPythonThread.getClass().getClassLoader() .loadClass("你的项目包名.notification_listener.NotificationListener"); pythonListenerInstance = listenerCls.getDeclaredConstructor().newInstance(); // 触发Python层的onCreate初始化逻辑 listenerCls.getMethod("onCreate", android.content.Context.class) .invoke(pythonListenerInstance, this); } catch (Exception e) { Log.e("NotificationBridge", "Python监听类初始化失败", e); } } @Override public void onNotificationPosted(StatusBarNotification sbn) { // 把系统收到的新通知事件转发给Python层的回调 try { pythonListenerInstance.getClass() .getMethod("onNotificationPosted", StatusBarNotification.class) .invoke(pythonListenerInstance, sbn); } catch (Exception e) { Log.e("NotificationBridge", "通知事件转发失败", e); } } @Override public void onDestroy() { super.onDestroy(); // 转发服务销毁逻辑 try { pythonListenerInstance.getClass().getMethod("onDestroy").invoke(pythonListenerInstance); } catch (Exception e) { Log.e("NotificationBridge", "Python监听资源释放失败", e); } } }
2. AndroidManifest.xml 配置片段
把下面的配置完整放到Manifest的<application>节点内部,android:name的值必须和上面桥接Java类的全路径完全一致:
<service android:name="org.kivy.android.NotificationListenerBridge" android:label="应用通知监听权限" android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE" android:exported="true"> <intent-filter> <action android:name="android.service.notification.NotificationListenerService" /> </intent-filter> </service>
关键校验点:
android:permission字段必须填写android.permission.BIND_NOTIFICATION_LISTENER_SERVICE,这是安卓系统对通知监听服务的强制安全校验,缺失这个配置的服务会被系统直接拦截,不会出现在通知权限的可选列表里。
3. 打包适配要求
- 用python-for-android打包时,需要把上述桥接Java类的路径加入
add_java_files配置项,确保编译时把这个Java类打包进最终APK - 严禁直接把Python类的路径填到Manifest的
android:name字段,安卓系统没有直接实例化Python类的能力,这么写会直接报服务找不到的错误 - 首次启动应用时,需要主动引导用户跳转到系统通知权限设置页开启对应权限,这个跳转逻辑可以直接用Pyjnius调用原生API实现,不需要额外写Java代码
高频踩坑提醒
- 不要遗漏
android:exported="true"配置:因为通知监听服务是由系统的通知管理进程跨进程绑定启动的,必须允许外部进程调用才能正常建立连接 - 桥接类初始化时机要和Python线程启动节奏匹配:不要在应用启动最开始就尝试加载Python层的监听类,必须等服务的
onCreate回调触发后再做初始化,避免出现Python解释器未就绪的空指针错误 - 不要尝试绕过桥接层直接用Pyjnius动态注册服务:系统绑定服务的流程是在APK安装时就读取Manifest里的静态配置,动态注册的服务无法被通知权限管理模块识别
内容的提问来源于stack exchange,提问作者Adrian Seidel
相关产品推荐
相关产品推荐

