I have requirement to track any new image file of type .jpg created on device.
I have done this using ContentObserver
on MediaStore
using below class MediaStoreObserver
and,
registering the same in one of my service.
I have noticed that onChange()
method gets called many times for a single file creation.
I understand that media file created gets updated in many tables of MediaStore
hence onChange()
gets called many times.
My question: How to register to MediaStore
for ONLY image file create/edit operation ?
-Thanks in advance, Manju
private class MediaStoreObserver extends ContentObserver {
public MediaStoreObserver() {
super(null);
}
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
//check image file changes in MediaStore
readFromMediaStore(_context,MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
}
}
//register for external media changes for image files
if(mediaStoreObserver!=null){
_context.getContentResolver().registerContentObserver(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
false,mediaStoreObserver);
Short answer: You can't, it's the provider which sends notifyChange
(received with observers onChange
) whenever something is: updated/inserted/deleted
Longer answer: This is what would've done to achieve what you want (How to register to MediaStore for ONLY image file create/edit operation ?):
Read image table from MediaStore upon start and store the _data column (file paths), in a sorted collection
, a sorted collection
with paths (strings). And whenever you receive an onChange
call make a new collection of the above sort, then loop over the new collection and search the original collection you created , with binary search (since the collection is sorted and we want to keep the time complexity low). This would lead to a quite effective implementation with running time of O(n*logn).
Or in pseudo code:
1. Read current image columns from media store (the `_data column as projection)
2. Store result in a collection, with string type
3. Sort collection
4. Upon `onChange` is received, make a new collection as step 1-3
5. Loop over collection created in 4 and search each string you take out with
binary search in the sorted collection you got from step 3, if item is not found
then the item is new
6. Make the collection in 4 the current cached version of mediastore
7. Time complexity is O(n*log n) for the above algorithm
Edit for the updated file part i would read the date modified field from MediaStore whenever my search in step 5 hits, that would mean that you should actually store both file (uri) and date modified in a data class, but as search lookup use file path. Whenever file is found you should check if the modified dates match, if not then it's an updated file.