Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to replace FileObserver in Android 10?

android.os.FileObserver requires a java.io.File to function. But with Android 10 Google restricted access to everything but your app's private directory due to the famous "Storage Access Framework". Thus, accessing anything via java.io.File breaks and renders FileObserver useless unless you intend to use it in your app's private directory. However, I want to be notified when something is changed in a certain directory on external storage. I would also like to avoid periodically checking for changes.

I tried using ContentResolver.registerContentObserver(uri,notifyForDescendants,observer) and ran into some problems with that method:

  • Every Uri I have plugged in so far was accepted
  • It neither fails nor notifies if the Uri doesn't work
  • I cannot find any documentation telling me which Uris actually work

The only thing I got working to some extent is the following approach:

// works, but returns all changes to the external storage
contentResolver.registerContentObserver(MediaStore.Files.getContentUri("external"), true, contentObserver)

Unfortunately this includes all of the external storage and only returns Media Uris when changes happen - for example content://media/external/file/67226.

Is there a way to find out whether or not that Uri points to my directory?

Or is there a way to make registerContentObserver() work with a Uri in such a way that I get a notification whenever something in the folder has changed?

I also had no success trying various Uris related to DocumentsFile and external storage Uris.

like image 478
squaresandcircles Avatar asked Nov 11 '19 01:11

squaresandcircles


1 Answers

I kept getting errors when even trying to use the base constructor such as the following -

No direct method <init>(Ljava/util/List;I)V in class Landroid/os/FileObserver; or its super classes (declaration of 'android.os.FileObserver' appears in /system/framework/framework.jar!classes2.dex)

From a comment on Detect file change using FileObserver on Android:

I saw that message (or something like that) when i was trying to use constructor FileObserver(File). Use of deprecated FileObserver(String) solved my problem.... Original FileObserver has bugs.

Full disclosure, I was using the Xamarin.Android API; however, the gist and the commenter I quoted were both working with Java. At any rate, indeed - tried again using the counterpart String constructor and I was finally able to make and use the observer. Grinds my gears to use a deprecated API, but apparently they're hanging onto it at least up to and including Android 12.0.0_r3... still, would much prefer the supported constructors actually work. Maybe there's some warrant here for filing an issue.

like image 136
Bondolin Avatar answered Oct 05 '22 02:10

Bondolin