0

I have a test program that requests access to the Android/obb folder, but I do not know how I can move files to this folder. I tried to use standard kotlin functions to manage files, but it didn't give any result. I also have a similar version written in Java.

private fun moveFile(src: File, dest: File): Boolean {
    return src.renameTo(dest)
}

@RequiresApi(Build.VERSION_CODES.O)
private val handleIntentActivityResult =
    registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
        if (it.resultCode != Activity.RESULT_OK)
            return@registerForActivityResult
        val directoryUri = it.data?.data ?: return@registerForActivityResult
        contentResolver.takePersistableUriPermission(
            directoryUri, Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
        )
        if (checkIfGotAccess())
            onGotAccess()
        else
            Log.d("AppLog", "you didn't grant permission to the correct folder")
    }


@RequiresApi(Build.VERSION_CODES.Q)
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    val openDirectoryButton = findViewById<Button>(R.id.button1)
    val test = findViewById<Button>(R.id.button2)
    val test1 = findViewById<Button>(R.id.button3)
    openDirectoryButton.setOnClickListener {
        openDirectory()
    }
    test.setOnClickListener {
        main()
    }
    test1.setOnClickListener {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            main1()
        }
    }
}

@RequiresApi(Build.VERSION_CODES.R)
private fun main1() {
    val uri = Uri.parse("package:${BuildConfig.APPLICATION_ID}")

    startActivity(
        Intent(
            Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION,
            uri
        )
    )
}

private fun main() {
    val from = File(Environment.getExternalStorageDirectory(), "video.mp4")
    val to = File(Environment.getExternalStorageDirectory(), "Android/obb/video.mp4")
    try {
        val isSuccess = moveFile(from, to)
        if (isSuccess) {
            val text = "File Moved Successfully!"
            val duration = Toast.LENGTH_SHORT

            val toast = Toast.makeText(applicationContext, text, duration)
            toast.show()
        } else {
            val text = "File Moved Failed!"
            val duration = Toast.LENGTH_SHORT

            val toast = Toast.makeText(applicationContext, text, duration)
            toast.show()
        }
    } catch (ex: IOException) {
        ex.printStackTrace()
    }
}

private fun checkIfGotAccess(): Boolean {
    return contentResolver.persistedUriPermissions.indexOfFirst { uriPermission ->
        uriPermission.uri.equals(androidTreeUri) && uriPermission.isReadPermission && uriPermission.isWritePermission
    } >= 0
}

@RequiresApi(Build.VERSION_CODES.O)
private fun onGotAccess() {
    Log.d("AppLog", "got access to Android folder. showing content of each folder:")
    @Suppress("DEPRECATION")
    File(Environment.getExternalStorageDirectory(), "Android/obb").listFiles()?.forEach { androidSubFolder ->
        val docId = "$ANDROID_DOCID/${androidSubFolder.name}"
        val childrenUri = DocumentsContract.buildChildDocumentsUriUsingTree(androidTreeUri, docId)
        val contentResolver = this.contentResolver
        Log.d("AppLog", "content of:${androidSubFolder.absolutePath} :")
        contentResolver.query(childrenUri, null, null, null)
            ?.use { cursor ->
                val filesCount = cursor.count
                Log.d("AppLog", "filesCount:$filesCount")
                val nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
                val mimeIndex = cursor.getColumnIndex("mime_type")
                while (cursor.moveToNext()) {
                    val displayName = cursor.getString(nameIndex)
                    val mimeType = cursor.getString(mimeIndex)
                    Log.d("AppLog", "  $displayName isFolder?${mimeType == DocumentsContract.Document.MIME_TYPE_DIR}")
                }
            }
    }
}
@RequiresApi(Build.VERSION_CODES.Q)
private fun openDirectory() {
    if (checkIfGotAccess())
        onGotAccess()
    else {
        val primaryStorageVolume = (getSystemService(STORAGE_SERVICE) as StorageManager).primaryStorageVolume
        val intent =
            primaryStorageVolume.createOpenDocumentTreeIntent().putExtra(EXTRA_INITIAL_URI, androidUri)
        handleIntentActivityResult.launch(intent)
    }
}

companion object {
    private const val ANDROID_DOCID = "primary:Android/obb"
    private const val EXTERNAL_STORAGE_PROVIDER_AUTHORITY = "com.android.externalstorage.documents"
    private val androidUri = DocumentsContract.buildDocumentUri(
        EXTERNAL_STORAGE_PROVIDER_AUTHORITY, ANDROID_DOCID
    )
    private val androidTreeUri = DocumentsContract.buildTreeDocumentUri(
        EXTERNAL_STORAGE_PROVIDER_AUTHORITY, ANDROID_DOCID
    )
}

I think I need to use SAF but haven't found the way I need in my situation.

0 Answers0