Python Kivy/Pyjnius android NotificationListenerService
Posted
技术标签:
【中文标题】Python Kivy/Pyjnius android NotificationListenerService【英文标题】: 【发布时间】:2021-06-13 14:14:17 【问题描述】:我想用python中的kivy为android创建一个应用程序,它监听通知。
我创建了一个 notification_listener.py:
from kivy import platform
if platform == "android":
from jnius import autoclass, cast, PythonJavaClass, java_method
from android.runnable import run_on_ui_thread
PythonActivity = autoclass("org.kivy.android.PythonActivity")
Activity = autoclass("android.app.Activity")
Context = autoclass("android.content.Context")
NotificationListenerService = autoclass("android.service.notification.NotificationListenerService")
StatusBarNotification = autoclass("android.service.notification.StatusBarNotification")
Log = autoclass("android.util.Log")
Toast = autoclass("android.widget.Toast")
String = autoclass("java.lang.string")
CharSequence = autoclass("java.lang.CharSequence")
activity = PythonActivity.mActivity
currentActivity = cast(Activity, activity)
context = cast(Context, currentActivity.getApplicationContext())
class NotificationListener(PythonJavaClass):
__javaclass__ = "android.service.notification.NotificationListenerService"
__javacontext__ = "app"
@java_method("()V")
def onCreate(self):
super(NotificationListener, self).onCreate()
text = cast(CharSequence, String("Listener started..."))
toast = Toast.makeText(context, text, Toast.LENGTH_LONG)
toast.show()
@java_method("(Landroid/service/notification/StatusBarNotification)V")
def onNotificationPosted(self, sbn):
notification = cast(StatusBarNotification, sbn)
extras = notification.getNotification().extras
tag = String("Notification recived")
msg_title = String("title: %s" % (extras.getString("android.title")))
msg_text = String("text: %s" % (extras.getString("android.text")))
Log.v(tag, msg_title)
Log.v(tag, msg_text)
text = cast(CharSequence, String("Notification recieved..."))
toast = Toast.makeText(context, text, Toast.LENGTH_LONG)
toast.show()
但我必须如何将其添加到 AndroidManifest.xml 中? 如果我用Java来做,下面的代码是正确的,但它是一个python文件,那么我该如何实现呢? ????
<service name=".NotificationListener"
android:label="notification_listener"
android:permissions="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
<intent-filter>
<action android:name="android.service.notification.NotificationListenerService" />
</intent-filter>
</service>
【问题讨论】:
【参考方案1】:最近我成功了,所以我在这里写下我的经历。
Buildozer 不提供任何选项来注册具有权限和意图过滤器的服务。但是,您可以从 .buildozer 目录中的模板文件自定义 AndroidManifest.xml。
/your/project/home/.buildozer/android/platform/build-armeabi-v7a/dists/yourapp__armeabi-v7a/templates/AndroidManifest.tmpl.xml
您可以在“end-if”和“if”之间插入 xml 块,这样它就不会被 buildozer.spec 设置更改。
接下来你需要做的是一个java类文件。可惜python类不能绑定NotificationListeners,所以需要手动复制一个接收StatusBarNotifications的java类。
路径将是:
/your/project/home/.buildozer/android/platform/build-armeabi-v7a/dists/yourapp__armeabi-v7a/src/main/java/your/app/domain/NotificationListener.java
通过java类,可以将StatusBarNotification广播到python端getApplicationContext().sendBroadcast(intent);
,p4a的android.broadcast.BroadcastReceiver会接收到main.py上的对象。
Java 类
@Override
public void onNotificationPosted(StatusBarNotification sbn)
super.onNotificationPosted(sbn);
try
Bundle bundle = new Bundle();
bundle.putParcelable("sbn",sbn);
Intent intent = new Intent("action_name_matches_with_java_side");
intent.putExtra("sbn",sbn);
getApplicationContext().sendBroadcast(intent);
catch(Exception e)
Log.v("KIVYAPP","Notification broadcasting prohibited");
main.py
class YourApp(App):
def build(self):
...
self.br = BroadcastReceiver(self.onReceive,actions=["action_name_matches_with_java_side"])
self.br.start()
...
def onReceive(self, context, intent):
bundle = cast(Bundle, intent.getExtras())
sbn = cast(StatusBarNotification,bundle.getParcelable("sbn"))
...
【讨论】:
以上是关于Python Kivy/Pyjnius android NotificationListenerService的主要内容,如果未能解决你的问题,请参考以下文章
Python Kivy/Pyjnius android NotificationListenerService
如何使用 kivy、pyjnius 为 android 制作 GPS 应用程序?