mirror of
https://github.com/kiwix/kiwix-android.git
synced 2025-09-23 12:42:56 -04:00
Merge remote-tracking branch 'origin/Issue#2868' into Issue#2868
This commit is contained in:
commit
c780e1a67d
@ -18,8 +18,10 @@
|
||||
|
||||
package org.kiwix.kiwixmobile.core.main;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import android.webkit.MimeTypeMap;
|
||||
import android.webkit.WebResourceRequest;
|
||||
@ -27,9 +29,12 @@ import android.webkit.WebResourceResponse;
|
||||
import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.content.FileProvider;
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import org.kiwix.kiwixmobile.core.CoreApp;
|
||||
import org.kiwix.kiwixmobile.core.reader.ZimReaderContainer;
|
||||
import org.kiwix.kiwixmobile.core.utils.files.FileUtils;
|
||||
|
||||
import static org.kiwix.kiwixmobile.core.reader.ZimFileReader.CONTENT_PREFIX;
|
||||
import static org.kiwix.kiwixmobile.core.reader.ZimFileReader.UI_URI;
|
||||
@ -97,11 +102,22 @@ public class CoreWebViewClient extends WebViewClient {
|
||||
private boolean handleEpubAndPdf(String url) {
|
||||
String extension = MimeTypeMap.getFileExtensionFromUrl(url);
|
||||
if (DOCUMENT_TYPES.containsKey(extension)) {
|
||||
File savedFile = FileUtils.downloadFileFromUrl(url, null, zimReaderContainer);
|
||||
if (savedFile != null && savedFile.exists()) {
|
||||
Context context = CoreApp.getInstance();
|
||||
Uri uri = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
|
||||
? FileProvider.getUriForFile(
|
||||
context,
|
||||
context.getPackageName() + ".fileprovider", savedFile)
|
||||
: Uri.fromFile(savedFile);
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
Uri uri = Uri.parse(url);
|
||||
intent.setDataAndType(uri, DOCUMENT_TYPES.get(extension));
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
}
|
||||
callback.openExternalUrl(intent);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -20,12 +20,9 @@ package org.kiwix.kiwixmobile.core.main
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import android.os.Environment
|
||||
import android.os.Handler
|
||||
import android.os.Message
|
||||
import android.util.AttributeSet
|
||||
import android.util.Log
|
||||
import android.view.ContextMenu
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
@ -40,8 +37,7 @@ import org.kiwix.kiwixmobile.core.extensions.toast
|
||||
import org.kiwix.kiwixmobile.core.reader.ZimReaderContainer
|
||||
import org.kiwix.kiwixmobile.core.utils.LanguageUtils.Companion.getCurrentLocale
|
||||
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import org.kiwix.kiwixmobile.core.utils.files.FileUtils
|
||||
import javax.inject.Inject
|
||||
|
||||
private const val INITIAL_SCALE = 100
|
||||
@ -147,39 +143,16 @@ open class KiwixWebView @SuppressLint("SetJavaScriptEnabled") constructor(
|
||||
|
||||
internal class SaveHandler(private val zimReaderContainer: ZimReaderContainer) :
|
||||
Handler() {
|
||||
private fun getDecodedFileName(url: String?, src: String?): String =
|
||||
url?.substringAfterLast("/", "")
|
||||
?.takeIf { it.contains(".") }
|
||||
?: src?.substringAfterLast("/", "")
|
||||
?.substringAfterLast("%3A") ?: ""
|
||||
|
||||
@SuppressWarnings("NestedBlockDepth")
|
||||
override fun handleMessage(msg: Message) {
|
||||
val url = msg.data["url"] as? String
|
||||
val src = msg.data["src"] as? String
|
||||
if (url != null || src != null) {
|
||||
val fileName = getDecodedFileName(url, src)
|
||||
var root =
|
||||
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
|
||||
if (instance.externalMediaDirs.isNotEmpty()) {
|
||||
root = instance.externalMediaDirs[0]
|
||||
}
|
||||
val fileToSave = sequence {
|
||||
yield(File(root, fileName))
|
||||
yieldAll(
|
||||
generateSequence(1) { it + 1 }.map {
|
||||
File(root, fileName.replace(".", "_$it."))
|
||||
}
|
||||
)
|
||||
}.first { !it.exists() }
|
||||
val source = Uri.parse(src)
|
||||
try {
|
||||
zimReaderContainer.load("$source", emptyMap()).data.use { inputStream ->
|
||||
fileToSave.outputStream().use { inputStream.copyTo(it) }
|
||||
}
|
||||
instance.toast(instance.getString(R.string.save_media_saved, fileToSave.name))
|
||||
} catch (e: IOException) {
|
||||
Log.w("kiwix", "Couldn't save image", e)
|
||||
val savedFile = FileUtils.downloadFileFromUrl(url, src, zimReaderContainer)
|
||||
savedFile?.let {
|
||||
instance.toast(instance.getString(R.string.save_media_saved, it.name))
|
||||
} ?: run {
|
||||
instance.toast(R.string.save_media_error)
|
||||
}
|
||||
}
|
||||
|
@ -28,11 +28,13 @@ import android.provider.DocumentsContract
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import androidx.documentfile.provider.DocumentFile
|
||||
import org.kiwix.kiwixmobile.core.CoreApp
|
||||
import org.kiwix.kiwixmobile.core.R
|
||||
import org.kiwix.kiwixmobile.core.downloader.ChunkUtils
|
||||
import org.kiwix.kiwixmobile.core.entity.LibraryNetworkEntity.Book
|
||||
import org.kiwix.kiwixmobile.core.extensions.get
|
||||
import org.kiwix.kiwixmobile.core.extensions.toast
|
||||
import org.kiwix.kiwixmobile.core.reader.ZimReaderContainer
|
||||
import java.io.BufferedReader
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
@ -288,4 +290,48 @@ object FileUtils {
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the file name from the url or src. In url it gets the file name from the last '/' and
|
||||
* if it contains '.'. If the url is null then it'll get the file name from the last '/'.
|
||||
* If the url and src doesn't exist it returns the empty string.
|
||||
*/
|
||||
fun getDecodedFileName(url: String?, src: String?): String =
|
||||
url?.substringAfterLast("/", "")
|
||||
?.takeIf { it.contains(".") }
|
||||
?: src?.substringAfterLast("/", "")
|
||||
?.substringAfterLast("%3A") ?: ""
|
||||
|
||||
@JvmStatic fun downloadFileFromUrl(
|
||||
url: String?,
|
||||
src: String?,
|
||||
zimReaderContainer: ZimReaderContainer
|
||||
): File? {
|
||||
val fileName = getDecodedFileName(url, src)
|
||||
var root =
|
||||
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
|
||||
if (CoreApp.instance.externalMediaDirs.isNotEmpty()) {
|
||||
root = CoreApp.instance.externalMediaDirs[0]
|
||||
}
|
||||
val fileToSave = sequence {
|
||||
yield(File(root, fileName))
|
||||
yieldAll(
|
||||
generateSequence(1) { it + 1 }.map {
|
||||
File(
|
||||
root, fileName.replace(".", "_$it.")
|
||||
)
|
||||
}
|
||||
)
|
||||
}.first { !it.exists() }
|
||||
val source = if (url == null) Uri.parse(src) else Uri.parse(url)
|
||||
return try {
|
||||
zimReaderContainer.load("$source", emptyMap()).data.use { inputStream ->
|
||||
fileToSave.outputStream().use { inputStream.copyTo(it) }
|
||||
}
|
||||
fileToSave
|
||||
} catch (e: IOException) {
|
||||
Log.w("kiwix", "Couldn't save file", e)
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -88,4 +88,44 @@ class FileUtilsTest {
|
||||
every { mockFile.path } returns "$fileName$extension"
|
||||
every { mockFile.exists() } returns fileExists
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test decode file name`() {
|
||||
val fileName =
|
||||
FileUtils.getDecodedFileName(
|
||||
url = "https://kiwix.org/contributors/contributors_list.pdf",
|
||||
src = null
|
||||
)
|
||||
assertThat(fileName).isEqualTo("contributors_list.pdf")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test file name if extension doesn't exist`() {
|
||||
val fileName = FileUtils.getDecodedFileName(url = "https://kiwix.org/contributors/", src = null)
|
||||
assertThat(fileName).isEqualTo("")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test file name if the url and src doesn't exist`() {
|
||||
val fileName = FileUtils.getDecodedFileName(url = null, src = null)
|
||||
assertThat(fileName).isEqualTo("")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test file name if only file name exist`() {
|
||||
val fileName = FileUtils.getDecodedFileName(src = "android_tutorials.pdf", url = null)
|
||||
assertThat(fileName).isEqualTo("")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test file name if url doesn't exist`() {
|
||||
val fileName = FileUtils.getDecodedFileName(url = null, src = "/html/images/test.png")
|
||||
assertThat(fileName).isEqualTo("test.png")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test file name if url and src's extension doesn't exist`() {
|
||||
val fileName = FileUtils.getDecodedFileName(url = null, src = "/html/images/")
|
||||
assertThat(fileName).isEqualTo("")
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user