Android Créer un service non lié


Exemple

La première chose à faire est d'ajouter le service à AndroidManifest.xml , à l'intérieur de la <application> :

<application ...>

    ...        

    <service
        android:name=".RecordingService"
        <!--"enabled" tag specifies Whether or not the service can be instantiated by the system — "true" -->
        <!--if it can be, and "false" if not. The default value is "true".-->
        android:enabled="true"
        <!--exported tag specifies Whether or not components of other applications can invoke the -->
        <!--service or interact with it — "true" if they can, and "false" if not. When the value-->
        <!--is "false", only components of the same application or applications with the same user -->
        <!--ID can start the service or bind to it.-->
        android:exported="false" />

</application>

Si vous avez l'intention de gérer votre classe de service dans un package séparé (par exemple: .AllServices.RecordingService), vous devrez spécifier l'emplacement de votre service. Donc, dans le cas ci-dessus, nous modifierons:

android:name=".RecordingService"

à

android:name=".AllServices.RecordingService"

ou le moyen le plus simple est de spécifier le nom complet du package.

Ensuite, nous créons la classe de service actuelle:

public class RecordingService extends Service {
    private int NOTIFICATION = 1; // Unique identifier for our notification

    public static boolean isRunning = false;
    public static RecordingService instance = null;


    private NotificationManager notificationManager = null;


    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate(){
        instance = this;
        isRunning = true;

        notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId){
        // The PendingIntent to launch our activity if the user selects this notification
        PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0);

        // Set the info for the views that show in the notification panel.
        Notification notification = new NotificationCompat.Builder(this)
                .setSmallIcon(R.mipmap.ic_launcher)        // the status icon
                .setTicker("Service running...")           // the status text
                .setWhen(System.currentTimeMillis())       // the time stamp
                .setContentTitle("My App")                 // the label of the entry
                .setContentText("Service running...")      // the content of the entry
                .setContentIntent(contentIntent)           // the intent to send when the entry is clicked
                .setOngoing(true)                          // make persistent (disable swipe-away)
                .build();

        // Start service in foreground mode
        startForeground(NOTIFICATION, notification);

        return START_STICKY;
    }


    @Override
    public void onDestroy(){
        isRunning = false;
        instance = null;

        notificationManager.cancel(NOTIFICATION); // Remove notification

        super.onDestroy();
    }


    public void doSomething(){
        Toast.makeText(getApplicationContext(), "Doing stuff from service...", Toast.LENGTH_SHORT).show();
    }

}

Tout ce que fait ce service est de montrer une notification quand il est en cours d'exécution, et il peut afficher des toasts lorsque sa méthode doSomething() est appelée.

Comme vous le remarquerez, il est implémenté en tant que singleton , en gardant une trace de sa propre instance, mais sans la méthode habituelle de fabrique de singleton, car les services sont naturellement conçus et créés par intents. L'instance est utile à l'extérieur pour obtenir un "handle" au service lorsqu'il est en cours d'exécution.

Enfin, nous devons démarrer et arrêter le service d’une activité:

public void startOrStopService(){
    if( RecordingService.isRunning ){
        // Stop service
        Intent intent = new Intent(this, RecordingService.class);
        stopService(intent);
    }
    else {
        // Start service
        Intent intent = new Intent(this, RecordingService.class);
        startService(intent);
    }
}

Dans cet exemple, le service est démarré et arrêté par la même méthode, en fonction de son état actuel.

Nous pouvons également invoquer la méthode doSomething() de notre activité:

public void makeServiceDoSomething(){
    if( RecordingService.isRunning )
        RecordingService.instance.doSomething();
}