试图在Android上启动一个服务

我一直试图在设备在android上启动时启动一项服务,但我无法让它工作。我在网上看了一些链接,但没有一个代码工作。我是不是忘了什么?

AndroidManifest.xml

<receiver
android:name=".StartServiceAtBootReceiver"
android:enabled="true"
android:exported="false"
android:label="StartServiceAtBootReceiver" >
<intent-filter>
<action android:name="android.intent.action._BOOT_COMPLETED" />
</intent-filter>
</receiver>


<service
android:name="com.test.RunService"
android:enabled="true" />

BroadcastReceiver

public void onReceive(Context context, Intent intent) {
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
Intent serviceLauncher = new Intent(context, RunService.class);
context.startService(serviceLauncher);
Log.v("TEST", "Service loaded at start");
}
}
196637 次浏览

我有一个额外的__abc0标签,不知道这是否有任何区别。

<receiver android:name="BootIntentReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.HOME" />
</intent-filter>
</receiver>

你有没有试过省略if-clause "android.intent.action.BOOT_COMPLETED".equals(intent.getAction(),因为接收者可能只接收到那个意图?

我认为你们的货单需要加上:

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

作为附加信息:BOOT_COMPLETE被发送到应用程序之前外部存储被挂载。因此,如果应用程序被安装到外部存储,它将不会收到BOOT_COMPLETE广播消息。

更多有关在这里的详细信息见广播接收器正在监听“引导完成”

请注意,在问题的开头,有一个拼写错误:

<action android:name="android.intent.action._BOOT_COMPLETED"/>

而不是:

<action android:name="android.intent.action.BOOT_COMPLETED"/>

一个小“_”和所有这些麻烦:)

其他答案看起来不错,但我认为我应该把所有问题都归结为一个完整的答案。

你需要在你的AndroidManifest.xml文件中包含以下内容:

  1. 在你的<manifest>元素中:

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    
  2. In your <application> element (be sure to use a fully-qualified [or relative] class name for your BroadcastReceiver):

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

    (你不需要android:enabledexported等属性:Android默认值是正确的)

    MyBroadcastReceiver.java:

    package com.example;
    
    
    public class MyBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
    Intent startServiceIntent = new Intent(context, MyService.class);
    context.startService(startServiceIntent);
    }
    }
    

From the original question:

  • it's not clear if the <receiver> element was in the <application> element
  • it's not clear if the correct fully-qualified (or relative) class name for the BroadcastReceiver was specified
  • there was a typo in the <intent-filter>

我刚刚发现,这可能是因为Settings > Power中的Fast Boot选项

当我关闭这个选项时,我的应用程序接收到一个this广播,而不是其他。

顺便说一下,我在HTC Incredible S上有Android 2.3.3

希望能有所帮助。

随着

<action android:name="android.intent.action.BOOT_COMPLETED" />

也使用,

<action android:name="android.intent.action.QUICKBOOT_POWERON" />

HTC设备似乎没有捕捉BOOT_COMPLETED

事实上,我不久前遇到了这个麻烦,而且它非常非常容易修复,如果你设置了"android.intent.action.BOOT_COMPLETED"权限和意图过滤器,你实际上没有做错任何事情。

注意,如果你在Android 4。X,你必须在启动服务之前运行广播监听器,这意味着,你必须先添加一个活动,一旦你的广播接收器运行,你的应用程序应该像你预期的那样运行,然而,在Android 4上。X,我还没有找到一种方法来启动启动没有任何活动的服务,我认为谷歌这样做是出于安全原因。

如何在设备启动时启动服务(autorun app等)

首先:自版本Android 3.1+你不会收到BOOT_COMPLETE如果用户从未启动你的应用程序至少一次或用户“强制关闭”应用程序。 这样做是为了防止恶意软件自动注册服务。此安全漏洞在新版本的Android中已被关闭

解决方案:

创建带有活动的应用程序。当用户运行它一次应用程序可以收到BOOT_COMPLETE广播消息。

第二:在挂载外部存储之前发送BOOT_COMPLETE。如果app被安装到外部存储,它不会收到BOOT_COMPLETE广播消息。

在这种情况下,有两个解决方案:

  1. 将应用程序安装到内部存储
  2. 在内部存储中安装另一个小应用程序。这个应用程序接收BOOT_COMPLETE并在外部存储上运行第二个应用程序。

如果你的应用程序已经安装在内部存储中,那么下面的代码可以帮助你理解如何在设备启动时启动服务。


在Manifest.xml

许可:

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

注册你的BOOT_COMPLETED接收器:

<receiver android:name="org.yourapp.OnBoot">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>

注册您的服务:

<service android:name="org.yourapp.YourCoolService" />

在接收器OnBoot.java中:

public class OnBoot extends BroadcastReceiver
{


@Override
public void onReceive(Context context, Intent intent)
{
// Create Intent
Intent serviceIntent = new Intent(context, YourCoolService.class);
// Start service
context.startService(serviceIntent);


}


}

对于HTC,如果设备没有捕获RECEIVE_BOOT_COMPLETED,你可能还需要在Manifest中添加这段代码:

<action android:name="android.intent.action.QUICKBOOT_POWERON" />

接收器现在看起来是这样的:

<receiver android:name="org.yourapp.OnBoot">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver>

如何在没有重新启动模拟器或真实设备的情况下测试BOOT_COMPLETED ? 很容易。试试这个:< / p >

adb -s device-or-emulator-id shell am broadcast -a android.intent.action.BOOT_COMPLETED

如何获取设备id?获取带有id的连接设备列表:

adb devices

默认情况下,您可以在ADT中找到:

adt-installation-dir/sdk/platform-tools

享受!)

如果在接收类中保留空构造函数,就会遇到这个问题。删除空构造函数后,onRreceive方法开始正常工作。

如果你正在使用Android Studio,你非常喜欢自动完成,那么我必须告诉你,我正在使用Android Studio v 1.1.0,我使用自动完成以下权限

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

和Android Studio自动完成__abc0都在小写,像receive_boot_completed和我一直拉我的头发,因为我已经打了我的检查表的事情要做启动服务在启动。我刚刚再次确认

Android Studio会自动用小写完成此权限。

正如@Damian评论的那样,这个帖子里的所有答案都是错误的。手动这样做会有服务在设备进入睡眠状态时中途停止的风险。你需要先获得一个尾流锁。幸运的是,支持库给了我们一个类可以这样做:

public class SimpleWakefulReceiver extends WakefulBroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// This is the Intent to deliver to our service.
Intent service = new Intent(context, SimpleWakefulService.class);


// Start the service, keeping the device awake while it is launching.
Log.i("SimpleWakefulReceiver", "Starting service @ " + SystemClock.elapsedRealtime());
startWakefulService(context, service);
}
}

然后,在你的服务中,确保释放唤醒锁:

    @Override
protected void onHandleIntent(Intent intent) {
// At this point SimpleWakefulReceiver is still holding a wake lock
// for us.  We can do whatever we need to here and then tell it that
// it can release the wakelock.


...
Log.i("SimpleWakefulReceiver", "Completed service @ " + SystemClock.elapsedRealtime());
SimpleWakefulReceiver.completeWakefulIntent(intent);
}

不要忘记在mainfest中添加WAKE_LOCK权限:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
在尝试了所有提到的答案和技巧后,我终于发现为什么代码不能在我的手机上工作。一些Android手机,如“Huawei Honor 3C Android 4.2.2”,在他们的设置中有一个Statup经理菜单,你的应用程序必须在列表中勾选。 :) < / p >

在挂载外部存储之前,BOOT_COMPLETE被发送执行。如果你的应用被安装到外部存储,它不会收到BOOT_COMPLETE广播消息。为了防止这种情况,可以将应用程序安装在内部存储中。只需在menifest.xml中添加这一行即可

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:installLocation="internalOnly"
... >

一些HTC设备可以启用“快速启动”功能,这更像是深度休眠,而不是真正的重新启动,因此不应该给出BOOT_COMPLETE意图。为了恢复这个,你可以在你的接收器中添加这个intent过滤器:

            <intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
</intent-filter>

这就是我所做的

1. 我创建了Receiver类

public class BootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//whatever you want to do on boot
Intent serviceIntent = new Intent(context, YourService.class);
context.startService(serviceIntent);
}
}

2.在清单中

<manifest...>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application...>
<receiver android:name=".BootReceiver" android:enabled="true" android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
...

3.你需要在MainActivity中“设置”接收器,它可能在onCreate中

...
final ComponentName onBootReceiver = new ComponentName(getApplication().getPackageName(), BootReceiver.class.getName());
if(getPackageManager().getComponentEnabledSetting(onBootReceiver) != PackageManager.COMPONENT_ENABLED_STATE_ENABLED)
getPackageManager().setComponentEnabledSetting(onBootReceiver,PackageManager.COMPONENT_ENABLED_STATE_ENABLED,PackageManager.DONT_KILL_APP);
...

这是我从ApiDemos中学到的最后一个步骤