Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect new photos with workmanager

Now I'm using Firebase for uploading photos and this working great and was able to rebuild this work to use workmanager, but I don't know how to pass content URI trigger to my workmanager builder.

val dispatcher = FirebaseJobDispatcher(GooglePlayDriver(applicationContext))
    val job = dispatcher.newJobBuilder()
            .setService(UploadJobService::class.java)
            .setTag(TAG)
            .setRecurring(true)
            .setTrigger(Trigger.executionWindow(0, 60))
            .setTrigger(Trigger.contentUriTrigger( Arrays.asList(
                    ObservedUri(Uri.parse(Environment.getExternalStorageDirectory().absolutePath), ObservedUri.Flags.FLAG_NOTIFY_FOR_DESCENDANTS))
            ))
            .setLifetime(Lifetime.FOREVER)
            .setReplaceCurrent(false)
            .setConstraints(
                    Constraint.ON_UNMETERED_NETWORK
            )
            .build()
    dispatcher.mustSchedule(job)

Here is code what I use for workmanager and it works most of the time, but when I take the photo and delete this is not working, due 15min interval, How I can register new unique worker what will start the job when the new photo is detected?

EDIT:Here is code what im using and its working, but not sure if i implement correctly...

This is how to schedule worker:

public static void Checkfornewphotos(String ONE_MY_WORK) {
    OneTimeWorkRequest.Builder photoCheckBuilder =
            new OneTimeWorkRequest.Builder(MyWorker.class);
    photoCheckBuilder.setConstraints(new Constraints.Builder()
            .addContentUriTrigger(MediaStore.Images.Media.INTERNAL_CONTENT_URI, true)
            .addContentUriTrigger(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, true)
            .build());
    OneTimeWorkRequest Photocheck = photoCheckBuilder.build();
    WorkManager instance = WorkManager.getInstance();
    instance.enqueueUniqueWork(ONE_MY_WORK, ExistingWorkPolicy.REPLACE, Photocheck);
}

Here is my worker:

public class MyWorker extends Worker {

public MyWorker(
        @NonNull Context context,
        @NonNull WorkerParameters params) {
    super(context, params);
}

@Override
public Worker.Result doWork() {
    // Do your actual work
    try {
        Log.i(TAG, "mywork")
        Result.RETRY

    } catch (exception: Exception) {
        Log.i(TAG, "mywork")
        Result.SUCCESS
    }
    // Then start listening for more changes
    Checkfornewphotos(getTags().iterator().next());
}

}

like image 501
Marko1221 Avatar asked Dec 02 '18 15:12

Marko1221


People also ask

How do I know if my WorkManager is running?

You can check this by running getStatus() method on the WorkInfo instance. Calling the state immediately after enqueuing the WorkRequest will give the state as ENQUEUED and hence don't get any output data.

How does a WorkManager work?

WorkManager is intended for work that is required to run reliably even if the user navigates off a screen, the app exits, or the device restarts. For example: Sending logs or analytics to backend services. Periodically syncing application data with a server.

Does WorkManager work in doze mode?

Another nice feature of WorkManager is that it respects power-management features so that if a job is scheduled to run at a defined time and the device is in Doze at that time, WorkManager will try to run the task during a maintenance window if the constraints are met or after Doze is lifted.

How do you debug a WorkManager?

Use adb shell dumpsys jobscheduler On API level 23 or higher, you can run the command adb shell dumpsys jobscheduler to look at the list of jobs which have been attributed to your package. When using WorkManager, the component responsible for managing Worker execution is SystemJobService (on API level 23 or higher).


1 Answers

WorkManager does not support periodic (i.e., repeating) content URI triggers, but it does support enqueueing a OneTimeWorkRequest with addContentUriTrigger() as one of the constraints.

public static void scheduleWork(String tag) {
  OneTimeWorkRequest.Builder photoCheckBuilder =
      new OneTimeWorkRequest.Builder(MyWorker.class);
  photoCheckBuilder.setConstraints(new Constraints.Builder()
      .addContentUriTrigger(MediaStore.Images.Media.INTERNAL_CONTENT_URI, true)
      .addContentUriTrigger(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, true)
      .build());
  OneTimeWorkRequest photoCheckWork = photoCheckBuilder.build();
  WorkManager instance = WorkManager.getInstance();
  instance.enqueueUniqueWork(tag, ExistingPeriodicWorkPolicy.REPLACE, photoCheckWork);
}

Because it is a OneTimeWorkRequest, it will only fire on the first time the URI is changed - you'd need to re-enqueue the work when your Worker is finish to catch the next change:

public class MyWorker extends Worker {

  public MyWorker(
    @NonNull Context context,
    @NonNull WorkerParameters params) {
    super(context, params);
  }

  @Override
  public Worker.Result doWork() {
    // Do your actual work

    // Then start listening for more changes
    scheduleWork(getTags().iterator().next());
  }
}
like image 54
ianhanniballake Avatar answered Sep 28 '22 08:09

ianhanniballake