无法从boot_complete接收器启动外部服务

时间:2014-01-22 21:25:03

标签: java android service bootcompleted

我正在尝试使用尽可能少的代码从我的apk启动外部服务。在4.0 AVD上测试包并在logcat中验证响应似乎给出了正确的结果;但是,在实际设备上它不会加载。实际上,它似乎甚至没有在logcat中列出。

这可能是我忽略的东西,只需要第二双眼睛来确认。

StartService.java:

package com.winca.service.start;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

public class StartService extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Intent i = new Intent();
        i.setClassName("com.winca.service", "com.winca.service.StartService");
        context.startService(i);
    }
}

的AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.winca.service.start"
    android:versionCode="13"
    android:versionName="1.3" >

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <uses-sdk android:targetSdkVersion="14" android:minSdkVersion="14"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <receiver android:name="com.winca.service.start.StartService">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
            </intent-filter>
        </receiver>
    </application>
</manifest>

AVD回应:

# getprop ro.build.fingerprint
generic/sdk/generic:4.0.2/ICS_MR0/229537:eng/test-keys
# logcat -c; sleep 1; am broadcast -a android.intent.action.BOOT_COMPLETED; sleep 20; logcat -d | grep winca
Broadcasting: Intent { act=android.intent.action.BOOT_COMPLETED }
Broadcast completed: result=0
W/ActivityManager(   80): Unable to start service Intent { cmp=com.winca.service/.StartService }: not found
#

我实际上期望“找不到”,因为包含该服务的实际包未安装在AVD上。由于系统SharedUserID,我无法安装它。但是,至少我可以看到它试图用AVD加载它,而实际的设备甚至没有在logcat消息中列出。

为了说明原因,当第三方启动器设置为默认值时,此特定Android设备未加载“com.winca.service / .StartService”服务。这可以防止设备上的许多音频服务在激活之前保持禁用状态。所以,我想也许可以快速打包一下;而不是使用像Tasker这样的东西(由于某些未知的原因,力量在这个设备上关闭)。

2 个答案:

答案 0 :(得分:1)

在您的某个组件响应显式Intent之前,您的接收器将无法工作。这种方法的典型方法是由用户运行您的一项活动。在此之前,在Android 3.1+上,您的应用程序处于“停止状态”,其中没有明显注册的接收器将响应广播。

答案 1 :(得分:0)

事实证明,将应用程序移动到/ system / app目录会绕过正常安装中的“已停止状态”。无论如何这是意图,因为用户正在拼凑这个特定Android设备的自定义ROM。问题是我们一直在通过安装它来测试应用程序,导致“停止状态”并阻止它正常执行。但是,使用正确的文件权限将应用程序移动到/ system / app目录允许apk按预期工作。

我认为这种解决方案对大多数第三方开发情况都不实用,例如通过Google Play分发应用程序。为此,您需要遵守允许用户按照CommonsWare的指示安装至少一次意图的约定。

至于为什么它在AVD中运行,回想起来我怀疑它与最初通过Eclipse的Run&gt;安装它有关。调试(F11)机制。我想这使用了一种不同的安装方法,根据“dumpsys package {package.name}”将包标记为“stopped = false”。