I want to create sub directory (custom folder) with text file and write string data in it. As in Android 11 there is restriction so i have done this code.
private val filepath = "mySubDirectory"
private val filename = "test.txt"
private fun writeExternalStorage(list: MutableList<String>) {
if (VERSION.SDK_INT >= VERSION_CODES.Q) {
val resolver = contentResolver
val values = ContentValues()
values.put(MediaStore.MediaColumns.DISPLAY_NAME, filename)
values.put(MediaStore.MediaColumns.MIME_TYPE, "text/plain")
values.put(
MediaStore.MediaColumns.RELATIVE_PATH,
Environment.DIRECTORY_DOCUMENTS + "/" + filepath
)
val uri = resolver.insert(MediaStore.Files.getContentUri("external"), values)
Log.v("MYATGAGAA", uri!!.toString())
val file = FileUtil.from(this, uri!!) as File
Log.v("MYATGAGAA", file.absolutePath)
try {
file.parentFile.mkdirs()
file.bufferedWriter().use { out ->
for (item in list) {
Log.v("MYATGAGAA", item)
out.write(item)
}
}
} catch (e: IOException) {
Toast.makeText(this, "Error Q", Toast.LENGTH_LONG).show()
return
}
Toast.makeText(this, "Saved for Q", Toast.LENGTH_LONG).show()
}
But i m getting uri null at this line Log.v("MYATGAGAA", uri!!.toString())
I have already granted storage permission below:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"></uses-permission>
For Android R devices i have manually checked
if (SDK_INT >= Build.VERSION_CODES.R) {
try {
val intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)
intent.addCategory("android.intent.category.DEFAULT")
intent.data =
Uri.parse(String.format("package:%s", applicationContext.packageName))
startActivityForResult(intent, 2296)
} catch (e: Exception) {
val intent = Intent()
intent.action = Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION
startActivityForResult(intent, 2296)
}
}
This is my FileUtil class.
class FileUtil {
companion object {
private const val EOF = -1
private const val DEFAULT_BUFFER_SIZE = 1024 * 4
@Throws(IOException::class)
fun from(context: Context, uri: Uri): File? {
val inputStream: InputStream = context.contentResolver.openInputStream(uri)!!
val fileName = getFileName(context, uri)
val splitName = splitFileName(fileName)
var tempFile: File = File.createTempFile(splitName[0], splitName[1])
tempFile = rename(tempFile, fileName)
tempFile.deleteOnExit()
var out: FileOutputStream? = null
try {
out = FileOutputStream(tempFile)
} catch (e: FileNotFoundException) {
e.printStackTrace()
}
if (inputStream != null) {
copy(inputStream, out!!)
inputStream.close()
}
out?.close()
return tempFile
}
private fun splitFileName(fileName: String): Array<String> {
var name = fileName
var extension = ""
val i = fileName.lastIndexOf(".")
if (i != -1) {
name = fileName.substring(0, i)
extension = fileName.substring(i)
}
return arrayOf(name, extension)
}
private fun getFileName(context: Context, uri: Uri): String {
var result: String? = null
if (uri.scheme.equals("content")) {
val cursor: Cursor = context.contentResolver.query(uri, null, null, null, null)!!
try {
if (cursor != null && cursor.moveToFirst()) {
result =
cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME))
}
} catch (e: Exception) {
e.printStackTrace()
} finally {
if (cursor != null) {
cursor.close()
}
}
}
if (result == null) {
result = uri.path
val cut: Int = result!!.lastIndexOf(File.separator)
if (cut != -1) {
result = result.substring(cut + 1)
}
}
return result
}
private fun rename(file: File, newName: String): File {
val newFile = File(file.parent, newName)
if (newFile != file) {
if (newFile.exists() && newFile.delete()) {
Log.d("FileUtil", "Delete old $newName file")
}
if (file.renameTo(newFile)) {
Log.d("FileUtil", "Rename file to $newName")
}
}
return newFile
}
@Throws(IOException::class)
private fun copy(input: InputStream, output: OutputStream): Long {
var count: Long = 0
var n: Int
val buffer = ByteArray(DEFAULT_BUFFER_SIZE)
while (EOF != input.read(buffer).also { n = it }) {
output.write(buffer, 0, n)
count += n.toLong()
}
return count
}
}
}
still getting error. So please help me to sort out this. Thanks in Advance