在Android启动时启动Kivy服务

11

我希望在启动时启动我的Kivy应用程序服务。

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

我阅读了这篇文章并尝试着去做。

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);
    }
}

它可以工作,但只启动应用程序而不启动服务。所以我在StackOverflow上研究了一些问题,并针对此更改了我的代码:

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 中的一些字符串:

  1. 我拥有 RECEIVE_BOOT_COMPLETED 权限:

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

  2. 我拥有 receiver:

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

  3. 我注册了 service:

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

根据 @mariachi 的建议,我尝试将 receiver 中的 android:enabled="true" 更改为 android:enabled="false",并在 service 中添加 android:exported="false"。在这种情况下,设备启动时不会发生任何事情:没有错误,也没有服务。


https://dev59.com/e47da4cB1Zd3GeqP9CFy#32033021 - Juggernaut
3
一个Activity必须被传递给Intent,但你正在将一个Service传递给它。这就是失败的原因,但我没有解决方案! - Juggernaut
看起来你正在尝试从意图的捆绑包中访问额外的内容,但是它导致了崩溃。如果能提供更多关于你实际服务实现的代码将会很有帮助。此外,在启动服务之前,你没有向意图添加任何额外的内容,这很可能是你尝试访问它们时发生崩溃的原因。 - Submersed
@Submersed 感谢您的评论。我已经添加了我的 AndroidManifest。这就是全部 - 我的服务周围没有更多的代码。在我的情况下,我应该添加哪些额外内容? - Andrzej S.
3个回答

2

哇塞!我通过解决kivy服务的其他问题找到了解决方案。只需要添加一些额外的内容就可以了。这是可行的代码:

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);
    }
}

1
似乎您尝试启动的服务或活动未初始化。由于您没有粘贴AndroidManifest,所以我会写出它应该具有的内容。
首先,您应该添加在启动时运行的权限:
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

第二件事是在清单文件中定义接收器: ```xml

您需要在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"。但是在这种情况下,当设备启动时什么也不会发生:没有错误,也没有服务。 - Andrzej S.
启动时没有错误是您的应用程序的好兆头。您能否在活动/服务的起始点周围放置一个记录器,以检查是否从广播接收器接收到任何内容? - mariachi
是的,我有。我通常会先重新安装并运行应用程序,使用logcat检查我的服务,然后重新启动设备。 - Andrzej S.
我想知道你是否真的需要为你的接收器和服务指定android:process?根据文档: “应用程序组件通常在为整个应用程序创建的单个进程中运行。如果进程名称以“:”字符开头,则在需要运行该组件时将创建一个新的专用于该应用程序的进程(允许您将应用程序分布在多个进程中)。" - 因此,您的应用程序、接收器和服务存在于不同的进程中。我不确定这是否是问题的原因,但我会尝试从两者中删除android:process - mariachi
同一份文档中写道:“指定相关代码要在哪个特定进程中运行。可与应用程序标签一起使用(为所有应用程序组件提供默认进程),或与活动、接收器、服务或提供者标签一起使用(为该组件提供特定图标)。”另外还有:“如果进程名称以小写字符开头,则该组件将在该名称的全局进程中运行,前提是您有权限这样做,从而允许多个应用程序共享一个进程以减少资源使用。”我认为你应该去掉“:”,并尝试使用应用程序标签。 - mariachi
显示剩余3条评论

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

这并没有回答问题。一旦您拥有足够的声望,您将能够评论任何帖子;相反,提供不需要询问者澄清的答案。- 来自审核 - Daraan
https://habr.com/ru/post/694906/ - Jessy James

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接