File observer not working in android 10 and higher

Viewed 1389

My requirement was to observe one of the user's file even if the app is not running in the background, so I created a foreground service (nice and easy) and placed the file observer code in it and of course, I handled the following warning

Warning: If a FileObserver is garbage collected, it will stop sending events. To ensure you keep receiving events, you must keep a reference to the FileObserver instance from some other live object.

by placing the FileObserver variable in App.class

And it is working fine up to android 9 perfectly as expected but when I tried my app on android 10 I could see the foreground service running but whenever observed file got modified, no event gets fired

I read some new restrictions on java.io.file from android 10 but I'm not able to get my desired result.

Is there any way or alternative to get around this bug?

code

private void startObserving() {
        fileObserver = new FileObserver(utilityClass.GET_X_FOLDER().getPath(), FileObserver.ALL_EVENTS) {
            @Override
            public void onEvent(int event, @Nullable String path) {
                if (event == FileObserver.CREATE) {
                    start(path);
                }
            }
        };
        fileObserver.startWatching();
    }

manifest file

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.ss_app">

    <application
        android:name=".App"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:logo="@mipmap/ic_launcher"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity android:name=".Help" />
        <activity android:name=".developer"/>
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <receiver android:name=".AlaramReceiver" />
        <receiver android:name=".BootBroadCastReceiver">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>

        <service android:name=".FileDeleteService" />
        <service android:name=".ForeGroundService" />
        <service android:name=".xService" />
        <meta-data
            android:name="com.google.android.gms.ads.APPLICATION_ID"
            android:value="xxxx"/>
    </application>

    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
    <uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

</manifest>
2 Answers

Solution: just add the following line under your application tag in manifest

 android:requestLegacyExternalStorage="true"

Also be sure to go in to Settings->Apps->YourApp and grant Storage permission if you aren't requesting it dynamically in your app.

Related