如何让string.xml从外部文件导入内容?求有效解决方案
从外部文件动态加载字符串(替代string.xml静态内容)
Android的string.xml是编译时打包的资源,没法直接让它在运行时读取外部文件内容。但可以通过代码读取外部文本文件的内容,然后在应用里动态使用,达到类似效果。下面提供两种常见场景的实现代码:
场景1:从assets目录加载(打包在APK内的外部文件)
把你的文本文件放到src/main/assets/目录下(比如命名为external_strings.txt),用下面的工具类读取:
读取工具类
import android.content.Context import java.io.BufferedReader import java.io.IOException import java.io.InputStreamReader object ExternalStringLoader { // 读取整个文本文件内容 fun loadFromAssets(context: Context, fileName: String): String { val stringBuilder = StringBuilder() try { val inputStream = context.assets.open(fileName) val reader = BufferedReader(InputStreamReader(inputStream)) var line: String? while (reader.readLine().also { line = it } != null) { stringBuilder.append(line).append("\n") } reader.close() inputStream.close() } catch (e: IOException) { e.printStackTrace() return "" } return stringBuilder.toString().trim() } // 如果文本是键值对格式(比如welcome=欢迎使用),解析成Map fun loadKeyValuesFromAssets(context: Context, fileName: String): Map<String, String> { val keyValueMap = mutableMapOf<String, String>() try { val inputStream = context.assets.open(fileName) val reader = BufferedReader(InputStreamReader(inputStream)) var line: String? while (reader.readLine().also { line = it } != null) { line?.split("=")?.takeIf { it.size == 2 }?.let { keyValueMap[it[0].trim()] = it[1].trim() } } reader.close() inputStream.close() } catch (e: IOException) { e.printStackTrace() } return keyValueMap } }
使用示例
// 读取整个文本内容,直接设置给TextView val fullText = ExternalStringLoader.loadFromAssets(this, "external_strings.txt") textView.text = fullText // 如果是键值对格式,按key取字符串(替代getString(R.string.welcome)) val stringMap = ExternalStringLoader.loadKeyValuesFromAssets(this, "external_strings.txt") textView.text = stringMap["welcome"] ?: getString(R.string.default_welcome)
场景2:从设备外部存储(比如SD卡)加载
先在Manifest里配置权限,然后读取指定路径的文件:
权限配置(AndroidManifest.xml)
<!-- Android 10及以上无需申请该权限,特殊场景可参考MANAGE_EXTERNAL_STORAGE --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="29" />
读取工具类
import android.os.Environment import java.io.BufferedReader import java.io.File import java.io.FileReader import java.io.IOException object ExternalStorageStringLoader { // 读取指定路径的文本文件 fun loadFromFilePath(filePath: String): String { val stringBuilder = StringBuilder() val file = File(filePath) if (!file.exists()) return "" try { val reader = BufferedReader(FileReader(file)) var line: String? while (reader.readLine().also { line = it } != null) { stringBuilder.append(line).append("\n") } reader.close() } catch (e: IOException) { e.printStackTrace() return "" } return stringBuilder.toString().trim() } // 快捷方法:读取SD卡根目录下的文件 fun loadFromSdCardRoot(fileName: String): String { val sdCardPath = Environment.getExternalStorageDirectory().absolutePath return loadFromFilePath("$sdCardPath/$fileName") } }
使用示例(需先处理权限请求)
import android.Manifest import android.content.pm.PackageManager import androidx.appcompat.app.AppCompatActivity import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat class MainActivity : AppCompatActivity() { private val REQUEST_STORAGE_PERMISSION = 1001 override fun onStart() { super.onStart() checkStoragePermissionAndLoad() } private fun checkStoragePermissionAndLoad() { if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED ) { // 权限已获取,读取文件 val externalText = ExternalStorageStringLoader.loadFromSdCardRoot("external_strings.txt") textView.text = externalText } else { // 请求权限 ActivityCompat.requestPermissions( this, arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), REQUEST_STORAGE_PERMISSION ) } } // 处理权限请求结果 override fun onRequestPermissionsResult( requestCode: Int, permissions: Array<out String>, grantResults: IntArray ) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) if (requestCode == REQUEST_STORAGE_PERMISSION) { if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { checkStoragePermissionAndLoad() } } } }
内容的提问来源于stack exchange,提问作者Emmanuel Goldstein
相关产品推荐
相关产品推荐

