How to detect new photos with workmanager
Asked Answered
B

1

6

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());
}

}

Ballew answered 2/12, 2018 at 15:55 Comment(0)
S
9

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());
  }
}
Schick answered 2/12, 2018 at 16:23 Comment(3)
This API requires Android N - any options to support it below that API level?Body
@Body - prior to Android N, the only way to listen for content URI changes is to have your app constantly running, so no.Schick
does the broadcast for developer.android.com/reference/android/hardware/… do the trick below N?Body

© 2022 - 2024 — McMap. All rights reserved.