Fixed: Download zim files in Android/media/org.kiwix/kiwixmobile/ folder instead of internal app-specific directory.

* Now all the downloading files will store in this public app-specific directory.
* Refactored the code to show this new location in storageSelection dialog for both internal and external storage.
* Updated the `README.md` file to educate user that how they can read already downloaded zim files in PS version.
* Refactored the test cases according to this change.
This commit is contained in:
MohitMaliFtechiz 2024-07-16 18:57:48 +05:30
parent a6de67e6de
commit 34618aec05
5 changed files with 24 additions and 10 deletions

View File

@ -28,7 +28,11 @@ Play Store policies. The Play Store variant of Kiwix does not require
the `MANAGE_EXTERNAL_STORAGE` permission anymore, which is necessary
to scan storage and access ZIM files at arbitrary locations.
Therefore, the storage scanning & file picking functionalities are not
available in this variant anymore. To use the full version of Kiwix
available in this variant anymore. For already downloaded ZIM files, You can copy
them to the `Android/media/org.kiwix.kiwixmobile/` folder, and the application will read them.
Before uninstalling the application, please ensure that you move all your ZIM files
from this folder, as they will be automatically deleted when the application is uninstalled
or if the application data is cleared. To use the full version of Kiwix
and benefit of the ZIM file picker feature, you can download it
directly from the [official
repository](https://download.kiwix.org/release/kiwix-android/) or use

View File

@ -19,6 +19,7 @@
package eu.mhutti1.utils.storage
import android.content.Context
import android.content.ContextWrapper
import android.os.Environment
import androidx.core.content.ContextCompat
import java.io.File
@ -28,7 +29,8 @@ import java.util.ArrayList
object StorageDeviceUtils {
@JvmStatic
fun getWritableStorage(context: Context) = validate(externalFilesDirsDevices(context, true), true)
fun getWritableStorage(context: Context) =
validate(externalMediaFilesDirsDevices(context), true)
@JvmStatic
fun getReadableStorage(context: Context): List<StorageDevice> {
@ -36,6 +38,7 @@ object StorageDeviceUtils {
add(environmentDevices(context))
addAll(externalMountPointDevices())
addAll(externalFilesDirsDevices(context, false))
addAll(externalMediaFilesDirsDevices(context))
// Scan the app-specific directory as well because we have limitations in scanning
// all directories on Android 11 and above in the Play Store variant.
// If a user copies the ZIM file to the app-specific directory on the SD card,
@ -55,6 +58,12 @@ object StorageDeviceUtils {
.filterNotNull()
.mapIndexed { index, dir -> StorageDevice(generalisePath(dir.path, writable), index == 0) }
private fun externalMediaFilesDirsDevices(
context: Context
) = ContextWrapper(context).externalMediaDirs
.filterNotNull()
.mapIndexed { index, dir -> StorageDevice(generalisePath(dir.path, true), index == 0) }
private fun externalMountPointDevices(): Collection<StorageDevice> =
ExternalPaths.possiblePaths.fold(mutableListOf(), { acc, path ->
acc.apply {

View File

@ -18,6 +18,7 @@
package org.kiwix.kiwixmobile.core.utils
import android.content.Context
import android.content.ContextWrapper
import android.content.SharedPreferences
import android.os.Build
import androidx.appcompat.app.AppCompatDelegate
@ -106,12 +107,12 @@ class SharedPreferenceUtil @Inject constructor(val context: Context) {
get() {
val storage = sharedPreferences.getString(PREF_STORAGE, null)
return when {
storage == null -> getPublicDirectoryPath(defaultStorage()).also {
storage == null -> getPublicDirectoryPath(defaultPublicStorage()).also {
putPrefStorage(it)
putStoragePosition(0)
}
!File(storage).isFileExist() -> getPublicDirectoryPath(defaultStorage()).also {
!File(storage).isFileExist() -> getPublicDirectoryPath(defaultPublicStorage()).also {
putStoragePosition(0)
}
@ -126,6 +127,10 @@ class SharedPreferenceUtil @Inject constructor(val context: Context) {
getExternalFilesDirs(context, null)[0]?.path
?: context.filesDir.path // a workaround for emulators
fun defaultPublicStorage(): String =
ContextWrapper(context).externalMediaDirs[0]?.path
?: context.filesDir.path // a workaround for emulators
fun getPrefStorageTitle(defaultTitle: String): String =
sharedPreferences.getString(PREF_STORAGE_TITLE, defaultTitle) ?: defaultTitle

View File

@ -19,7 +19,6 @@
package org.kiwix.kiwixmobile.custom.download.effects
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import org.kiwix.kiwixmobile.core.base.SideEffect
import org.kiwix.kiwixmobile.core.settings.StorageCalculator
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
@ -30,7 +29,7 @@ class SetPreferredStorageWithMostSpace @Inject constructor(
private val sharedPreferenceUtil: SharedPreferenceUtil
) : SideEffect<Unit> {
override fun invokeWith(activity: AppCompatActivity) {
ContextCompat.getExternalFilesDirs(activity, null)
activity.externalMediaDirs
.filterNotNull()
.maxBy(storageCalculator::availableBytes)
?.let { sharedPreferenceUtil.putPrefStorage(it.path) }

View File

@ -19,10 +19,8 @@
package org.kiwix.kiwixmobile.custom.download.effects
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import io.mockk.every
import io.mockk.mockk
import io.mockk.mockkStatic
import io.mockk.verify
import org.junit.jupiter.api.Test
import org.kiwix.kiwixmobile.core.settings.StorageCalculator
@ -36,10 +34,9 @@ internal class SetPreferredStorageWithMostSpaceTest {
val storageCalculator = mockk<StorageCalculator>()
val sharedPreferenceUtil = mockk<SharedPreferenceUtil>()
val activity = mockk<AppCompatActivity>()
mockkStatic(ContextCompat::class)
val directoryWithMoreStorage = mockk<File>()
val directoryWithLessStorage = mockk<File>()
every { ContextCompat.getExternalFilesDirs(activity, null) } returns arrayOf(
every { activity.externalMediaDirs } returns arrayOf(
directoryWithMoreStorage, null, directoryWithLessStorage
)
every { storageCalculator.availableBytes(directoryWithMoreStorage) } returns 1