'FileObserver not working on Android SDK 30

I am working on an android application where i have used FileObserver to get data changes on a specific folder. The folder is WhatsApp Images and whenever there is a new file added to that folder i perform my further work when onEvent of FileObserver is triggered. Everything works fine until i set targetSdkVersion=29 but as i am migrating my project to targetSdkVersion=30 FileObserver stopped working.

Below is my code for FileObserver

import android.os.Environment
import android.os.FileObserver
import android.util.Log
import java.io.File

    class WhatsAppImageObserver11(var notify:(msg:String)->Unit) : FileObserver(
        File(
            Environment.getExternalStorageDirectory().toString(),
            Constants.whatsapp_images_path11).toString(), ALL_EVENTS
    ) {
        init {
            Log.d("WhatsAppImageObserver11", "start")
        }
    
        override fun onEvent(i: Int, str: String?) {
            val str2 = "WhatsAppImageObserver11"
            if (i == CREATE || i == MOVED_TO && str != ".probe") {
                val sb = StringBuilder()
                sb.append("create File path--> ")
                sb.append(str)
                Log.d(str2, sb.toString())
                try {
                    val whatsDeleted = File(
                        Environment.getExternalStorageDirectory().path,
                        Constants.whatsapp_reserved_media
                    )
                    if(!whatsDeleted.exists()) {
                        whatsDeleted.mkdirs()
                    }
                    val srcFile = File(
                        Environment.getExternalStorageDirectory(),
                        Constants.whatsapp_images_path11+str)
                    val destFile = File(Environment.getExternalStorageDirectory(), Constants.whatsapp_reserved_media+str)
                    if (srcFile.exists()){
                        srcFile.copyTo(target = destFile, overwrite = false, bufferSize = DEFAULT_BUFFER_SIZE)
                    }
                } catch (e: Exception) {
                    val sb2 = StringBuilder()
                    sb2.append("create error: ")
                    sb2.append(e.toString())
                    Log.d(str2, sb2.toString())
                }
            }
            if (i and 512 != 0 || i and 1024 != 0) {
                val sb3 = StringBuilder()
                sb3.append("dlete File path--> ")
                sb3.append(str)
                Log.d(str2, sb3.toString())
                try {
                    val whatsDeleted = File(
                        Environment.getExternalStorageDirectory().path,
                        Constants.new_whatsapp_deleted_media
                    )
                    if(!whatsDeleted.exists()) {
                        whatsDeleted.mkdirs()
                    }
                    val srcFile = File(Environment.getExternalStorageDirectory().path, Constants.whatsapp_reserved_media+str)
                    val destFile = File(Environment.getExternalStorageDirectory().path, Constants.new_whatsapp_deleted_media+str)
    
                    if (srcFile.exists()){
                        srcFile.copyTo(target = destFile, overwrite = false, bufferSize = DEFAULT_BUFFER_SIZE)
                        srcFile.delete()
                        notify(destFile.absolutePath)
                    }
                } catch (e2: Exception) {
                    val sb4 = StringBuilder()
                    sb4.append("del error: ")
                    sb4.append(e2.toString())
                    Log.d(str2, sb4.toString())
                }
    
            }
        }
    }

Here in this FileObserver i am copying media from WhatsApp Reserved Media to My own WhatsAppDeleted folder for media recovery feature.

What i have tried?

1- As i know Environment.getExternalStorageDirectory() is deprecated i tried replacing it with mContext.getExternalFilesDir(null).getAbsolutePath()

2- Also checked using android:preserveLegacyExternalStorage="true" in Manifest.

3- Tried added ignore attribute in

<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
        tools:ignore="ScopedStorage"/>

What is Required?

1- FileObserver on path "/Android/media/" + WHATSAPP_PKG_NAME + "/WhatsApp/Media/WhatsApp Images/" should trigger onEvent when i set targetSdkVersion-30

Can somebody please help me out with this? Any help will be appreciated.

Thank you



Solution 1:[1]

As written here:

Apps that run on Android 11 but target Android 10 (API level 29) can still request the requestLegacyExternalStorage attribute. This flag allows apps to temporarily opt out of the changes associated with scoped storage, such as granting access to different directories and different types of media files. After you update your app to target Android 11, the system ignores the requestLegacyExternalStorage flag.

Basically, you don't have permission to "listen" to external directories in the device, but only to your own internal/external directories.

You should use the MediaStore API in order to access media files which have been scanned by the OS (Including WhatsApp's files).

You can use components like JobService to register for the event of a new media been scanned.

Enjoy

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Shirane85