在启动时启动 Kivy 服务 (Android)

Posted

技术标签:

【中文标题】在启动时启动 Kivy 服务 (Android)【英文标题】:Starting Kivy service on bootup (Android) 【发布时间】:2018-04-02 17:38:54 【问题描述】:

我正在尝试在启动时启动我的 kivy 应用服务。

我确定我的服务没问题,因为它在我启动我的应用程序时工作。但是在启动时我遇到了问题。

我已阅读this article 并尝试过:

package net.saband.myapp;

import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.Context;
import org.kivy.android.PythonActivity;

public class MyBroadcastReceiver extends BroadcastReceiver 
    public void onReceive(Context context, Intent intent) 
        Intent ix = new Intent(context, PythonActivity.class);
        ix.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(ix);
    

它可以工作,但会启动应用程序而不是服务。所以我研究了一些关于 *** 的问题并为此更改了我的代码:

package net.saband.myapp;

import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.Context;
import net.saband.myapp.ServiceMyservice;

public class MyBroadcastReceiver extends BroadcastReceiver 
    public void onReceive(Context context, Intent intent) 
        Intent ix = new Intent(context, ServiceMyservice.class);
        ix.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startService(ix);
    

...并得到一个错误:

10-21 19:16:44.784  1513  1569 I ActivityManager: Start proc 6334:net.saband.myapp:service_myservice/u0a116 for service net.saband.myapp/.ServiceMyservice
10-21 19:16:44.786  6334  6334 I art     : Late-enabling -Xcheck:jni
10-21 19:16:44.885  6334  6334 D AndroidRuntime: Shutting down VM
10-21 19:16:44.888  6334  6334 E AndroidRuntime: FATAL EXCEPTION: main
10-21 19:16:44.888  6334  6334 E AndroidRuntime: Process: net.saband.myapp:service_myservice, PID: 6334
10-21 19:16:44.888  6334  6334 E AndroidRuntime: Theme: themes:
10-21 19:16:44.888  6334  6334 E AndroidRuntime: java.lang.RuntimeException: Unable to start service net.saband.myapp.ServiceMyservice@8c96929 with Intent  cmp=net.saband.myapp/.ServiceMyservice : java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.os.Bundle.getString(java.lang.String)' on a null object reference

您能否解释一下出了什么问题以及我应该怎么做才能启动该服务?谢谢!

更新

应@Juggernaut 的要求,我添加了我的服务代码:

from time import sleep

if __name__ == '__main__':
    while True:
        print "myapp service"
        sleep(5)

当我运行应用程序时它可以工作,因为应用程序调用了服务:

def __start_service(self):
    if platform == 'android':
        service = autoclass('net.saband.myapp.ServiceMyservice')
        mActivity = autoclass('org.kivy.android.PythonActivity').mActivity
        argument = ''
        service.start(mActivity, argument)

更新(AndroidManifest)

这是我的 AndroidManifest.xml 中的一些字符串。

    我有 RECEIVE_BOOT_COMPLETED 权限:

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

    我有接收器:

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

    我已经注册了服务:

    <service android:name="net.saband.myapp.ServiceMyservice" android:process=":service_myservice" />

根据@mariachi 的建议,我尝试在接收器中更改android:enabled="true" to android:enabled="false" 并将android:exported="false" 添加到服务中。在这种情况下,设备启动时什么都不会发生:没有错误,没有服务。

【问题讨论】:

***.com/a/32033021/6764079 @Juggernaut 谢谢你的评论,但我不明白它对我有什么帮助。我试过检查 ix.getExtras() 是的,它是空的,但我不明白为什么,也不明白我应该在这里做什么? 也许您应该与我们分享您的服务代码 @Juggernaut 我已经添加了。 必须将 Activity 传递给 Intent,但您将 Service 传递给它。这就是它失败的原因,但我没有解决方案! 【参考方案1】:

天哪!我通过解决my another issue with kivy service 找到了解决方案。只需添加一些额外内容就足够了。这是工作代码:

package net.saband.myapp;

import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.Context;
import net.saband.myapp.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/main.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);
    

【讨论】:

【参考方案2】:

您尝试启动的服务或活动似乎未初始化。 你没有粘贴你的 AndroidManifest,所以我会写它应该有的。

第一件事是你应该有权限添加在启动时运行:

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

第二件事是你应该在 Manifest 中定义你的接收者:

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

第三件事是您应该定义您尝试启动的服务或活动,例如:

    <activity android:name=".PythonActivity" />
    <service android:name=".ServiceMyservice" android:exported="false"/>

【讨论】:

感谢您的回答,但没有帮助。我已经用我之前的 AndroidManifest 更新了我的问题,我尝试将接收器中的 android:enabled="true" 更改为 android:enabled="false" 并将 android:exported="false" 添加到服务中。但是在这种情况下,当设备启动时什么都没有发生:没有错误,没有服务。 启动时没有错误对您的应用来说是一个好兆头。您可以在您的活动/服务起点周围放置一个记录器,以检查您是否从 BroadcastReceiver 收到任何内容? 当然。看起来 BroadcastReceiver 没有被调用或什么也没有收到,因为我没有看到我的 Log.d 消息,如果我使用我的版本(有android:enabled="true" 和没有android:exported="false"),我可以看到我的 Log.d 消息。 您是否在安装后至少启动了一次应用程序以激活它?我想知道您的应用程序是否处于停止状态,所以它不会收到任何广播。 是的,我有。我总是首先重新安装并运行应用程序,使用 logcat 检查我的服务,然后重新启动设备。

以上是关于在启动时启动 Kivy 服务 (Android)的主要内容,如果未能解决你的问题,请参考以下文章

Kivy:从主应用程序停止 android 服务

Kivy 使用预填充的联系人字段启动 android 意图

导入外部库时 Kivy 在启动时崩溃

移除或更换启动时的 kivy 闪屏

如何在 Kivy 应用程序启动时满足特定条件时自动弹出警报

从 kivy 1.11.1 升级到 kivy 2.0.0 后,应用程序在启动时抛出错误。任何想法?