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());
}
}
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.
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.
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.
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).
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());
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With