web-dev-qa-db-fra.com

Android - Service d'arrière-plan périodique - Conseils

Je travaille sur une application qui transmettra des informations sur son emplacement à un serveur distant. J'ai l'intention de le faire en faisant un simple post HTTP sur le serveur Web et tout est simple et précis.

Mais selon les spécifications, l'application doit s'exécuter de temps en temps, disons une fois toutes les 30 minutes. Soyez indépendant de l'interface, ce qui signifie qu'il doit être exécuté même si l'application est fermée.

J'ai regardé autour de moi et découvert qu'Android Services est ce qu'il faut utiliser. Que pourrais-je utiliser pour mettre en place un tel système? Le service (ou un autre mécanisme) redémarrera-t-il au redémarrage du téléphone? 

Merci d'avance.

27
Ziyan Junaideen

Créez une Service pour envoyer vos informations à votre serveur. Vraisemblablement, vous avez cela sous contrôle. 

Votre Service doit être lancé par une alarme déclenchée par le AlarmManager , où vous pouvez spécifier un intervalle. Sauf si vous devez signaler vos données exactement toutes les 30 minutes, vous souhaiterez probablement une alarme inexacte vous permettant de préserver une partie de la vie de la batterie.

Enfin, vous pouvez enregistrer votre application pour obtenir la diffusion de démarrage en configurant une BroadcastReceiver like de la manière suivante:

public class BootReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {  
        if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
            // Register your reporting alarms here.            
        }
    }
}

Vous devrez ajouter l’autorisation suivante à votre AndroidManifest.xml pour que cela fonctionne. N'oubliez pas d'enregistrer vos alarmes lorsque vous exécutez l'application normalement, sinon elles ne seront enregistrées qu'au démarrage de l'appareil.

<uses-permission Android:name="Android.permission.RECEIVE_BOOT_COMPLETED"/>
30
Argyle

Voici une manière semi-différente de maintenir le service pour toujours. Il y a moyen de le tuer en code si vous le souhaitez

Service de fond:

package com.ex.ample;

import Android.app.Service;
import Android.content.*;
import Android.os.*;
import Android.widget.Toast;

public class BackgroundService extends Service {

    public Context context = this;
    public Handler handler = null;
    public static Runnable runnable = null;

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

    @Override
    public void onCreate() {
        Toast.makeText(this, "Service created!", Toast.LENGTH_LONG).show();

        handler = new Handler();
        runnable = new Runnable() {
            public void run() {
                Toast.makeText(context, "Service is still running", Toast.LENGTH_LONG).show();
                handler.postDelayed(runnable, 10000);
            }
        };

        handler.postDelayed(runnable, 15000);
    }

    @Override
    public void onDestroy() {
        /* IF YOU WANT THIS SERVICE KILLED WITH THE APP THEN UNCOMMENT THE FOLLOWING LINE */
        //handler.removeCallbacks(runnable);
        Toast.makeText(this, "Service stopped", Toast.LENGTH_LONG).show();
    }

    @Override
    public void onStart(Intent intent, int startid) {
        Toast.makeText(this, "Service started by user.", Toast.LENGTH_LONG).show();
    }
}

Voici comment vous commencez à partir de votre activité principale ou où vous le souhaitez:

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

onDestroy() sera appelé lorsque l'application sera fermée ou supprimée, mais le processus exécutable le lancera de nouveau.

J'espère que ça aide quelqu'un.

Certaines personnes font cela à cause d'applications d'entreprise dans lesquelles, dans certains cas, les utilisateurs/employés ne doivent pas être en mesure d'arrêter certaines choses :)

http://i.imgur.com/1vCnYJW.png


MODIFIER

Depuis Android O (8.0), vous devez utiliser JobManager pour les tâches planifiées. Il existe une bibliothèque appelée Android-Job de Evernote qui simplifiera le travail périodique en arrière-plan sur toutes les versions d'Android. J'ai également fait un Xamarin Binding de cette bibliothèque.

Ensuite, tout ce que vous devez faire est le suivant:

Dans votre classe d'application:

public class MyApp extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        JobManager.create(this).addJobCreator(new MyJobCreator());
    }
}

Créez les deux classes suivantes YourJobCreator et YourSyncJob (Où tout le travail sera effectué. Android alloue du temps pour l'exécution de tous les travaux en arrière-plan. Pour les versions Android <8.0, il sera toujours exécuté avec un gestionnaire d'alarmes et un service en arrière-plan habituels) 

public class MyJobCreator implements JobCreator {

    @Override
    @Nullable
    public Job create(@NonNull String tag) {
        switch (tag) {
            case MySyncJob.TAG:
                return new MySyncJob();
            default:
                return null;
        }
    }
}

public class MySyncJob extends Job {

    public static final String TAG = "my_job_tag";

    @Override
    @NonNull
    protected Result onRunJob(Params params) {
        //
        // run your job here
        //
        //
        return Result.SUCCESS;
    }

    public static void scheduleJob() {
        new JobRequest.Builder(MySyncJob.TAG)
                .setExecutionWindow(30_000L, 40_000L) //Every 30 seconds for 40 seconds
                .build()
                .schedule();
    }
}
15
Pierre

Vous devez planifier votre service avec Alarm Manager, commencez par créer l'intention de service en attente:

Intent ii = new Intent(getApplicationContext(), MyService.class);
PendingIntent pii = PendingIntent.getService(getApplicationContext(), 2222, ii,
PendingIntent.FLAG_CANCEL_CURRENT);

Puis planifiez-le à l'aide du gestionnaire d'alarmes:

//getting current time and add 5 seconds to it
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, 5);
//registering our pending intent with alarmmanager
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP,cal.getTimeInMillis(), pi);

cela lancera votre service après 5 secondes de l'heure actuelle. Vous pouvez faire en sorte que votre alarme se répète.

8
SohailAziz

Vous pouvez utiliser Gestionnaire d’alarmes pour démarrer le service à une heure précise, puis répéter l’alarme dans l’intervalle spécifié. Lorsque l'alarme se déclenche, vous pouvez démarrer le service, vous connecter au serveur et créer ce que vous voulez.

0
vandzi