我用 Android Studio 在 Kotlin 中编写了一个应用程序,将一些字符串写入文件。所有的工作,我都可以在应用程序内部读写,但是我看不到在 Documents 文件夹中查找的文件。如何使用文件夹 Documents 作为存储空间?谢谢
这些是我使用的功能:
fun saveTextFile(view: View, nomeFile: String, testo: String, contesto: Context){
var fileStream: FileOutputStream
try {
fileStream = contesto.openFileOutput(nomeFile, MODE_APPEND) // OK esegue append
fileStream.write(testo.toByteArray())
fileStream.close()
}catch (e: Exception){
e.printStackTrace()
}
}
fun readTextFile(view: View, nomeFile: String, contesto: Context): String{
var fileInputStream: FileInputStream? = null
fileInputStream = contesto.openFileInput(nomeFile)
var inputStreamReader: InputStreamReader = InputStreamReader(fileInputStream)
val bufferedReader: BufferedReader = BufferedReader(inputStreamReader)
val stringBuilder: StringBuilder = StringBuilder()
var text: String? = null
while ({ text = bufferedReader.readLine(); text }() != null) {
stringBuilder.append(text)
}
inputStreamReader.close();
return(stringBuilder.toString())
}
谢谢你,利维奥
要写入设备的 Documents 文件夹,您只需要使用 MediaStore 即可。你可以为这个函数输入任何你想要的东西,比如 String 、 bitmap 、 PdfDocument 等等。
对于您的用例,您可以执行以下操作,
全局变量:
private var imageUri: Uri? = null
override suspend fun saveDocument(context : Context, text : String) {
withContext(Dispatchers.IO) {
try {
val collection =
MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
val dirDest = File(
Environment.DIRECTORY_DOCUMENTS,
context.getString(R.string.app_name)
)
val date = System.currentTimeMillis()
val fileName = "$date.txt"
val contentValues = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, fileName)
put(MediaStore.MediaColumns.RELATIVE_PATH,
"$dirDest${File.separator}")
put(MediaStore.Files.FileColumns.IS_PENDING, 1)
}
}
val imageUri = context.contentResolver.insert(collection, contentValues)
withContext(Dispatchers.IO) {
imageUri?.let { uri ->
context.contentResolver.openOutputStream(uri, "w").use { out -> out?.write(text.toByteArray())
}
contentValues.clear()
contentValues.put(MediaStore.Files.FileColumns.IS_PENDING, 0)
context.contentResolver.update(uri, contentValues, null, null)
}
}
} catch (e: FileNotFoundException) {
null
}
}
}
要更新现有文件,请执行以下操作。第一次创建文件后,我将 imageUri 保存在全局变量中(如果您想永久/或暂时存储它,您可以使用 Jetpack Datastore / Shared Preference 来保存相同的内容):
suspend fun updateData(context: Context,text : String){
withContext(Dispatchers.IO) {
try {
val collection =
MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
val dirDest = File(
Environment.DIRECTORY_DOCUMENTS,
context.getString(R.string.app_name)
)
val fileName = "test.txt"
val contentValues = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, fileName)
put(
MediaStore.MediaColumns.RELATIVE_PATH,
"$dirDest${File.separator}"
)
put(MediaStore.Files.FileColumns.IS_PENDING, 1)
}
withContext(Dispatchers.IO) {
imageUri?.let { uri ->
context.contentResolver.openOutputStream(uri, "wa").use { out ->
out?.write(text.toByteArray())
}
contentValues.clear()
contentValues.put(MediaStore.Files.FileColumns.IS_PENDING, 0)
context.contentResolver.update(uri, contentValues, null, null)
}
}
} catch (e: FileNotFoundException) {
null
}
}
}
要读取文件,请执行以下操作:
suspend fun read(context: Context, source: Uri): String = withContext(Dispatchers.IO) {
val resolver: ContentResolver = context.contentResolver
resolver.openInputStream(source)?.use { stream -> stream.readText() }
?: throw IllegalStateException("could not open $source")
}
private fun InputStream.readText(charset: Charset = Charsets.UTF_8): String =
readBytes().toString(charset)
这是最终代码的样子:
class MainActivity : AppCompatActivity() {
private lateinit var btn: Button
private var imageUri: Uri? = null
private lateinit var btn2: Button
private lateinit var btn3 : Button
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
btn = findViewById(R.id.btnAdd)
btn2 = findViewById(R.id.getText)
btn3 = findViewById(R.id.updateText)
btn.setOnClickListener {
lifecycleScope.launch {
saveDocument(applicationContext, "Original ")
}
}
btn3.setOnClickListener {
lifecycleScope.launch {
updateData(applicationContext,"Appended")
}
}
btn2.setOnClickListener {
lifecycleScope.launch {
imageUri?.let { it1 ->
val data = read(applicationContext, it1)
Toast.makeText(applicationContext, "The data is $data ", Toast.LENGTH_LONG)
.show()
}
}
}
}
suspend fun saveDocument(context: Context, text: String) {
withContext(Dispatchers.IO) {
try {
val collection =
MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
val dirDest = File(
Environment.DIRECTORY_DOCUMENTS,
context.getString(R.string.app_name)
)
val date = System.currentTimeMillis()
val fileName = "test.txt"
val contentValues = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, fileName)
put(
MediaStore.MediaColumns.RELATIVE_PATH,
"$dirDest${File.separator}"
)
put(MediaStore.Files.FileColumns.IS_PENDING, 1)
}
imageUri = context.contentResolver.insert(collection, contentValues)
withContext(Dispatchers.IO) {
imageUri?.let { uri ->
context.contentResolver.openOutputStream(uri, "w").use { out ->
out?.write(text.toByteArray())
}
contentValues.clear()
contentValues.put(MediaStore.Files.FileColumns.IS_PENDING, 0)
context.contentResolver.update(uri, contentValues, null, null)
}
}
} catch (e: FileNotFoundException) {
null
}
}
}
suspend fun updateData(context: Context, text: String) {
withContext(Dispatchers.IO) {
try {
val collection =
MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
val dirDest = File(
Environment.DIRECTORY_DOCUMENTS,
context.getString(R.string.app_name)
)
val fileName = "test.txt"
val contentValues = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, fileName)
put(
MediaStore.MediaColumns.RELATIVE_PATH,
"$dirDest${File.separator}"
)
put(MediaStore.Files.FileColumns.IS_PENDING, 1)
}
withContext(Dispatchers.IO) {
imageUri?.let { uri ->
context.contentResolver.openOutputStream(uri, "wa").use { out ->
out?.write(text.toByteArray())
}
contentValues.clear()
contentValues.put(MediaStore.Files.FileColumns.IS_PENDING, 0)
context.contentResolver.update(uri, contentValues, null, null)
}
}
} catch (e: FileNotFoundException) {
null
}
}
}
suspend fun read(context: Context, source: Uri): String = withContext(Dispatchers.IO) {
val resolver: ContentResolver = context.contentResolver
resolver.openInputStream(source)?.use { stream -> stream.readText() }
?: throw IllegalStateException("could not open $source")
}
private fun InputStream.readText(charset: Charset = Charsets.UTF_8): String =
readBytes().toString(charset)
我有三个按钮。首先我创建了一个文件,然后 uri 被存储在全局变量中。然后单击第二个按钮,我将其添加到已经存在的文件中,然后使用存储在全局变量中的相同 imageUri 使用第三个按钮读取文件
这是相同的演示。检查按下按钮的时间以及底部 Toast 形式的输出。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句