尝试在Android上启动服务

Ale*_*lex 327 android broadcastreceiver android-service

当设备在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" />
Run Code Online (Sandbox Code Playgroud)

广播接收器

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");
    }
}
Run Code Online (Sandbox Code Playgroud)

Tim*_*uck 600

其他答案看起来不错,但我想我会把所有内容都包含在一个完整的答案中.

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

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

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    
    Run Code Online (Sandbox Code Playgroud)
  2. 在您的<application>元素中(确保为您使用完全限定的[或相对]类名称BroadcastReceiver):

    <receiver android:name="com.example.MyBroadcastReceiver">  
        <intent-filter>  
            <action android:name="android.intent.action.BOOT_COMPLETED" />  
        </intent-filter>  
    </receiver>
    
    Run Code Online (Sandbox Code Playgroud)

    (你不需要的android:enabled,exported等等,属性: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);
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

从原来的问题:

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

  • 只是补充:确保您的应用程序安装在内部存储器<manifest xmlns:android ="..."package ="..."android:installLocation ="internalOnly"> (50认同)
  • 如果接收器用于不同的东西:<br> if("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())){Intent serviceIntent = new Intent(context,Service_Location.class); // i.putExtra("KEY1","服务使用的值"); context.startService(serviceIntent); } (6认同)
  • 这看起来不错.我将以此为基础,谢谢:).没有选中标记或赞成或悲伤的回应:(.任何人都验证这个? (2认同)
  • 在<receiver>标签中的Android Jellybean 4.2.2中,我必须使用类的相对名称而不是服务的完全限定名称,如http://stackoverflow.com/questions/16671619/android中所述-intentservice-不会启动上启动 (2认同)
  • 您应该扩展https://developer.android.com/reference/android/support/v4/content/WakefulBroadcastReceiver.html.它是实现BroadcastReceiver的常见模式的帮助程序,该接收设备唤醒事件然后将工作传递给服务,同时确保设备在转换期间不会重新进入休眠状态.本课程负责为您创建和管理部分唤醒锁; 您必须请求WAKE_LOCK权限才能使用它. (2认同)

ina*_*ruk 83

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

更多细节在这里在部分广播接收机监听"启动完成"


use*_*968 68

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

首先:从版本Android 3.1+开始,如果用户从未启动过您的应用程序至少一次或用户"强制关闭"应用程序,则不会收到BOOT_COMPLETE.这样做是为了防止恶意软件自动注册服务.此安全漏洞在较新版本的Android中关闭.

解:

使用活动创建应用.当用户运行它时,应用程序可以接收BOOT_COMPLETE广播消息.

第二个:在安装外部存储之前发送BOOT_COMPLETE.如果应用程序安装到外部存储,它将不会收到BOOT_COMPLETE广播消息.

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

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

如果您的应用已安装在内部存储中,则下面的代码可以帮助您了解如何在设备启动时启动服务.


在Manifest.xml中

允许:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
Run Code Online (Sandbox Code Playgroud)

注册您的BOOT_COMPLETED接收器:

<receiver android:name="org.yourapp.OnBoot">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
    </intent-filter>
</receiver>
Run Code Online (Sandbox Code Playgroud)

注册您的服务:

<service android:name="org.yourapp.YourCoolService" />
Run Code Online (Sandbox Code Playgroud)

在接收器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);

    }

 }
Run Code Online (Sandbox Code Playgroud)

对于HTC,如果设备没有捕获RECEIVE_BOOT_COMPLETED,您可能还需要添加Manifest此代码:

<action android:name="android.intent.action.QUICKBOOT_POWERON" />
Run Code Online (Sandbox Code Playgroud)

接收器现在看起来像这样:

<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>
Run Code Online (Sandbox Code Playgroud)

如何在没有重启模拟器或真实设备的情况下测试BOOT_COMPLETED?这很简单.试试这个:

adb -s device-or-emulator-id shell am broadcast -a android.intent.action.BOOT_COMPLETED
Run Code Online (Sandbox Code Playgroud)

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

adb devices
Run Code Online (Sandbox Code Playgroud)

ADT中的adb默认情况下可以在以下位置找到:

adt-installation-dir/sdk/platform-tools
Run Code Online (Sandbox Code Playgroud)

请享用!)


Ton*_*ony 34

随着

<action android:name="android.intent.action.BOOT_COMPLETED" />  
Run Code Online (Sandbox Code Playgroud)

也用,

<action android:name="android.intent.action.QUICKBOOT_POWERON" />
Run Code Online (Sandbox Code Playgroud)

HTC设备似乎没有抓住BOOT_COMPLETED

  • 这在某些情况下可能很有用,但我知道HTC Fast Boot是一种休眠形式,系统状态保存到文件系统,而`android.intent.action.QUICKBOOT_POWERON`仅在从快速启动恢复时发送.这意味着在保存时从快速启动恢复时不必执行重置警报等操作.因此,如果您想在用户认为设备已启动时执行某些操作,则只需要使用`<action android:name ="android.intent.action.QUICKBOOT_POWERON"/>`. (2认同)
  • 从应用程序开发人员的角度来看,如果行为仅存在于HTC设备上,我们就不应该使用它.因为,根据文档,BOOT_COMPLETED将始终在设备开启时发送.其他一些制造商可能会提出另一种快速启动的方法,我们最终会在每个规范中弄乱我们的代码. (2认同)

Evg*_*man 20

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

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

代替 :

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

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


Ome*_*ter 13

我刚刚发现它可能是因为>中的Fast Boot选项SettingsPower

当我关闭此选项时,我的应用程序会收到此广播,但不是.

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

希望能帮助到你.


Ric*_*red 12

我认为您的清单需要添加:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
Run Code Online (Sandbox Code Playgroud)


Ami*_*mir 7

在尝试了所有提到的答案和技巧之后,我终于找到了为什么代码在我的手机中不起作用.某些Android手机如"Huawei Honor 3C Android 4.2.2 " 在其设置中有一个Statup Manager菜单,您的应用必须在列表中进行检查.:)


Nic*_*ick 5

我有一个额外的<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>
Run Code Online (Sandbox Code Playgroud)

您是否尝试过省略if-clause "android.intent.action.BOOT_COMPLETED".equals(intent.getAction(),因为接收器可能只接收到该意图?

  • 以防万一:将Android.intent.category.HOME添加到AndroidManifest中的任何标签都会导致Samsung Galaxy Tab在兼容模式下运行应用程序,即使在使用hack关闭兼容模式之后也是如此.不确定其他标签是否相同.我建议不要设置HOME类别.这是不必要的. (2认同)

小智 5

这就是我所做的

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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>
    ...
Run Code Online (Sandbox Code Playgroud)

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);
...
Run Code Online (Sandbox Code Playgroud)

我从 ApiDemos 学到的最后一步