Aller au contenu

[TUTO] Lancer un service au boot de la machine


xma

Recommended Posts

Salut,

sur anddev, quelqu'un cherchait à faire un truc simple: qu'un service démarre lors du boot de son appareil (sans avoir à cliquer dans le home). Comme je lui ai filé la réponse et vu que ça pourrait service à d'autres, je vous soumets la solution. Ce code est placé sous http://www.gnu.org/copyleft/gpl.html GPLv3. Merci de bien la lire avant de reprendre ce code dans vos développements.

De quoi avons-nous besoin ?

Des 3 items suivants:

  • une permission pour savoir lorsque le boot est terminé
  • un broadcast receiver
  • un service quelconque

Commençons par écrire le squelette d'un service "vide" ne faisant rien d'autre qu'afficher son état:

/*
Test app to demo OnBootReceiver (starting a service on boot).

Copyright (C) 2010 by Xavier Maillard 

This is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

It is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
*/

package im.maillard.android.onbootservice;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

public class MySimpleService extends Service {

   public MySimpleService() {
   }

   @Override
   public IBinder onBind(Intent arg0) {
       // TODO Auto-generated method stub
       return null;
   }

   @Override
   public void onRebind(Intent intent) {
       super.onRebind(intent);
       Log.d("TestApp", ">>>onRebind()");
   }

   @Override
   public void onCreate() {
       super.onCreate();
       Log.d("TestApp", ">>>onCreate()");
   }

   @Override
   public void onStart(Intent intent, int startId) {
       super.onStart(intent, startId);
       Log.d("TestApp", ">>>onStart()");
   }

   @Override
   public boolean onUnbind(Intent intent) {
       return super.onUnbind(intent);
   }
}

Très simple :D

Ensuite, passons à l'écriture de notre broadcast receiver qui sera chargé de démarrer notre service au moment opportun:

/*
Test app to demo OnBootReceiver (starting a service on boot).

Copyright (C) 2010 by Xavier Maillard 

This is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

It is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
*/

package im.maillard.android.onbootservice;

import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;

public class OnBootReceiver extends BroadcastReceiver {

   public static final String TAG = "TestApp";

   @Override
   public void onReceive(Context context, Intent intent) {
       Log.d("TestApp", "Got the Boot Event>>>");
       Log.d("TestApp", "Starting MySimpleService>>>");
       context.startService(new Intent().setComponent(new ComponentName(
               context.getPackageName(), MySimpleService.class.getName())));
   }
}

Pour blinder le truc et si nous avions voulu réagir à d'autres intents, nous aurions pu tester que l'intent reçu était bien celui attendu par exemple en faisant:

if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) { 
              Log.d("TestApp", "Got the Boot Event>>>"); 
         } 

Voilà, nous avons nos deux morceaux de code, maintenant passons à l'étape ultime: le manifest.

Rien de bien plus compliqué ici, notre programme n'a pas la légitimité d'être lancé autrement que par un intent spécial (pas besoin d'un clic dans le launcher, etc.).

Nous devons donc simplement glisser dans notre manifest la déclaration de notre broadcast receiver (avec son intent-filter sur android.intent.action.BOOT_COMPLETED), déclarer notre service MySimpleService et ajouter la permission pour autoriser notre programme à lire et connaître l'état du boot.

<?xml version="1.0" encoding="utf-8"?> 
    package="im.maillard.android.onbootservice" android:versionCode="1" 
    android:versionName="1.0"> 

              android:exported="false" android:label="OnBootReceiver"> 





              android:exported="false" android:label="MySimpleService" /> 



Lorsque vous mettez tout cela en musique et que vous lancez le programme, un petit détour par logcat vous donnera ceci:

D/PackageManager( 52): Services: im.maillard.android.onbootservice.MySimpleService

D/PackageManager( 52): Receivers: im.maillard.android.onbootservice.OnBootReceiver

I/installd( 31): move /data/dalvik-cache/data@app@vmdl15924.tmp@classes.dex -> /data/dalvik-cache/data@app@im.maillard.android.onbootservice.apk@classes.dex

D/PackageManager( 52): New package installed in /data/app/im.maillard.android.onbootservice.apk

D/AndroidRuntime( 117): Shutting down VM

D/dalvikvm( 117): DestroyJavaVM waiting for non-daemon threads to exit

D/dalvikvm( 117): DestroyJavaVM shutting VM down

D/dalvikvm( 117): HeapWorker thread shutting down

D/dalvikvm( 117): HeapWorker thread has shut down

D/jdwp ( 117): JDWP shutting down net...

D/dalvikvm( 117): VM cleaning up

D/dalvikvm( 117): LinearAlloc 0x0 used 663068 of 4194304 (15%)

I/WindowManager( 52): Config changed: { scale=1.0 imsi=0/0 loc=fr_CH touch=3 keys=2/1/2 nav=3 orien=1 layout=18}

D/ddm-heap( 129): Got feature list request

D/dalvikvm( 52): GC freed 5361 objects / 354488 bytes in 182ms

D/ActivityManager( 52): Uninstalling process im.maillard.android.onbootservice

D/dalvikvm( 52): GC freed 1172 objects / 53120 bytes in 112ms

D/ActivityManager( 52): Uninstalling process im.maillard.android.onbootservice

D/HomeLoaders( 99): application intent received: android.intent.action.PACKAGE_REMOVED, replacing=true

D/HomeLoaders( 99): --> package:im.maillard.android.onbootservice

D/HomeLoaders( 99): application intent received: android.intent.action.PACKAGE_ADDED, replacing=true

D/HomeLoaders( 99): --> package:im.maillard.android.onbootservice

D/HomeLoaders( 99): --> update package im.maillard.android.onbootservice

D/MountListener( 52): handleEvent ums_disabled

D/MountListener( 52): handleEvent ums_disconnected

I/ActivityManager( 52): Start proc android.process.media for broadcast com.android.providers.downloads/.DownloadReceiver: pid=160 uid=10005 gids={1006, 1015, 2001, 3003}

I/ActivityManager( 52): processNextBroadcast: waiting for ProcessRecord{438d12d0 160:android.process.media/10005}

I/jdwp ( 160): received file descriptor 10 from ADB

E/ActivityThread( 94): Failed to find provider info for android.server.checkin

W/Checkin ( 94): Can't update stat PHONE_GSM_REGISTERED: java.lang.IllegalArgumentException: Unknown URL content://android.server.checkin/stats

D/ddm-heap( 160): Got feature list request

I/ActivityManager( 52): processNextBroadcast: waiting for ProcessRecord{438d12d0 160:android.process.media/10005}

I/ActivityManager( 52): processNextBroadcast: waiting for ProcessRecord{438d12d0 160:android.process.media/10005}

D/dalvikvm( 52): GC freed 3333 objects / 236136 bytes in 142ms

D/HomeLoaders( 99): aborting loaders

I/ActivityManager( 52): processNextBroadcast: waiting for ProcessRecord{438d12d0 160:android.process.media/10005}

I/ActivityThread( 160): Publishing provider downloads: com.android.providers.downloads.DownloadProvider

W/ResourceType( 52): No package identifier when getting value for resource number 0x7f060000

I/ActivityThread( 160): Publishing provider drm: com.android.providers.drm.DrmProvider

W/ResourceType( 52): No package identifier when getting value for resource number 0x7f060001

I/ActivityThread( 160): Publishing provider media: com.android.providers.media.MediaProvider

W/ResourceType( 52): No package identifier when getting value for resource number 0x7f060000

W/ResourceType( 52): No package identifier when getting value for resource number 0x7f060001

D/GpsLocationProvider( 52): state: DISCONNECTED apnName: null reason: radioTurnedOff

D/GpsLocationProvider( 52): state: DISCONNECTED apnName: null reason: gprsDetached

V/MediaProvider( 160): Attached volume: internal

D/HomeLoaders( 99): load applications

D/HomeLoaders( 99): loading user items

D/HomeLoaders( 99): --> starting workspace loader

D/GpsLocationProvider( 52): state: DISCONNECTED apnName: null reason: null

D/StatusBar( 52): updateResources

D/HomeLoaders( 99): ----> running workspace loader (2)

D/TelephonyProvider( 94): Setting numeric '310260' to be the current operator

E/ActivityThread( 94): Failed to find provider info for android.server.checkin

W/Checkin ( 94): Can't update stat PHONE_GPRS_ATTEMPTED: java.lang.IllegalArgumentException: Unknown URL content://android.server.checkin/stats

E/ActivityThread( 94): Failed to find provider info for android.server.checkin

W/Checkin ( 94): Can't update stat PHONE_GPRS_CONNECTED: java.lang.IllegalArgumentException: Unknown URL content://android.server.checkin/stats

D/GpsLocationProvider( 52): state: CONNECTING apnName: epc.tmobile.com reason: simLoaded

D/MobileDataStateTracker( 52): CONNECTED event did not supply interface name.

D/MobileDataStateTracker( 52): DNS server addresses are not known.

D/GpsLocationProvider( 52): state: CONNECTED apnName: epc.tmobile.com reason: simLoaded

D/GpsLocationProvider( 52): updateNetworkState available

D/GpsLocationProvider( 52): NetworkThread wait for 9223372036854775807ms

D/HomeLoaders( 99): --> done loading workspace

D/HomeLoaders( 99): ----> worskpace items=5

D/HomeLoaders( 99): ----> worskpace widgets=0

D/HomeLoaders( 99): ----> items cloned, ready to refresh UI

D/HomeLoaders( 99): ----> loading applications from workspace loader

D/HomeLoaders( 99): --> starting applications loader unlocked

D/HomeLoaders( 99): --> starting applications loader

D/HomeLoaders( 99): ----> running applications loader (2)

I/ActivityManager( 52): Start proc com.android.alarmclock for broadcast com.android.alarmclock/.AlarmInitReceiver: pid=175 uid=10017 gids={}

D/HomeLoaders( 99): ----> onDesktopItemsLoaded()

D/Launcher( 99): ------> binding 5 items

D/Launcher( 99): ------> binding 0 widgets

D/Launcher( 99): ------> start binding items

D/MediaPlayer( 52): Couldn't open file on client side, trying server side

D/ActivityManager( 52): checkComponentPermission() adjusting {pid,uid} to {30,1013}

D/ActivityManager( 52): checkComponentPermission() adjusting {pid,uid} to {30,1013}

D/ActivityManager( 52): checkComponentPermission() adjusting {pid,uid} to {30,1013}

I/jdwp ( 175): received file descriptor 10 from ADB

D/ActivityManager( 52): checkComponentPermission() adjusting {pid,uid} to {30,1013}

E/MediaPlayerService( 30): Couldn't open fd for content://settings/system/notification_sound

E/MediaPlayer( 52): Unable to to create media player

W/NotificationService( 52): error loading sound for content://settings/system/notification_sound

W/NotificationService( 52): java.io.IOException: setDataSource failed.: status=0x80000000

W/NotificationService( 52): at android.media.MediaPlayer.setDataSource(Native Method)

W/NotificationService( 52): at android.media.MediaPlayer.setDataSource(MediaPlayer.java:621)

W/NotificationService( 52): at android.media.AsyncPlayer$Thread.run(AsyncPlayer.java:76)

D/ddm-heap( 175): Got feature list request

D/MediaScannerService( 160): start scanning volume internal

I/ActivityThread( 175): Publishing provider com.android.alarmclock: com.android.alarmclock.AlarmProvider

I/ActivityManager( 52): Start proc im.maillard.android.onbootservice for broadcast im.maillard.android.onbootservice/.OnBootReceiver: pid=186 uid=10023 gids={}

I/jdwp ( 186): received file descriptor 10 from ADB

D/ddm-heap( 186): Got feature list request

I/ActivityManager( 52): Stopping service: com.android.providers.downloads/.DownloadService

D/TestApp ( 186): Got the Boot Event>>>

D/TestApp ( 186): Starting MySimpleService>>>

D/TestApp ( 186): >>>onCreate()

D/TestApp ( 186): >>>onStart()

I/ActivityManager( 52): Start proc com.svox.pico for broadcast com.svox.pico/.VoiceDataInstallerReceiver: pid=194 uid=10003 gids={}

D/HomeLoaders( 99): ----> cleared application list

I/jdwp ( 194): received file descriptor 20 from ADB

I/dalvikvm( 194): Debugger thread not active, ignoring DDM send (t=0x54455354 l=

D/ddm-heap( 194): Got feature list request

D/dalvikvm( 52): GC freed 7382 objects / 597080 bytes in 203ms

D/MediaScanner( 160): opendir /system/media/ failed, errno: 2

D/MediaScanner( 160): prescan time: 1222ms

D/MediaScanner( 160): scan time: 745ms

D/MediaScanner( 160): postscan time: 0ms

D/MediaScanner( 160): total time: 1967ms

I/ActivityManager( 52): Stopping service: com.android.mms/.transaction.TransactionService

D/MediaScannerService( 160): done scanning volume internal

I/ActivityManager( 52): Stopping service: com.android.providers.media/.MediaScannerService

I/ActivityManager( 52): Stopping service: com.android.mms/.transaction.SmsReceiverService

I/ActivityManager( 52): Stopping service: com.android.providers.downloads/.DownloadService

D/dalvikvm( 99): GC freed 6714 objects / 372896 bytes in 125ms

Voilà, j'espère que ça vous servira :D

Bon courage pour vos développements.

Lien vers le commentaire
Partager sur d’autres sites

  • 2 weeks later...
  • 2 months later...

Rejoignez la conversation

Vous pouvez poster maintenant et vous enregistrez plus tard. Si vous avez un compte, connectez-vous maintenant pour poster.

Invité
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Répondre à ce sujet…

×   Collé en tant que texte enrichi.   Coller en tant que texte brut à la place

  Seulement 75 émoticônes maximum sont autorisées.

×   Votre lien a été automatiquement intégré.   Afficher plutôt comme un lien

×   Votre contenu précédent a été rétabli.   Vider l’éditeur

×   Vous ne pouvez pas directement coller des images. Envoyez-les depuis votre ordinateur ou insérez-les depuis une URL.

×
×
  • Créer...