327 votes

Essayer de démarrer un service au démarrage sur Android

J'ai essayé de lancer un service au démarrage d'un appareil sous Android, mais je n'arrive pas à le faire fonctionner. J'ai consulté un certain nombre de liens en ligne, mais aucun code ne fonctionne. Est-ce que j'oublie quelque chose ?

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

Récepteur de diffusion

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

600voto

Timo Bruck Points 4713

Les autres réponses semblent bonnes, mais j'ai pensé que je pourrais tout regrouper en une seule réponse complète.

Vous avez besoin des éléments suivants dans votre AndroidManifest.xml fichier :

  1. Dans votre <manifest> élément :

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
  2. Dans votre <application> (veillez à utiliser un nom de classe entièrement qualifié [ou relatif] pour votre élément BroadcastReceiver ) :

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

    (vous n'avez pas besoin de la android:enabled , exported etc., attributs : les valeurs par défaut d'Android sont correctes)

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

De la question originale :

  • il n'est pas clair si le <receiver> était dans l'élément <application> élément
  • il n'est pas clair si le nom de classe entièrement qualifié (ou relatif) correct pour la classe BroadcastReceiver a été spécifié
  • il y avait une faute de frappe dans le <intent-filter>

83voto

inazaruk Points 37760

Comme information supplémentaire : BOOT_COMPLETE est envoyé aux applications. antes de le stockage externe est monté. Ainsi, si l'application est installée sur le stockage externe, elle ne recevra pas le message de diffusion BOOT_COMPLETE.

Plus de détails aquí en section Récepteurs de diffusion à l'écoute de "démarrage terminé"

68voto

user3439968 Points 118

Comment lancer un service au démarrage du périphérique (application autorun, etc.) ?

Tout d'abord, depuis la version Android 3.1+, vous ne recevez pas BOOT_COMPLETE si l'utilisateur n'a jamais démarré votre application au moins une fois ou si l'utilisateur a "forcé la fermeture" de l'application. Cela a été fait pour empêcher les logiciels malveillants d'enregistrer automatiquement un service. Cette faille de sécurité a été comblée dans les versions plus récentes d'Android.

Solution :

Créez une application avec une activité. Lorsque l'utilisateur l'exécute une fois, l'application peut recevoir le message de diffusion BOOT_COMPLETE.

Pour la seconde : BOOT_COMPLETE est envoyé avant que le stockage externe soit monté. Si l'application est installée sur le stockage externe, elle ne recevra pas le message de diffusion BOOT_COMPLETE.

Dans ce cas, il y a deux solutions :

  1. Installez votre application sur le stockage interne
  2. Installez une autre petite application dans le stockage interne. Cette application reçoit BOOT_COMPLETE et lance la deuxième application sur le stockage externe.

Si votre application est déjà installée dans le stockage interne, le code ci-dessous peut vous aider à comprendre comment démarrer le service au démarrage de l'appareil.


Dans Manifest.xml

Permission :

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

Enregistrez votre récepteur BOOT_COMPLETED :

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

Enregistrez votre service :

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

Dans le récepteur 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);

    }

 }

Pour HTC, vous devez peut-être aussi ajouter dans le manifeste ce code si le dispositif n'attrape pas RECEIVE_BOOT_COMPLETED :

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

Les récepteurs ressemblent maintenant à ceci :

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

Comment tester BOOT_COMPLETED sans redémarrer l'émulateur ou le dispositif réel ? C'est facile. Essayez ceci :

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

Comment obtenir l'identifiant de l'appareil ? Obtenir la liste des appareils connectés avec leurs identifiants :

adb devices

adb dans ADT par défaut que vous pouvez trouver dans :

adt-installation-dir/sdk/platform-tools

Profitez-en ! )

34voto

Tony Points 290

Avec

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

utiliser également,

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

Les appareils HTC ne semblent pas capter BOOT_COMPLETED.

20voto

Evgeny Erlihman Points 238

Notez qu'au début de la question, il y a une erreur de frappe :

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

au lieu de :

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

un petit "_" et tous ces problèmes :)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X