I want to create an application for android with kivy in python, which Listens for notification.
I created a 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()
but how do I have to add the to the AndroidManifest.xml? if I would do it in Java, the following code would be correct but its a python file, so how do I have to implement it?
<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>
Recently I made it work, so I am writing here about my experience.
Buildozer does not provide any options for registering a service with permissions and an intent-filter. However, you can customize AndroidManifest.xml from the template file which is located in your .buildozer directory.
You can insert the xml block between "end-if" and "if" so that it won't be changed by the buildozer.spec settings.
Next thing you need to make is a java class file. Unfortunately, python class cannot be bound to NotificationListeners, so you need to manually copy a java class that receives StatusBarNotifications.
The path is going to be:
With the java class, you can broadcast the StatusBarNotification to the python side,
getApplicationContext().sendBroadcast(intent);, and p4a's android.broadcast.BroadcastReceiver will receive the object on main.py.Java class
main.py