You need to enable JavaScript to run this app. Kivy/Pyjnius实现通知监听服务的AndroidManifest配置方法
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.30 01:45:04