android 重启后 Kivy 服务未启动
Kivy service not started after reboot in android
我创建了 Kivy android 应用程序,并希望创建一个提醒服务以通过遵循 link here and here 在特定时间显示通知。
当我启动我的应用程序时服务 运行 成功,也可以在从最近的应用程序中清除后自动重新启动。
但是有几个问题我无法解决,希望这里的任何人都可以提供帮助。
- 我的服务在重新启动 phone 后无法加载。 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
- 目前我正在使用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通知,重启后可以重新注册。
我创建了 Kivy android 应用程序,并希望创建一个提醒服务以通过遵循 link here and here 在特定时间显示通知。 当我启动我的应用程序时服务 运行 成功,也可以在从最近的应用程序中清除后自动重新启动。 但是有几个问题我无法解决,希望这里的任何人都可以提供帮助。
- 我的服务在重新启动 phone 后无法加载。 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
- 目前我正在使用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通知,重启后可以重新注册。