web-dev-qa-db-fra.com

Vérifier si WorkRequest a déjà été exploité par WorkManager Android

J'utilise PeriodicWorkRequest pour effectuer une tâche pour moi toutes les 15 minutes .. Je souhaite vérifier si cette demande de travail périodique a déjà été planifiée. Sinon, programmez-le.

     if (!PreviouslyScheduled) {
        PeriodicWorkRequest dataupdate = new PeriodicWorkRequest.Builder( DataUpdateWorker.class , 15 , TimeUnit.MINUTES).build();
        WorkManager.getInstance().enqueue(dataupdate);
      }

Auparavant, lorsque je travaillais sur JobScheduler, j’utilisais 

public static boolean isJobServiceScheduled(Context context, int JOB_ID ) {
    JobScheduler scheduler = (JobScheduler) context.getSystemService( Context.JOB_SCHEDULER_SERVICE ) ;

    boolean hasBeenScheduled = false ;

    for ( JobInfo jobInfo : scheduler.getAllPendingJobs() ) {
        if ( jobInfo.getId() == JOB_ID ) {
            hasBeenScheduled = true ;
            break ;
        }
    }

    return hasBeenScheduled ;
}

Besoin d'aide pour construire un module similaire pour une demande de travail afin de vous aider à trouver des demandes de travail planifiées/actives.

6
Bhavita Lalwani

Définissez une balise sur votre tâche PeriodicWorkRequest:

    PeriodicWorkRequest work =
            new PeriodicWorkRequest.Builder(DataUpdateWorker.class, 15, TimeUnit.MINUTES)
                    .addTag(TAG)
                    .build();

Ensuite, recherchez les tâches avec le TAG avant que le travail de mise en file d'attente:

    WorkManager wm = WorkManager.getInstance();
    ListenableFuture<List<WorkStatus>> future = wm.getStatusesByTag(TAG);
    List<WorkStatus> list = future.get();
    // start only if no such tasks present
    if((list == null) || (list.size() == 0)){
        // shedule the task
        wm.enqueue(work);
    } else {
        // this periodic task has been previously scheduled
    }

Mais si vous n’avez vraiment pas besoin de savoir qu’il était programmé ou non, vous pouvez utiliser:

    static final String TASK_ID = "data_update"; // some unique string id for the task
    PeriodicWorkRequest work =
            new PeriodicWorkRequest.Builder(DataUpdateWorker.class,
                    15, TimeUnit.MINUTES)
                    .build();

    WorkManager.getInstance().enqueueUniquePeriodicWork(TASK_ID,
                ExistingPeriodicWorkPolicy.KEEP, work);

ExistingPeriodicWorkPolicy.KEEP signifie que la tâche sera planifiée une seule fois, puis fonctionnera périodiquement même après le redémarrage du périphérique. Si vous devez reprogrammer la tâche (par exemple, si vous devez en modifier certains paramètres), vous devrez utiliser ExistingPeriodicWorkPolicy.REPLACE ici.

6
Alex

Vous devez ajouter une balise unique à chaque WorkRequest. Vérifier Travail tagué .

Vous pouvez regrouper vos tâches de manière logique en attribuant une chaîne de balises à tout objet WorkRequest. Pour cela, vous devez appeler WorkRequest.Builder.addTag()

Vérifiez ci-dessous l'exemple de doc Android:

OneTimeWorkRequest cacheCleanupTask =
    new OneTimeWorkRequest.Builder(MyCacheCleanupWorker.class)
.setConstraints(myConstraints)
.addTag("cleanup")
.build();

Même chose que vous pouvez utiliser pour PeriodicWorkRequest

Ensuite, vous obtiendrez une liste de tous les WorkStatus pour toutes les tâches avec cette balise en utilisant WorkManager.getStatusesByTag() .

Ce qui vous donne une LiveData liste de WorkStatus pour un travail marqué avec une balise.

Ensuite, vous pouvez vérifier l’état en utilisant WorkStatus comme ci-dessous:

       WorkStatus workStatus = listOfWorkStatuses.get(0);

        boolean finished = workStatus.getState().isFinished();
        if (!finished) {
            // Work InProgress
        } else {
            // Work Finished
        }

Vous pouvez consulter ci-dessous l'exemple de Google pour plus de détails. Ici, ils ont ajouté comment ajouter une balise à WorkRequest et obtenir le statut de travail par balise:

https://github.com/googlecodelabs/Android-workmanager

Edits Vérifiez le code ci-dessous et commentez comment nous pouvons obtenir WorkStatus par balise. Et planifiez notre travail si les résultats de WorkStatus sont vides.

 // Check work status by TAG
    WorkManager.getInstance().getStatusesByTag("[TAG_STRING]").observe(this, listOfWorkStatuses -> {

        // Note that we will get single WorkStatus if any tag (here [TAG_STRING]) related Work exists

        // If there are no matching work statuses
        // then we make sure that periodic work request has been previously not scheduled
        if (listOfWorkStatuses == null || listOfWorkStatuses.isEmpty()) {
           // we can schedule our WorkRequest here
            PeriodicWorkRequest dataupdate = new PeriodicWorkRequest.Builder( DataUpdateWorker.class , 15 , TimeUnit.MINUTES)
                    .addTag("[TAG_STRING]")
                    .build();
            WorkManager.getInstance().enqueue(dataupdate);
            return;
        }

        WorkStatus workStatus = listOfWorkStatuses.get(0);
        boolean finished = workStatus.getState().isFinished();
        if (!finished) {
            // Work InProgress
        } else {
            // Work Finished
        }
    });

Je n'ai pas testé le code. S'il vous plaît fournir vos commentaires pour la même chose.

J'espère que cela vous aide.

1
pRaNaY

Je cherchais aussi le même état. Je ne pouvais pas en trouver un. Alors, pour résoudre ce problème, j’ai trouvé un mécanisme. Tout d’abord, annulez tous les travaux planifiés et reprogrammez le travail. Pour que nous puissions nous assurer qu’une seule instance de votre travail sera maintenue. Assurez-vous également que vous devez conserver la logique de code de travail de cette manière. 

Pour annuler un travail. Pour more

UUID compressionWorkId = compressionWork.getId();
WorkManager.getInstance().cancelWorkById(compressionWorkId);
0
AtHul Antony