如何在Python Kivy安卓应用中实现无需在线API的本地通知
如何在Python Kivy安卓应用中实现无需在线API的本地通知
嘿,我完全懂你不想依赖在线API、只想做本地系统通知的需求——之前用pyjnius踩过旧方法的坑也很正常,毕竟Android高版本(API 26+)强制要求用通知渠道(Notification Channels),老代码自然失效了。下面给你一套适配新系统的可行方案,全程离线,不用任何第三方在线服务:
第一步:准备依赖与权限
首先确保你的项目里已经安装了pyjnius,如果是用Buildozer打包,记得在buildozer.spec里添加以下配置:
- 在
requirements里加上pyjnius - 在
android.permissions里添加VIBRATE和POST_NOTIFICATIONS(Android 13+需要后者权限)
第二步:适配高版本Android的通知渠道创建
在Android 8.0及以上,必须先创建通知渠道才能发送通知,否则通知根本不会显示。用pyjnius调用Android原生API的代码如下:
from jnius import autoclass, cast from kivy.utils import platform def create_notification_channel(): if platform != 'android': return Context = autoclass('android.content.Context') NotificationManager = autoclass('android.app.NotificationManager') NotificationChannel = autoclass('android.app.NotificationChannel') # 获取系统的NotificationManager实例 notification_manager = cast('android.app.NotificationManager', Context.getSystemService(Context.NOTIFICATION_SERVICE)) # 定义渠道ID、名称和重要性(这里设为默认级别) channel_id = "kivy_local_notifications" channel_name = "本地通知" importance = NotificationManager.IMPORTANCE_DEFAULT # 创建渠道并注册到系统 channel = NotificationChannel(channel_id, channel_name, importance) notification_manager.createNotificationChannel(channel)
你可以在应用启动时调用这个函数,比如在Kivy的App.on_start()方法里执行。
第三步:构建并发送本地通知
有了通知渠道后,就可以构建并发送通知了。下面是完整的发送通知函数:
def send_local_notification(title, message): if platform != 'android': print("仅安卓支持本地通知") return # 先确保渠道已创建 create_notification_channel() Context = autoclass('android.content.Context') Intent = autoclass('android.content.Intent') PendingIntent = autoclass('android.app.PendingIntent') NotificationCompat = autoclass('androidx.core.app.NotificationCompat') NotificationManagerCompat = autoclass('androidx.core.app.NotificationManagerCompat') # 创建点击通知后打开应用的Intent intent = Intent(Context.getApplicationContext(), autoclass('org.kivy.android.PythonActivity')) intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK) pending_intent = PendingIntent.getActivity(Context.getApplicationContext(), 0, intent, PendingIntent.FLAG_IMMUTABLE) # 构建通知内容 channel_id = "kivy_local_notifications" notification_builder = NotificationCompat.Builder(Context.getApplicationContext(), channel_id) \ .setSmallIcon(autoclass('android.R$drawable').ic_dialog_info) # 用系统默认图标,也可以替换成自定义图标 .setContentTitle(title) \ .setContentText(message) \ .setPriority(NotificationCompat.PRIORITY_DEFAULT) \ .setContentIntent(pending_intent) \ .setAutoCancel(True) # 点击通知后自动消失 # 发送通知,这里用唯一的ID来区分不同通知 notification_manager = NotificationManagerCompat.from(Context.getApplicationContext()) notification_manager.notify(1, notification_builder.build())
使用示例
在你的Kivy代码里,只要调用send_local_notification("通知标题", "这是一条离线本地通知!")就能触发系统通知了。
注意事项
- 自定义图标:如果你不想用系统默认图标,可以把自己的图标放到
res/drawable目录下,然后替换setSmallIcon里的参数,比如autoclass('org.kivy.android.R$drawable').your_icon_name - Android 13+需要动态申请
POST_NOTIFICATIONS权限,你可以用pyjnius调用权限申请API,或者在Buildozer里配置权限后让用户在应用第一次启动时授权
备注:内容来源于stack exchange,提问作者Fabian Joseph




