2

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.

Luis A. Florit
  • 2,169
  • 1
  • 33
  • 58

1 Answers1

3

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.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Strange. I get no lint warnings (in any part of my code, actually). I guess you meant `FileObserver` instead of `FileProvider`? But you are right, the crash was in Android 9, not 10. Anyway, I am using your option 2. – Luis A. Florit Dec 25 '21 at 18:43
  • @LuisA.Florit: Oops, yes, I meant `FileObserver` -- I will fix up the answer! – CommonsWare Dec 25 '21 at 18:51
  • I wonder why I didn't get any lint warnings... This is the kind of things that Studio catches easily by default. Maybe I have something wrong configured in the inspections? – Luis A. Florit Dec 25 '21 at 18:56
  • @LuisA.Florit: "This is the kind of things that Studio catches easily by default" -- I was rather surprised that you got caught by this. "Maybe I have something wrong configured in the inspections?" -- possibly. Or, perhaps you already have an annotation for this scenario on the class or method, from something else, that had the side effect of suppressing the warning for this new API usage. – CommonsWare Dec 25 '21 at 19:18
  • Very strange. NewApi inspection is enabled, and there is no @SuppressLint in that class. This error was already reported before. Maybe there is a bug in the Lint inspection that prevents catching this...? – Luis A. Florit Dec 25 '21 at 20:05