diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 958b0d75..06d5123c 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -6,6 +6,8 @@
+
+
->
if (isGranted.all { it.value }) {
// phone permissions granted
- if(isGranted.containsKey(CALL_PHONE) || isGranted.containsKey(READ_PHONE_STATE)){
+ if (isGranted.containsKey(CALL_PHONE) || isGranted.containsKey(READ_PHONE_STATE)) {
binding.swiperefresh.isRefreshing = true
setDefaultSubscriptionId()
onRefresh()
@@ -58,6 +58,21 @@ class MainActivity : AbstractBaseActivity(), SwipeRefreshLayout.OnRefreshListene
}
}
+ private val requestStoragePermission = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->
+ // Because of api version some device need permission to save file in storage
+ // so a contract is created
+ val canRead = permissions[READ_EXTERNAL_STORAGE] ?: false
+ val canWrite = permissions[WRITE_EXTERNAL_STORAGE] ?: false
+ if (canRead && canWrite) {
+ // when user grant read and write permission,
+ // export the file to download folder
+ exportAsCsv()
+ } else {
+ // User did not grant permission so an error is displayed for the user to see
+ showSnackbar(R.string.export_error_saving_file)
+ }
+ }
+
override fun onCreate(savedInstanceState: Bundle?) {
val splashScreen = installSplashScreen()
// Apply dynamic colors here to avoid losing them due to splash screen: https://github.com/material-components/material-components-android/issues/2555
@@ -117,7 +132,7 @@ class MainActivity : AbstractBaseActivity(), SwipeRefreshLayout.OnRefreshListene
override fun onOptionsItemSelected(item: MenuItem): Boolean {
Log.d(TAG, "onOptionsItemSelected($item)")
- return when(item.itemId) {
+ return when (item.itemId) {
R.id.preferences -> {
Intent(this, PreferenceActivity::class.java).apply {
startActivity(this)
@@ -125,7 +140,20 @@ class MainActivity : AbstractBaseActivity(), SwipeRefreshLayout.OnRefreshListene
true
}
R.id.export -> {
- exportAsCsv()
+ if (
+ Build.VERSION.SDK_INT <= Build.VERSION_CODES.P &&
+ !hasPermissions(READ_EXTERNAL_STORAGE) &&
+ !hasPermissions(WRITE_EXTERNAL_STORAGE)
+ ) {
+ // this if statement check if this device is with in the version that needs
+ // permission to save file. It also check if read and write permission not granted.
+ // It then launch the contract for the user to grant the permission
+ requestStoragePermission.launch(arrayOf(WRITE_EXTERNAL_STORAGE, READ_EXTERNAL_STORAGE))
+ } else {
+ // modern device does not need permission to save file in public folder like
+ // download
+ exportAsCsv()
+ }
true
}
android.R.id.home -> {
@@ -136,20 +164,20 @@ class MainActivity : AbstractBaseActivity(), SwipeRefreshLayout.OnRefreshListene
}
}
+ /**
+ * Export a CSV file to the Downloads folder.
+ */
private fun exportAsCsv() {
launch {
- val content = buildCsv()
-
try {
+ val content = buildCsv()
val filename = "prepaid-balance-${System.currentTimeMillis()}.csv"
writeToFileInDownloads(content, filename)
showSnackbar(getString(R.string.export_saved_file, filename))
- return@launch
} catch (e: Exception) {
Log.e(TAG, "Error saving file", e)
+ showSnackbar(R.string.export_error_saving_file)
}
-
- showSnackbar(R.string.export_error_saving_file)
}
}