I can't delete the folder's content from path - android

I'm currently getting this path from my FileExplorer
val path = "content://com.android.externalstorage.documents/tree/primary:Download"
And I'm trying to delete the content of this location:
val fileFolder = File(path)
deleteFolderContent(fileFolder)
private fun deleteFolderContent(fileFolder: File) {
val files = fileFolder.listFiles()
if (files.isNullOrEmpty()) {
return
} else {
for (file in files) {
file.delete()
}
}
}
But files is always null and I can't delete the content. What am I doing wrong? Can anyone help me? Thanks.
Update:
For obtain this "path" I did this:
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
startActivityForResult(intent, SELECT_FOLDER_REQUEST_CODE)
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == SELECT_FOLDER_REQUEST_CODE && resultCode == RESULT_OK) {
val uriTree = data?.data
}
}

you can't access content directory as a File (even when URI points on local storage). check out Providers and ContentResolver, HERE you have some basics, for files there is special one: FileProvider. but for your case ContentResolver may fit for your needs best, with method:
context.contentResolver.delete(uriToDelete, null, null)

Related

How to load audio file in ListView?

I need to load random audio files from storage, into my ListView, on a button click. But I don't understand how can I do this. When I call intent, file manager open to pick file. My song must have title, artist name and url. But after clicking it doesn't add. This is my code. Don't scold me for a possibly dull question. I'm new at android developing.
private fun loadSong() {
val intent: Intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
type = "audio/*"
action = Intent.ACTION_GET_CONTENT
}
startActivityForResult(Intent.createChooser(intent, "Select Audio"), PICK_AUDIO)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == PICK_AUDIO && resultCode == RESULT_OK){
if (data != null) {
audioUri = data.data
}
}
adapter = SongsAdapter(listSongs)
twoTracksListView.adapter = adapter
}

How do i create and fill a file in the directory the User choose with ACTION_OPEN_DOCUMENT_TREE on Android 9-11

I try to make an Export Function for my App, that can export(and later Import) data to a txt-file in the shared storage. I use the ACTION_OPEN_DOCUMENT_TREE to choose a Folder and get "resultdata: Intent?" back.
For explanation in the Downloads-folder/Documents-Folder there is a "myApp"-folder. The user gave permission for that folder. So i get an Intent? with the path to this place back
How can i use that to create a "Spells.txt" in said folder without ACTION_CREATE_DOCUMENT
Edit: Thanks to blackapps, I've found DocumentFile, which helped create and fill the File. Here are the relevant parts of my Code so far:
lateinit var permissedFolder: Intent
in onCreate
permissiontest_btn_Choose_Permission.setOnClickListener(){chooseFolder()}
permissiontest_btn_createFile.setOnClickListener(){createFile()}
fun chooseFolder(){
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).apply {
}
startActivityForResult(intent, 100)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) {
super.onActivityResult(requestCode, resultCode, resultData)
if(requestCode==100 && resultCode== RESULT_OK){
if (resultData != null) {
permissedFolder = resultData
}
fun createFile() {
if(permissedFolder.data != null) {
val folderUri:Uri = permissedFolder.data!!
val enabledDirectory:DocumentFile= DocumentFile.fromTreeUri(this, folderUri)!!
val spellsExportDF =enabledDirectory.createFile(".txt","Spells.txt")
val spellsExportURI = spellsExportDF?.uri
if(spellsExportURI != null) {
val fileOutputStream = getContentResolver().openOutputStream(spellsExportURI)
//FileOutputStream(spellsExportURI, true)
fileOutputStream.use { fileout ->
fileout?.writer(Charsets.UTF_8)?.use {
it.write(test)
it.flush()
it.close()
}
}
val readfile = spellsExportDF.canRead()
val writefile =spellsExportDF.canWrite()
Toast.makeText(this, "can Read: $readfile", Toast.LENGTH_SHORT).show()
Toast.makeText(this, "can Write: $writefile", Toast.LENGTH_SHORT).show()
}

uploading image from gallery and camera to server

I need to save the image that is taken from camera or image taken from gallery in kotlin. for now I've done this part and i'm finding other examples in kotlin but i'm unable to find. In other examples, images were send in multipart which was coded in java.
These are listeners
private val cameraRequest = 1888
private val pickImage = 100
private var imageUri: Uri? = null
takePhoto.setOnClickListener {
val cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
startActivityForResult(cameraIntent, cameraRequest)
}
choosePicture.setOnClickListener {
val gallery = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI)
startActivityForResult(gallery, pickImage)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == cameraRequest) {
val photo: Bitmap = data?.extras?.get("data") as Bitmap
takePhoto.setImageBitmap(photo)
}
if (resultCode == RESULT_OK && requestCode == pickImage) {
imageUri = data?.data
if (imageUri != null) {
choosePicture.setImageURI(imageUri)
}
}
}
You can use this library for making a multipart request: https://github.com/gotev/android-upload-service
Also, it will handle app behaviour for you which includes upload-retry on slow internet connection and many more.

getData() is not working since migration to kotlin

I am new to kotlin. I wrote this code that will get image from image picker.
But I am getting error on line:val filePath: Uri = attr.data.getData()
error: Unresolved reference. Is there any change in kotlin because this code was working properly in java (Means I migrated to kotlin)
And another error on imageStore(bitmap) error: smart cast to bitmap is impossible.
I've searched for documentation but couldn't solve this 2 problems .
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == Activity.RESULT_OK && requestCode == 1) {
val filePath: Uri = attr.data.getData()
try {
val inputStream: InputStream? = contentResolver.openInputStream(filePath)
bitmap = BitmapFactory.decodeStream(inputStream)
imageStore(bitmap)
} catch (e: FileNotFoundException) {
e.printStackTrace()
}
}
}
But I am getting error on line:val filePath: Uri = attr.data.getData() error: Unresolved reference
Well, this means the compiler can't understand what you're referring to. Is it correct to say this ?
Well, considering you don't have any object named attr it would seem that the compiler is correct.
this means you should remove the attr part, something like:
val filePath: Uri = data?.getData() ?: return
The return here will stop executing the rest of the method if the data from the intent is null
To resolve your second problem, you'll need something like this :
bitmap?.let { bitmapInstance ->
imageStore(bitmapInstance)
}
What does this do ?
Well, it gives you thread safe access to your bitmap object and also ensures that the instance isn't null.
As #a_local_nobody said "the migration tool isn't perfect", I learned the basics of kotlin and found that the following code works fine for me.
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == 1 && resultCode == Activity.RESULT_OK && data != null) {
val filePath = data.data
try {
val inputStream = contentResolver.openInputStream(filePath!!)
bitmap = BitmapFactory.decodeStream(inputStream)
imageView!!.setImageBitmap(bitmap)
imageStore(bitmap)
} catch (e: FileNotFoundException) {
e.printStackTrace()
}
}
super.onActivityResult(requestCode, resultCode, data)
}
Replace this line val filePath: Uri = attr.data.getData() with
val filePath: Uri = data!!.getData()!!
Updated code
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == Activity.RESULT_OK && requestCode == 1) {
val filePath: Uri = data!!.getData()!!
try {
val inputStream: InputStream? = contentResolver.openInputStream(filePath)
var bitmap = BitmapFactory.decodeStream(inputStream)
imageStore(bitmap)
} catch (e: FileNotFoundException) {
e.printStackTrace()
}
}
}

ZipFile Kotlin class returns java.io.FileNotFoundException: File doesn't exist

I'm learning how to work with zip files in Kotlin. In theory my app should read files from zip and extract them if needed. For this task I use java.util.zip.ZipFile, but when I pass a file I choose, the app crashes, saying the file doesn't exist.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val intent = Intent()
.setType("*/*")
.setAction(Intent.ACTION_GET_CONTENT)
startActivityForResult(Intent.createChooser(intent, "Select a file"), 111)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == 111 && resultCode == RESULT_OK) {
val selectedFile = data?.data
var file = File(selectedFile!!.path)
var zipFile = ZipFile(file)
}
}
java.io.FileNotFoundException: File doesn't exist: /document/acc=1;doc=155
ZipFile only works with files, while the result of ACTION_GET_CONTENT is an Uri, from which you can usually not get a file (see How to Consume Content From a Uri for a detailed explanation).
There are two solutions :
Use a ZipInputStream, which can extract the content of a stream.
Copy the stream from the Uri to a local file, then open it with the ZipFile

Categories

Resources