【问题标题】:Kivy service not started after reboot in android在android中重新启动后未启动Kivy服务
【发布时间】:2021-05-07 14:52:48
【问题描述】:

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

  1. 重启手机后我的服务无法加载。 logcat 有错误。
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 模块每5 秒触发一次plyer 通知测试,该服务在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

谢谢。

【问题讨论】:

    标签: python android kivy android-service


    【解决方案1】:

    如果有人遇到同样的问题,请回答我自己的问题。 参考 PythonService.java 第 77 行它需要一个参数 serviceStartAsForeground 但在我的参考链接中缺少,可能是由于版本差异。

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

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

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

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

    【讨论】:

      猜你喜欢
      • 2018-04-02
      • 1970-01-01
      • 2011-04-21
      • 2020-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多