androidcrashfileobserver

FIleObserver NoSuchMethodError in Android 10


I have a FileObserver(File dir) that works perfectly in Android11, but crashes badly in Android10 with the following LogCat even when I try to access the own APP private folder (external sdcard):

E/AndroidRuntime(24651): java.lang.NoSuchMethodError: No direct method <init>(Ljava/io/File;)V
      in class Landroid/os/FileObserver; or its super classes (declaration of
      'android.os.FileObserver' appears in /system/framework/framework.jar!classes2.dex)
E/AndroidRuntime(24651):     at com.floritfoto.apps.xvf.FileChooser$1.<init>(FileChooser.java:570)
E/AndroidRuntime(24651):     at com.floritfoto.apps.xvf.FileChooser.watchdir(FileChooser.java:570)
E/AndroidRuntime(24651):     at com.floritfoto.apps.xvf.FileChooser.access$500(FileChooser.java:53)

My code is pretty simple:

private void watchdir(final File dir) {
    if (observer != null) {
        observer.stopWatching();
        observer = null;
    }
    observer = new FileObserver(dir) {   // <===== CRASHES HERE
        @Override
        public void onEvent(int event, String path) {
            event &= FileObserver.ALL_EVENTS;
            ....
        }
    };
    observer.startWatching();
}

Changing observer = new FileObserver(dir) with observer = new FileObserver(dir.getAbsolutePath()) works fine, but FileObserver(String path) is deprecated.

My app has compileSdkVersion 31, targetSdkVersion 31, and minSdkVersion 14.

At least to some extent this error has been reported before, but no solution has been provided yet.

EDIT: The crash is in Android 9, not 10.


Solution

  • FileObserver(File) is new to API Level 29. Your minSdkVersion is 14. Your code will crash with this error on API Level 28 and lower. You should be getting Lint warnings and the like warning you that FileObserver(File) is newer than your minSdkVersion.

    Your options are:

    1. Use FileObserver(String) on all API levels, despite the deprecation warning.

    2. Use FileObserver(String) on API Levels 14-28 and use FileObserver(File) on API Level 29+, using Build.VERSION.SDK_INT to determine the API level of the device your app is running on.

    3. Set your minSdkVersion to 29.

    4. Only use FileObserver on API Level 29+, and skip whatever features depend on it on older devices.