Ficheros usando MediaStore en Kotlin
Escribir y leer ficheros usando MediaStore.
Para versiones de Android 10 (API 29) o superiores
Crear un nuevo proyecto en Kotlin: MemoriaExternaMediaStoreKotlin
Añadir el permiso al manifiesto:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
build.gradle
plugins { id("com.android.application") id("org.jetbrains.kotlin.android") } android { namespace = "com.example.memoriaexternakotlin" compileSdk = 34 buildFeatures { viewBinding = true }
strings.xml
<resources> <string name="app_name">Memoria Externa en Kotlin</string> <string name="texto">una prueba de escritura en memoria externa</string> <string name="botonEsc">Guardar</string> <string name="botonLee">Leer</string> <string name="propiedades">Propiedades del fichero</string> </resources>
activity_main.xml
<?xml version = "1.0" encoding = "utf-8" ?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <EditText android:id="@+id/editText" android:layout_width="270dp" android:layout_height="156dp" android:layout_marginLeft="40dp" android:layout_marginTop="20dp" android:layout_marginEnd="68dp" android:ems="10" android:gravity="top|left" android:text="@string/texto" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.04" /> <com.google.android.material.switchmaterial.SwitchMaterial android:id="@+id/swExplorer" android:layout_width="170dp" android:layout_height="48dp" android:layout_marginBottom="20dp" android:checked="false" android:text="Explorador" app:layout_constraintBottom_toTopOf="@+id/guideline" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" /> <androidx.constraintlayout.widget.Guideline android:id="@+id/guideline" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" app:layout_constraintGuide_begin="265dp" /> <Button android:id="@+id/btnWrite" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="36dp" android:layout_marginEnd="236dp" android:text="@string/botonEscribir" app:layout_constraintBottom_toTopOf="@+id/textView" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="@+id/guideline" app:layout_constraintVertical_bias="0.025" /> <Button android:id="@+id/btnRead" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="49dp" android:layout_marginEnd="68dp" android:text="@string/botonLeer" app:layout_constraintBottom_toTopOf="@+id/textView" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintLeft_toRightOf="@+id/btnWrite" app:layout_constraintTop_toTopOf="@+id/guideline" app:layout_constraintVertical_bias="0.025" /> <TextView android:id="@+id/textView" android:layout_width="310dp" android:layout_height="236dp" android:text="@string/propiedades" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.495" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/editText" app:layout_constraintVertical_bias="0.599" /> </androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.kt
class MainActivity : AppCompatActivity(), View.OnClickListener { lateinit var binding: ActivityMainBinding companion object { const val FICHERO = "ficheroExterna.txt" val RELATIVE_PATH = Environment.DIRECTORY_DOCUMENTS + "/" // val RELATIVE_PATH = Environment.DIRECTORY_DOCUMENTS + "/ficheros/" //end "/" is not mandatory val TYPE = "text/plain" } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) binding = ActivityMainBinding.inflate(layoutInflater) val view: View = binding.root setContentView(view) binding.btnWrite.setOnClickListener(this) binding.btnRead.setOnClickListener(this) } override fun onClick(view: View) { if (view === binding.btnWrite) if (!binding.swExplorer.isChecked) writeTextFileToMediaStore(FICHERO) else saveFileExplorer() else if (view === binding.btnRead) if (!binding.swExplorer.isChecked) readTextFileFromMediaStore(FICHERO) else openAndReadFile() } // write and read the file }
Ask Gemini
For Android 10 and higher, give me the code in Kotlin to write a text file to the user’s «Documents» directory using the Storage Access Framework (SAF)
private fun saveFileExplorer() { val fileName = FICHERO //"my_document.txt" val mimeType = TYPE // Create an intent to create a new document val intent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply { addCategory(Intent.CATEGORY_OPENABLE) type = mimeType putExtra(Intent.EXTRA_TITLE, fileName) } // Launch the activity to create the document createDocumentLauncher.launch(intent) } private val createDocumentLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> if (result.resultCode == Activity.RESULT_OK) { result.data?.data?.let { uri -> // Write the data to the file writeFile(uri, binding.editText.text.toString()) } } else { Log.e("MyTag", "Error creating file") } } private fun writeFile(uri: Uri, data: String) { //val fileUri: Uri = uri uri.let { fileUri -> try { contentResolver.openOutputStream(fileUri)?.use { outputStream -> outputStream.write(data.toByteArray()) Log.d("MyTag", "File written successfully to: $fileUri") } } catch (e: IOException) { Log.e("MyTag", "Error writing to file: $fileUri", e) } } }
Ask Gemini
For Android 10 and higher, give me the code in Kotlin to read a text file using the Storage Access Framework (SAF)
private fun openAndReadFile() { val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply { addCategory(Intent.CATEGORY_OPENABLE) type = "text/plain" // Filter for text files } openFileLauncher.launch(intent) } private val openFileLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> if (result.resultCode == Activity.RESULT_OK) { result.data?.data?.let { uri -> readFileContent(uri) } } else { Log.e("MyTag", "File not selected") } } private fun readFileContent(uri: Uri) { try { contentResolver.openInputStream(uri)?.use { inputStream -> BufferedReader(InputStreamReader(inputStream)).use { reader -> val fileContent = reader.readText() binding.editText.setText(fileContent) Log.d("MyTag", "File content: $fileContent") } } showMessage("File read successfully:\n $FICHERO") } catch (e: IOException) { binding.editText.setText("Error reading file") showMessage("Fail to read the file:\n $FICHERO \n" + e.message.toString()) Log.e("MyTag", "Error reading file" + e.message.toString()) } } private fun showMessage(texto: String) { Toast.makeText(this, texto, Toast.LENGTH_SHORT).show() }
Ask Gemini:
give me the code to write a text file in kotlin using MediaStore
fun writeTextFileToMediaStore(fileName: String) { val relativePath = RELATIVE_PATH val type = TYPE try { val values = ContentValues() values.put(MediaStore.MediaColumns.DISPLAY_NAME, fileName) //file name values.put(MediaStore.MediaColumns.MIME_TYPE, type) //file extension, will automatically add to file values.put(MediaStore.MediaColumns.RELATIVE_PATH, relativePath) val uri = contentResolver.insert(MediaStore.Files.getContentUri("external"), values) //important! val outputStream = contentResolver.openOutputStream(uri!!) outputStream!!.write(binding.editText.text.toString().toByteArray()) outputStream.close() getFileProperties(uri) showMessage("File created successfully: $FICHERO") } catch (e: IOException) { showMessage("Fail to create file: " + e.message.toString()) } }
Ask Gemini:
give me the code in Kotlin to get the properties of the file (path and creation date) after I write it
private fun getFileProperties(uri: Uri) { val projection = arrayOf( MediaStore.Files.FileColumns.DATA, MediaStore.Files.FileColumns.DATE_ADDED ) val query = contentResolver.query( uri, projection, null, null, null ) query?.use { cursor -> val dataColumn = cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DATA) val dateAddedColumn = cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DATE_ADDED) if (cursor.moveToFirst()) { val path = cursor.getString(dataColumn) val dateAddedTimestamp = cursor.getLong(dateAddedColumn) val dateFormat = SimpleDateFormat("dd/MM/yyyy HH:mm:ss", Locale.getDefault()) val creationDate = dateFormat.format(Date(dateAddedTimestamp * 1000)) binding.textView.text = "File Path: $path\n Creation Date: $creationDate" Log.d("MyTag", "File Path: $path") Log.d("MyTag", "Creation Date: $creationDate") } else { binding.textView.text = "File properties not found" Log.e("MyTag", "File properties not found") } } }
Ask Gemini:
give me the code to read a text file in kotlin using MediaStore, the file relative path is Environment.DIRECTORY_ DOCUMENTS
private fun readTextFileFromMediaStore(fileName: String) { val relativePath = RELATIVE_PATH val collection = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL) } else { MediaStore.Files.getContentUri("external") } val projection = arrayOf( MediaStore.Files.FileColumns._ID, MediaStore.Files.FileColumns.DISPLAY_NAME, MediaStore.Files.FileColumns.RELATIVE_PATH ) val selection = "${MediaStore.Files.FileColumns.DISPLAY_NAME} = ? AND ${MediaStore.Files.FileColumns.RELATIVE_PATH} = ?" val selectionArgs = arrayOf(fileName, relativePath) val query = contentResolver.query( collection, projection, selection, selectionArgs, null ) query?.use { cursor -> val idColumn = cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns._ID) val nameColumn = cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DISPLAY_NAME) val relativePathColumn = cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.RELATIVE_PATH) if (cursor.moveToFirst()) { val id = cursor.getLong(idColumn) val name = cursor.getString(nameColumn) val path = cursor.getString(relativePathColumn) val contentUri: Uri = Uri.withAppendedPath(collection, id.toString()) Log.d("MyTag", "Found file: $name, Path: $path, Uri: $contentUri") readFileContent(contentUri) } else { showMessage("File not found: $FICHERO") Log.e("MyTag", "File not found") } } } /* private fun readFileContent(uri: Uri) { try { contentResolver.openInputStream(uri)?.use { inputStream -> BufferedReader(InputStreamReader(inputStream)).use { reader -> val fileContent = reader.readText() binding.editText.setText(fileContent) Log.d("MyTag", "File content: $fileContent") } } showMessage("File read successfully:\n $FICHERO") } catch (e: IOException) { binding.editText.setText("Error reading file") showMessage("Fail to read the file:\n $FICHERO \n" + e.message.toString()) Log.e("MyTag", "Error reading file" + e.message.toString()) } } */
Más información:
Access media files from shared storage
Deja una respuesta
Lo siento, debes estar conectado para publicar un comentario.