Python Kivy/Pyjnius android NotificationListenerService

2024-09-30 02:31:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我想用python中的kivy为android创建一个应用程序,它监听通知

我创建了一个通知_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>

Tags: textlogextrasstringservicenotificationmsgjava
1条回答
网友
1楼 · 发布于 2024-09-30 02:31:00

最近我成功了,所以我在这里写下了我的经历

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"))
        ...

相关问题 更多 >

    热门问题