From c1cbebd64f96e2a39d34fb899f7dcf0e68920d7c Mon Sep 17 00:00:00 2001 From: MohitMali Date: Fri, 25 Aug 2023 12:33:31 +0530 Subject: [PATCH] Enhanced ZIM file support for Android 10 and above devices, including USB-OTG integration. * Previously we can only open zim files from `USB-OTG` in android 10 and below devices, because `context.getExternalFilesDirs("")` does not provide the USB path in android 10 and above devices for security reasons. There is no direct way to access the USB-OTG on these devices, but USB-OTG are mounted under the `/mnt/media_rw` directory, so now we are directly using this to open zim files from USB drive for android 10 and above devices. --- core/detekt_baseline.xml | 1 + .../kiwixmobile/core/utils/files/FileUtils.kt | 22 +++++++++++++++---- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/core/detekt_baseline.xml b/core/detekt_baseline.xml index ebf17defc..800d1054a 100644 --- a/core/detekt_baseline.xml +++ b/core/detekt_baseline.xml @@ -36,6 +36,7 @@ MaxLineLength:MetaLinkNetworkEntityTest.kt$MetaLinkNetworkEntityTest$"http://www.mirrorservice.org/sites/download.kiwix.org/zim/wikipedia/wikipedia_af_all_nopic_2016-05.zim" MaxLineLength:NetworkUtilsTest.kt$NetworkUtilsTest$// Here the Method should return the substring between the first '?' character and the nearest '/' character preceeding it NestedBlockDepth:FileUtils.kt$FileUtils$@JvmStatic @Synchronized fun deleteZimFile(path: String) + NestedBlockDepth:FileUtils.kt$FileUtils$@JvmStatic fun getLocalFilePathByUri( context: Context, uri: Uri ): String? NestedBlockDepth:ImageUtils.kt$ImageUtils$private fun getBitmapFromView(width: Int, height: Int, viewToDrawFrom: View): Bitmap? NestedBlockDepth:JNIInitialiser.kt$JNIInitialiser$private fun loadICUData(context: Context): String? NestedBlockDepth:OnSwipeTouchListener.kt$OnSwipeTouchListener.GestureListener$override fun onFling( e1: MotionEvent, e2: MotionEvent, velocityX: Float, velocityY: Float ): Boolean diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/utils/files/FileUtils.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/utils/files/FileUtils.kt index 8848cde82..67642e208 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/utils/files/FileUtils.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/utils/files/FileUtils.kt @@ -125,7 +125,12 @@ object FileUtils { return "${Environment.getExternalStorageDirectory()}/${documentId[1]}" } return try { - "${getSdCardMainPath(context, documentId[0])}/${documentId[1]}" + var sdCardOrUsbMainPath = getSdCardOrUSBMainPath(context, documentId[0]) + if (sdCardOrUsbMainPath == null) { + // USB sticks are mounted under the `/mnt/media_rw` directory. + sdCardOrUsbMainPath = "/mnt/media_rw/${documentId[0]}" + } + "$sdCardOrUsbMainPath/${documentId[1]}" } catch (ignore: Exception) { null } @@ -270,11 +275,20 @@ object FileUtils { fun isValidZimFile(filePath: String): Boolean = filePath.endsWith(".zim") || filePath.endsWith(".zimaa") + /** + * Get the main storage path for a given storage name (SD card or USB stick). + * + * @param context The application context. + * @param storageName The name of the storage (e.g., "sdcard" or "usbstick"). + * @return The main storage path for the given storage name, + * or null if the path is a USB path on Android 10 and above + * (due to limitations in `context.getExternalFilesDirs("")` behavior). + */ @JvmStatic - fun getSdCardMainPath(context: Context, storageName: String) = + fun getSdCardOrUSBMainPath(context: Context, storageName: String) = context.getExternalFilesDirs("") - .first { it.path.contains(storageName) } - .path.substringBefore(context.getString(R.string.android_directory_seperator)) + .firstOrNull { it.path.contains(storageName) } + ?.path?.substringBefore(context.getString(R.string.android_directory_seperator)) @SuppressLint("WrongConstant") @JvmStatic