Android load a config file from external Documents directory
1. Create a json file like this, config.json
{ "environment": "dev" }
2. Upload this config.json to the Android device
adb push config.json /sdcard/Documents/config.json
3. In Android Studio, click the Device Explorer on the right bottom panel, and check that this file is loaded.
4. Create a new Android Project, and add this permission in the Manifest file. As well as adding this flag to the application tag in the manifest file. android:requestLegacyExternalStorage="true"
5. Add these dependencies in the build gradle file.
implementation "androidx.preference:preference-ktx:1.1.0" implementation 'com.google.code.gson:gson:2.8.6'
6. Create Config.kt
data class Config(val environment: String)
7. Add this id android:id="@+id/tv_result"
to the TextView in activity_main.xml
8. Update the MainActivity file with the following code.
import android.Manifest import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.util.Log import java.io.File import java.io.FileInputStream import java.io.IOException import java.nio.charset.Charset import android.content.pm.PackageManager import android.os.Environment import android.os.Environment.getExternalStoragePublicDirectory import androidx.core.content.ContextCompat import androidx.core.app.ActivityCompat import com.google.gson.Gson import kotlinx.android.synthetic.main.activity_main.* class MainActivity : AppCompatActivity() { companion object { const val TAG = "MainActivity" } // /storage/emulated/0/Documents/test.txt or link /sdcard/Documents/config.json private var CONFIG_FILE_PATH = "${getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS)}/config.json" private val REQUEST_PERMISSIONS = 100 private val PERMISSIONS_REQUIRED = arrayOf( Manifest.permission.READ_EXTERNAL_STORAGE ) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) Log.d(TAG, "CONFIG_FILE_PATH: ${CONFIG_FILE_PATH}") if (checkPermission(PERMISSIONS_REQUIRED)) { showFileData() } else { ActivityCompat.requestPermissions(this, PERMISSIONS_REQUIRED, REQUEST_PERMISSIONS) } } override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) Log.d(TAG, "requestCode: $requestCode") Log.d(TAG, "Permissions:" + permissions.contentToString()) Log.d(TAG, "grantResults: " + grantResults.contentToString()) if (requestCode == REQUEST_PERMISSIONS) { var hasGrantedPermissions = true for (i in grantResults.indices) { if (grantResults[i] != PackageManager.PERMISSION_GRANTED) { hasGrantedPermissions = false break } } if (hasGrantedPermissions) { showFileData() } else { finish() } } else { finish() } } private fun showFileData() { val targetFile = File(CONFIG_FILE_PATH) val targetFileContent = if (targetFile.exists()) { readFile(targetFile) } else { "" } val config = Gson().fromJson(targetFileContent, Config::class.java) val stringBuilder = StringBuilder() stringBuilder.append("\n") stringBuilder.append("file location: $CONFIG_FILE_PATH") stringBuilder.append("\n") stringBuilder.append("file content: $targetFileContent") stringBuilder.append("\n") stringBuilder.append("environment: ${config.environment}") Log.d("file_debug", stringBuilder.toString()) tv_result.text = stringBuilder.toString() } private fun readFile(file: File) : String { var resultStr = "" try { val fileInputStream = FileInputStream(file) val size = fileInputStream.available() val buffer = ByteArray(size) fileInputStream.read(buffer) resultStr = String(buffer, Charset.forName("UTF-8")) fileInputStream.close() } catch (e: IOException) { e.printStackTrace() } return resultStr } private fun checkPermission(permissions: Array ): Boolean { for (permission in permissions) { if (ContextCompat.checkSelfPermission(applicationContext, permission) != PackageManager.PERMISSION_GRANTED) { return false } } return true } }
9. Run the app.
10. When asked for file permission, click allow.
Note: This only works for Android 10 or lower, for Android 11, scoped storage is strictly enforced and apps can no longer freely access external directories without using Documents Provider API.
Search within Codexpedia
Search the entire web