android 重启后 Kivy 服务未启动

Kivy service not started after reboot in android

我创建了 Kivy android 应用程序,并希望创建一个提醒服务以通过遵循 link here and here 在特定时间显示通知。 当我启动我的应用程序时服务 运行 成功,也可以在从最近的应用程序中清除后自动重新启动。 但是有几个问题我无法解决,希望这里的任何人都可以提供帮助。

  1. 我的服务在重新启动 phone 后无法加载。 logcat.
  2. 有错误
E AndroidRuntime: java.lang.RuntimeException: Unable to start service com.example.test.ServiceMyservice@18ea0a6 with Intent { flg=0x10000000 cmp=com.example.test/.ServiceMyservice (has extras) }: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
  1. 目前我正在使用plyer notification fire every 5 seconds with schedule模块进行测试,服务在2~3小时后停止,没有错误。如果我安排服务每天或每 6 小时显示一次通知,为什么它会被杀死?

这是我的代码。 /service/myservice.py

中的服务文件
import datetime
from plyer import notification
import schedule
import time
def noti():
    notification.notify(title=datetime.datetime.now(), message="test", app_name='test',  timeout=3600, ticker='', toast=False)

class KivyService:
    def __init__(self):
        pass

    def start(self):
        while True:
            schedule.run_pending()
            time.sleep(1)
            runjob = schedule.get_jobs('reminder')
            if not runjob:
                schedule.every(5).seconds.do(noti).tag("reminder")


if __name__ == '__main__':
    service = KivyService()
    service.start()

以下条目已添加到 AndroidManifest.tmpl.xml

 <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

另外,在下面添加

<receiver android:name=".MyBroadcastReceiver" android:enabled="true" android:exported="false">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>

和MyBroadcastReceiver.java

package com.example.test;

import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.Context;
import com.example.test.ServiceMyservice;

public class MyBroadcastReceiver extends BroadcastReceiver {
    public void onReceive(Context context, Intent intent) {
        String package_root = context.getFilesDir().getAbsolutePath();
        String app_root =  package_root + "/app";
        Intent ix = new Intent(context, ServiceMyservice.class);
        ix.putExtra("androidPrivate", package_root);
        ix.putExtra("androidArgument", app_root);
        ix.putExtra("serviceEntrypoint", "./service/myservice.py");
        ix.putExtra("pythonName", "myservice");
        ix.putExtra("pythonHome", app_root);
        ix.putExtra("pythonPath", package_root);
        ix.putExtra("pythonServiceArgument", app_root+":"+app_root+"/lib");
        ix.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startService(ix);
    }
}

示例使用 ix.putExtra("serviceEntrypoint", "./service/main.py");我不确定它是否应该指向我的服务 python 文件,但我遇到了同样的错误。

还有我的buildozer.spec许可部分

android.permissions = INTERNET, ACCESS_NETWORK_STATE, RECEIVE_BOOT_COMPLETED, FOREGROUND_SERVICE

服务

services=myservice:service/myservice.py

谢谢。

如果有人有同样的问题,只是回答我自己的问题。 参考 PythonService.java 第 77 行,它需要参数 serviceStartAsForeground 但在我的参考 link 中缺失,可能是由于版本差异。

boolean serviceStartAsForeground = (
            extras.getString("serviceStartAsForeground").equals("true")
        );

所以我需要在 Java 中添加以下行,无论是 true 还是 false,然后服务才能在重启后启动。

ix.putExtra("serviceStartAsForeground", "false");

但是,后台服务将在下班后被系统终止以释放资源。仍在寻找一种方法使其注册到 android 警报管理器以重复任务,例如调用plyer通知,重启后可以重新注册。