0

I have a stupid bug in my app.

I can copy contents of a folder from a folder like Downloads to root of my app in android, data,...

But

I can not copy contents of a folder from root of my app in android, data,... to a folder like Downloads

My code(that does work in android 11):

var this_dir = File("/storage/emulated/0/Download/Sandoghcheh")
var target_dir = File(requireActivity().getExternalFilesDir(null), "/backup")
copyFolder(this_dir, target_dir)

My code(that does not work in android 11):

var this_dir = File(requireActivity().getExternalFilesDir(null), "/backup")
var target_dir = File("/storage/emulated/0/Download/Sandoghcheh")
copyFolder(this_dir, target_dir)

permisions:

<uses-permission 
  android:name="android.permission.WRITE_SETTINGS" />

<uses-permission 
 android:name="android.permission.READ_EXTERNAL_STORAGE" />

<uses-permission
 android:name="android.permission.WRITE_EXTERNAL_STORAGE"
    android:maxSdkVersion="31" />

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

fun:

  fun copyFolder(source: File, destination: File) {
    if (source.isDirectory) {
        if (!destination.exists()) {
            destination.mkdirs()
        }
        val files = source.list()
        for (file in files) {
            val srcFile = File(source, file)
            val destFile = File(destination, file)
            copyFolder(srcFile, destFile)
        }
    } else {
        var `in`: InputStream? = null
        var out: OutputStream? = null
        try {
            `in` = FileInputStream(source)
            out = FileOutputStream(destination)
            val buffer = ByteArray(1024)
            var length: Int
            while (`in`.read(buffer).also { length = it } > 0) {
                out.write(buffer, 0, length)
            }
        } catch (e: Exception) {
            try {
                if (`in` != null) {
                    `in`.close()
                }
            } catch (e1: IOException) {
                e1.printStackTrace()
            }
            try {
                if (out != null) {
                    out.close()
                }
            } catch (e1: IOException) {
                e1.printStackTrace()
            }
        }
    }
}

reatore fun:

  private fun restore() {
    if (Build.VERSION.SDK_INT < 30) {
        createDirectory("backup")
        val file =   File("/storage/emulated/0/Download/Sandoghcheh")
        val target_dir = File(requireActivity().getExternalFilesDir(null), "/backup")
        copyFolder(target_dir,file )

    } else {

         val file =   File("/storage/emulated/0/Download/Sandoghcheh")
        val target_dir = File(requireActivity().getExternalFilesDir(null), "/backup")
        copyFolder(file, target_dir)
    }

    activity?.let {
        RoomBackup()
            .customRestoreDialogTitle("یکی از بشتیبان ها را انتخاب کنید")
            .context(it)
            .database(UserDatabase.getInstance(it))
            .enableLogDebug(true)
            .backupIsEncrypted(true)
            .customEncryptPassword("Amir")
            .useExternalStorage(true)
            .apply {
                onCompleteListener { success, message ->
                    Log.d("TAG", "success: $success, message: $message")
                    if (success) restartApp(Intent(context, SplashActivity::class.java))
                }
            }
            .restore()
    }
}

backup fun:

      private fun backup() {
      context?.let {
          RoomBackup()
              .context(it)
              .database(UserDatabase.getInstance(it))
              .enableLogDebug(true)
              .backupIsEncrypted(true)
              .customEncryptPassword("Amir")
              .useExternalStorage(true)
              .maxFileCount(5)
              .apply {
                  onCompleteListener { success, message ->
                  }
              }
              .backup()
      }
          if (Build.VERSION.SDK_INT < 30) {
            if (ContextCompat.checkSelfPermission(
                    requireActivity(),
                    Manifest.permission.WRITE_EXTERNAL_STORAGE
                ) == PackageManager.PERMISSION_GRANTED
            ) {
                var this_dir = File(requireActivity().getExternalFilesDir(null), "/backup")
                var target_dir = File("/storage/emulated/0/Download/Sandoghcheh")
                copyFolder(this_dir, target_dir)
            } else {
                askPermission()
            }
            var this_dir = File(requireActivity().getExternalFilesDir(null), "/backup")
            var target_dir =
                File("/storage/emulated/0/Sandoghcheh")
            copyFolder(this_dir, target_dir)

        } else {
            val download_folder =
                Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
            var this_dir = File(requireActivity().getExternalFilesDir(null), "/backup")
            var target_dir =download_folder
            copyFolder(target_dir, this_dir)
            Log.d("TAG", "backup: $download_folder,,$this_dir")


            //                 restartApp()

    }

}

and last but not the least: when I get this_dir and target_dir path it show me:

2022-01-21 13:41:07.938 23449-23449/com.example.holyquran D/TAG: backup: /storage/emulated/0/Download  ||||  /storage/emulated/0/Android/data/com.example.holyquran/files/backup

Restore FUN WORKS PERFECT, IT COPIES BUT BACK UP FUN DOES NOT COPY

as I said this code is not working in API +30

TNX for spending time on this Q :)

Amir
  • 333
  • 4
  • 16
  • It's not a bug. It's a change in Android. I suggest you to read this https://developer.android.com/about/versions/11/privacy/storage – Ivo Jan 21 '22 at 09:38
  • so thanks for you comment. Can you please provide me a piece of code that can copy content of root app folder to another folder in android 11 please? – Amir Jan 21 '22 at 09:41
  • I'm not that familiar with it but I would think the link could guide you. Or maybe someone else can answer it for you – Ivo Jan 21 '22 at 09:43
  • thanks in advance. but if it is a featchre in android 11, how I copy from a folder in download to root of app. – Amir Jan 21 '22 at 09:45
  • What you say does not make sense. Every app can create files in all public folders like Download and Documents. Just need normal write permissians as you used to have. – blackapps Jan 21 '22 at 09:52
  • `if (!destination.exists()) { destination.mkdirs() }` Check return value of mkdirs and stop if you cannot create the directory: `if (!destination.exists()) { if ( !destination.mkdirs()) return; }` Do not try to create files in a directory that does not exist. Please tell if you could create your directory. – blackapps Jan 21 '22 at 09:54
  • https://stackoverflow.com/questions/65637610/saving-files-in-android-11-to-external-storagesdk-30/65640584#65640584 – blackapps Jan 21 '22 at 09:57
  • wait a sec i will let u know – Amir Jan 21 '22 at 09:58
  • `MANAGE_EXTERNAL_STORAGE` Wel... if you requested that. And obtained that at runtime. Then you have access to all files and what you say is even more unbelievable. – blackapps Jan 21 '22 at 10:01
  • if I delete Sandoghcheh folder, it wont create this folder, but below 30 it will – Amir Jan 21 '22 at 10:02
  • `as I said this code is not working in API +30` That is a pretty bad problem description. What happens instead? Exceptions? Errors? Crashes? Please post the relevant logcat lines. – blackapps Jan 21 '22 at 10:02
  • let me provide more code – Amir Jan 21 '22 at 10:02
  • `if I delete Sandoghcheh folder, it wont create this folder, but below 30 it will ` And you did not even tell that in your post? You just said you could not copy. Sigh. And also tell \who deleted that folder. And how? Your app? We all have to guess what you do.. – blackapps Jan 21 '22 at 10:05
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/241274/discussion-between-amirandroiddeveloper-and-blackapps). – Amir Jan 21 '22 at 10:06
  • No chatting. Please edit your post and tell on the first lines what you did and want to do. Complete scenario. Dont let us guess. – blackapps Jan 21 '22 at 10:07
  • ok I added logs and in my opinion there is no problem with copy fun. bcz it works as expected, it copies files from Sandoghcheh folder to root of my app – Amir Jan 21 '22 at 10:14
  • it can not do the oppesit thing which is coping content of a file to root of app – Amir Jan 21 '22 at 10:15
  • so just provide me code that copy contetnt of a folder, works for u and works in android 11 TNX a million man – Amir Jan 21 '22 at 10:16

0 Answers0