Skip to content

Commit

Permalink
Fixed, I can't open Zim from an external download.
Browse files Browse the repository at this point in the history
* We are now using fileDescriptor to open the zim files with uris when someone tries to open the zim file directly from storage.
* As now we are using the assetFileDescriptor instead of direct files, we have refactored the functionality of saving (note, history, bookmark) so that we can open the same pages on the same zimFile.
  • Loading branch information
MohitMaliDeveloper committed Nov 16, 2023
1 parent 3716b72 commit f6b01a4
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ import org.kiwix.kiwixmobile.core.utils.TAG_CURRENT_FILE
import org.kiwix.kiwixmobile.core.utils.TAG_FILE_SEARCHED
import org.kiwix.kiwixmobile.core.utils.TAG_KIWIX
import org.kiwix.kiwixmobile.core.utils.files.FileUtils
import org.kiwix.kiwixmobile.core.utils.files.FileUtils.getAssetFileDescriptorFromUri
import org.kiwix.kiwixmobile.core.utils.titleToUrl
import org.kiwix.kiwixmobile.core.utils.urlSuffixToParsableUrl
import java.io.File
Expand Down Expand Up @@ -230,7 +231,9 @@ class KiwixReaderFragment : CoreReaderFragment() {

override fun onResume() {
super.onResume()
if (zimReaderContainer?.zimFile == null) {
if (zimReaderContainer?.zimFile == null &&
zimReaderContainer?.zimFileReader?.assetFileDescriptor == null
) {
exitBook()
}
if (isFullScreenVideo) {
Expand Down Expand Up @@ -316,8 +319,20 @@ class KiwixReaderFragment : CoreReaderFragment() {
): Super {
super.onNewIntent(activity.intent, activity)
intent.data?.let {
if ("file" == it.scheme) openZimFile(it.toFile())
else activity.toast(R.string.cannot_open_file)
when (it.scheme) {
"file" -> openZimFile(it.toFile())
"content" -> {
// pass this uri to zimFileReader, which is necessary for saving
// notes, bookmarks, history, and reopening the same ZIM file after the app closes.
getAssetFileDescriptorFromUri(activity, it)?.let { assetFileDescriptor ->
openZimFile(null, assetFileDescriptor = assetFileDescriptor, filePath = "$it")
} ?: kotlin.run {
activity.toast(R.string.cannot_open_file)
}
}

else -> activity.toast(R.string.cannot_open_file)
}
}
return ShouldCall
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1390,14 +1390,18 @@ abstract class CoreReaderFragment :
protected fun openZimFile(
file: File?,
isCustomApp: Boolean = false,
assetFileDescriptor: AssetFileDescriptor? = null
assetFileDescriptor: AssetFileDescriptor? = null,
filePath: String? = null
) {
if (hasPermission(Manifest.permission.READ_EXTERNAL_STORAGE) || isCustomApp) {
if (file?.isFileExist() == true) {
openAndSetInContainer(file = file)
updateTitle()
} else if (assetFileDescriptor != null) {
openAndSetInContainer(assetFileDescriptor = assetFileDescriptor)
openAndSetInContainer(
assetFileDescriptor = assetFileDescriptor,
filePath = filePath
)
updateTitle()
} else {
Log.w(TAG_KIWIX, "ZIM file doesn't exist at " + file?.absolutePath)
Expand Down Expand Up @@ -1429,7 +1433,8 @@ abstract class CoreReaderFragment :

private fun openAndSetInContainer(
file: File? = null,
assetFileDescriptor: AssetFileDescriptor? = null
assetFileDescriptor: AssetFileDescriptor? = null,
filePath: String? = null
) {
try {
if (isNotPreviouslyOpenZim(file?.canonicalPath)) {
Expand All @@ -1440,7 +1445,10 @@ abstract class CoreReaderFragment :
}
zimReaderContainer?.let { zimReaderContainer ->
if (assetFileDescriptor != null) {
zimReaderContainer.setZimFileDescriptor(assetFileDescriptor)
zimReaderContainer.setZimFileDescriptor(
assetFileDescriptor,
filePath = filePath
)
} else {
zimReaderContainer.setZimFile(file)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ data class BookmarkItem(
) : this(
zimId = zimFileReader.id,
zimName = zimFileReader.name,
zimFilePath = zimFileReader.zimFile?.canonicalPath,
zimFilePath = zimFileReader.zimFile?.canonicalPath ?: zimFileReader.assetDescriptorFilePath,
bookmarkUrl = url,
title = title,
favicon = zimFileReader.favicon
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ sealed class HistoryListItem : PageRelated {
) : this(
zimId = zimFileReader.id,
zimName = zimFileReader.name,
zimFilePath = zimFileReader.zimFile?.canonicalPath ?: "",
zimFilePath = zimFileReader.zimFile?.canonicalPath
?: zimFileReader.assetDescriptorFilePath
?: "",
favicon = zimFileReader.favicon,
historyUrl = url,
title = title,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ data class NoteListItem(
) : this(
zimId = zimFileReader.id,
title = title,
zimFilePath = zimFileReader.zimFile?.canonicalPath,
zimFilePath = zimFileReader.zimFile?.canonicalPath ?: zimFileReader.assetDescriptorFilePath,
zimUrl = url,
favicon = zimFileReader.favicon,
noteFilePath = noteFilePath
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,21 @@ import javax.inject.Inject

private const val TAG = "ZimFileReader"

@Suppress("LongParameterList")
class ZimFileReader constructor(
val zimFile: File?,
val assetFileDescriptor: AssetFileDescriptor? = null,
val assetDescriptorFilePath: String? = null,
private val jniKiwixReader: Archive,
private val nightModeConfig: NightModeConfig,
private val searcher: SuggestionSearcher = SuggestionSearcher(jniKiwixReader)
) {
interface Factory {
fun create(file: File): ZimFileReader?
fun create(assetFileDescriptor: AssetFileDescriptor): ZimFileReader?
fun create(
assetFileDescriptor: AssetFileDescriptor,
filePath: String? = null
): ZimFileReader?

class Impl @Inject constructor(private val nightModeConfig: NightModeConfig) :
Factory {
Expand All @@ -79,11 +84,15 @@ class ZimFileReader constructor(
null
}

override fun create(assetFileDescriptor: AssetFileDescriptor): ZimFileReader? =
override fun create(
assetFileDescriptor: AssetFileDescriptor,
filePath: String?
): ZimFileReader? =
try {
ZimFileReader(
null,
assetFileDescriptor,
assetDescriptorFilePath = filePath,
nightModeConfig = nightModeConfig,
jniKiwixReader = Archive(
assetFileDescriptor.parcelFileDescriptor.dup().fileDescriptor,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,13 @@ class ZimReaderContainer @Inject constructor(private val zimFileReaderFactory: F
else null
}

fun setZimFileDescriptor(assetFileDescriptor: AssetFileDescriptor) {
fun setZimFileDescriptor(
assetFileDescriptor: AssetFileDescriptor,
filePath: String? = null
) {
zimFileReader =
if (assetFileDescriptor.parcelFileDescriptor.dup().fileDescriptor.valid())
zimFileReaderFactory.create(assetFileDescriptor)
zimFileReaderFactory.create(assetFileDescriptor, filePath)
else null
}

Expand Down Expand Up @@ -84,7 +87,11 @@ class ZimReaderContainer @Inject constructor(private val zimFileReaderFactory: F

val zimFile get() = zimFileReader?.zimFile

val zimCanonicalPath get() = zimFileReader?.zimFile?.canonicalPath
/**
* Return the zimFile path if opened from file else return the filePath of assetFileDescriptor
*/
val zimCanonicalPath
get() = zimFileReader?.zimFile?.canonicalPath ?: zimFileReader?.assetDescriptorFilePath
val zimFileTitle get() = zimFileReader?.title
val mainPage get() = zimFileReader?.mainPage
val id get() = zimFileReader?.id
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import android.app.Activity
import android.content.ContentUris
import android.content.Context
import android.content.Intent
import android.content.res.AssetFileDescriptor
import android.net.Uri
import android.os.Build
import android.os.Environment
Expand All @@ -46,6 +47,7 @@ import org.kiwix.kiwixmobile.core.reader.ZimReaderContainer
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
import java.io.BufferedReader
import java.io.File
import java.io.FileNotFoundException
import java.io.IOException

object FileUtils {
Expand Down Expand Up @@ -407,4 +409,16 @@ object FileUtils {
@JvmStatic
fun getDemoFilePathForCustomApp(context: Context) =
"${ContextCompat.getExternalFilesDirs(context, null)[0]}/demo.zim"

@JvmStatic
fun getAssetFileDescriptorFromUri(
context: Context,
uri: Uri
): AssetFileDescriptor? {
return try {
context.contentResolver.openAssetFileDescriptor(uri, "r")
} catch (ignore: FileNotFoundException) {
null
}
}
}

0 comments on commit f6b01a4

Please sign in to comment.