尝试在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" /> 

广播接收器

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

谢谢

其他答案看起来不错,但我想我会把所有东西都包装成一个完整的答案。

您需要在您的AndroidManifest.xml文件中使用以下内容:

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

     <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> 
  2. 在您的<application>元素中(确保为您的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); } } 

从原来的问题来看:

  • 目前还不清楚<receiver>元素是否在<application>元素中
  • 目前尚不清楚是否指定了BroadcastReceiver的正确完全限定(或相对)类名
  • <intent-filter>有一个错字

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

更多细节在这里 广播接收器听“启动完成”

如何启动设备启动服务(自动运行应用程序等)

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

解:

用活动创build应用程序。 当用户运行它时,应用程序可以收到BOOT_COMPLETE广播消息。

其次:BOOT_COMPLETE在外部存储装载之前发送。 如果应用程序安装到外部存储,它将不会收到BOOT_COMPLETE广播消息。

在这种情况下有两个解决scheme:

  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,则可能还需要添加清单中的此代码:

 <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> 

如何testingBOOT_COMPLETED而不重新启动模拟器或真实设备? 这很容易。 尝试这个:

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

如何获取设备ID? 获取具有ID的连接设备的列表:

 adb devices 

在ADT ADB默认情况下你可以find:

 adt-installation-dir/sdk/platform-tools 

请享用! )

随着

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

也用,

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

HTC设备似乎没有捕获BOOT_COMPLETED

请注意,在问题开始时,有一个错字:

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

代替 :

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

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

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

当我有这个选项closures,我的应用程序收到这个广播,但没有其他。

顺便说一句,我有HTC Incredible S Android 2.3.3

希望它有帮助。

我认为你的清单需要补充:

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

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

 <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-子句"android.intent.action.BOOT_COMPLETED".equals(intent.getAction() ,因为接收者可能只接收到这个意图呢?

在尝试所有提到的答案和技巧之后,我终于发现为什么代码在我的手机中不起作用。 一些Android手机,如“华为荣耀3C 安卓4.2.2 ”,在他们的设置有一个Statuppipe理器菜单,你的应用程序必须在列表中检查。 🙂

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

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

一些macros达电设备可以启用“快速启动”function,更像是深度hibernate,而不是真正的重启,因此不应该给BOOT_COMPLETE意图。 要恢复这个,你可以在你的接收器里添加这个意图filter:

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

如果您使用的是Android Studio,并且您非常喜欢自动完成,那么我必须通知您,我正在使用Android Studio 1.1.0版,并且我使用了自动完成function以获得以下权限

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

和Android Studio自动完成RECEIVE_BOOT_COMPLETED所有在像receive_boot_completed小写,我不停地拉我的头发,因为我已经勾出我的清单的事情要做,以启动服务启动。 我刚刚再次确认

Android Studio将自动完成小写的权限。

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

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

正如@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); } } 

然后,在您的服务中,确保释放唤醒locking:

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

别忘了把WAKE_LOCK permssion加到你的mainfest中:

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

我面临这个问题,如果我留在接收器类中的空构造函数。 删除空的contsructor onRreceive methos后开始工作正常。

这就是我所做的

我做了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); } } 

在清单中

 <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那里学到了最后一步