web-dev-qa-db-fra.com

Le service Android doit toujours être exécuté (jamais de pause ou d'arrêt)

J'ai créé un service et je souhaite l'exécuter systématiquement jusqu'au redémarrage ou la fermeture forcée de mon téléphone. Le service devrait fonctionner en arrière-plan. 

Exemple de code du service créé et des services de démarrage:

Démarrer le service:

Intent service = new Intent(getApplicationContext(), MyService.class);
getApplicationContext().startService(service);

Le service:

public class MyService extends Service {

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // TODO do something useful
        HFLAG = true;
        //smsHandler.sendEmptyMessageDelayed(DISPLAY_DATA, 1000);
        return Service.START_NOT_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO for communication return IBinder implementation
        return null;
    }
}

Déclaration manifeste:

<service
    Android:name=".MyService"
    Android:icon="@drawable/ic_launcher"
    Android:label="@string/app_name" >
</service>

Est-il possible d’exécuter ce service toujours comme lorsque l’application se met en pause et tout le reste… .. Après quelque temps, mon application passe en pause et les services passent également en pause ou s’arrêtent… .. .

"Est-il possible d'exécuter ce service toujours comme lorsque l'application était en pause et autre chose?"

Oui.

  1. Dans la méthode de service onStartCommand, retournez START_STICKY.

    public int onStartCommand(Intent intent, int flags, int startId) {
            return START_STICKY;
    }
    
  2. Démarrez le service en arrière-plan à l'aide de startService (MyService) afin qu'il reste toujours actif, quel que soit le nombre de clients liés. 

    Intent intent = new Intent(this, PowerMeterService.class);
    startService(intent);
    
  3. Créez le classeur.

    public class MyBinder extends Binder {
            public MyService getService() {
                    return MyService.this;
            }
    }
    
  4. Définir une connexion de service.

    private ServiceConnection m_serviceConnection = new ServiceConnection() {
            public void onServiceConnected(ComponentName className, IBinder service) {
                    m_service = ((MyService.MyBinder)service).getService();
            }
    
            public void onServiceDisconnected(ComponentName className) {
                    m_service = null;
            }
    };
    
  5. Lier au service en utilisant bindService.

            Intent intent = new Intent(this, MyService.class);
            bindService(intent, m_serviceConnection, BIND_AUTO_CREATE);
    
  6. Pour votre service, vous voudrez peut-être une notification pour lancer l'activité appropriée une fois celle-ci fermée.

    private void addNotification() {
            // create the notification
            Notification.Builder m_notificationBuilder = new Notification.Builder(this)
                    .setContentTitle(getText(R.string.service_name))
                    .setContentText(getResources().getText(R.string.service_status_monitor))
                    .setSmallIcon(R.drawable.notification_small_icon);
    
            // create the pending intent and add to the notification
            Intent intent = new Intent(this, MyService.class);
            PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
            m_notificationBuilder.setContentIntent(pendingIntent);
    
            // send the notification
            m_notificationManager.notify(NOTIFICATION_ID, m_notificationBuilder.build());
    }
    
  7. Vous devez modifier le manifeste pour lancer l'activité en mode top simple.

              Android:launchMode="singleTop"
    
  8. Notez que si le système a besoin de ressources et que votre service n'est pas très actif, il peut être tué. Si cela est inacceptable, amenez le service au premier plan à l'aide de startForeground.

            startForeground(NOTIFICATION_ID, m_notificationBuilder.build());
    
85
Stephen Donecker

Afin de démarrer un service dans son propre processus, vous devez spécifier ce qui suit dans la déclaration xml.

<service
  Android:name="WordService"
  Android:process=":my_process" 
  Android:icon="@drawable/icon"
  Android:label="@string/service_name"
  >
</service> 

Ici vous pouvez trouver un bon tutoriel qui m'a été vraiment utile

http://www.vogella.com/articles/AndroidServices/article.html

J'espère que cela t'aides

8
Juan

Une solution simple consiste à redémarrer le service lorsque le système l’arrête.

J'ai trouvé cette implémentation très simple de cette méthode:

Comment rendre le service Android imparable

3
Alecs

Vous pouvez implémenter startForeground pour le service et même s'il meurt, vous pouvez le redémarrer à l'aide de START_STICKY sur startCommand(). Pas sûr que ce soit la bonne implémentation.

2
Srikanth Roopa

Si vous avez déjà un service et voulez qu'il fonctionne tout le temps, vous devez ajouter 2 choses:

  1. dans le service lui-même:

    public int onStartCommand(Intent intent, int flags, int startId) {
        return START_STICKY;
    }
    
  2. Dans le manifeste:

    Android:launchMode="singleTop"
    

Pas besoin d'ajouter une liaison sauf si vous en avez besoin dans le service.

1
Gilad Levinson

J'avais surmonté ce problème et mon exemple de code est le suivant.

Ajoutez la ligne ci-dessous dans votre activité principale, ici BackGroundClass est la classe de service.Vous pouvez créer cette classe dans Nouveau -> JavaClass (Dans cette classe, ajoutez le processus (tâches) dans lequel vous devez être exécuté en arrière-plan) . Pour plus de commodité, notez-les d'abord avec une sonnerie de notification en tant que processus d'arrière-plan.

 startService(new Intent(this, BackGroundClass .class));

Dans la BackGroundClass, incluez simplement mes codages et vous pourrez voir le résultat.

import Android.app.Service;
import Android.content.Intent;
import Android.media.MediaPlayer;
import Android.os.IBinder;
import Android.provider.Settings;
import Android.support.annotation.Nullable;
import Android.widget.Toast;

public class BackgroundService  extends Service {
    private MediaPlayer player;
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
@Override
    public int onStartCommand(Intent intent, int flags, int startId) {
     player = MediaPlayer.create(this,Settings.System.DEFAULT_RINGTONE_URI);
        player.setLooping(true);
         player.start();
        return START_STICKY;
    }
 @Override
    public void onDestroy() {
        super.onDestroy();
         player.stop();
    }
}

Et dans AndroidManifest.xml, essayez d'ajouter ceci.

<service Android:name=".BackgroundService"/>

Exécutez le programme, ouvrez simplement l'application, vous pouvez trouver l'alerte de notification en arrière-plan. Même si vous pouvez quitter l'application, vous pouvez quand même entendre l'alerte de sonnerie à moins que et jusqu'à ce que vous désactiviez l'application ou désinstallez l'application. Cela indique que l'alerte de notification est en arrière-plan. Comme cela, vous pouvez ajouter un processus pour le fond. 

Attention: S'il vous plaît, ne vérifiez pas avec TOAST car il ne fonctionnera qu'une seule fois, même s'il était en arrière-plan.

J'espère que ça aidera ... !!

1
Hari_Haran_N_S.

J'ai trouvé un moyen simple et clair de garder la Service toujours active. 

Ce gars a expliqué si clairement et a utilisé un bon algorithme. Son approche consiste à envoyer une diffusion lorsque le service est sur le point de disparaître, puis à l'utiliser pour redémarrer le service. 

Vous devriez vérifier: http://fabcirablog.weebly.com/blog/creating-a-never-ending-background-service-in-Android

0
Hammad Nasir

Ajoutez ceci dans le manifeste.

      <service
        Android:name=".YourServiceName"
        Android:enabled="true"
        Android:exported="false" />

Ajouter une classe de service.

public class YourServiceName extends Service {


    @Override
    public void onCreate() {
        super.onCreate();

      // Timer task makes your service will repeat after every 20 Sec.
       TimerTask doAsynchronousTask = new TimerTask() {
            @Override
            public void run() {
                handler.post(new Runnable() {
                    public void run() {
                       // Add your code here.

                     }

               });
            }
        };
  //Starts after 20 sec and will repeat on every 20 sec of time interval.
        timer.schedule(doAsynchronousTask, 20000,20000);  // 20 sec timer 
                              (enter your own time)
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // TODO do something useful

      return START_STICKY;
    }

}
0
Avinash Shinde

Vous n'avez pas besoin de récepteur de diffusion. Si vous voulez vous faire mal, copiez l'une des API (serviceconnection) de l'exemple ci-dessus par Stephen Donecker et collez-la dans Google, vous obtiendrez ceci, https://www.concretepage.com/Android/android-local-bound- service-example-with-binder-and-serviceconnection

0
Chirag Dave