mirror of
https://github.com/kiwix/kiwix-android.git
synced 2025-09-24 05:04:50 -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;
|
package org.kiwix.kiwixmobile.core.main;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.webkit.MimeTypeMap;
|
import android.webkit.MimeTypeMap;
|
||||||
import android.webkit.WebResourceRequest;
|
import android.webkit.WebResourceRequest;
|
||||||
@ -27,9 +29,12 @@ import android.webkit.WebResourceResponse;
|
|||||||
import android.webkit.WebView;
|
import android.webkit.WebView;
|
||||||
import android.webkit.WebViewClient;
|
import android.webkit.WebViewClient;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.core.content.FileProvider;
|
||||||
|
import java.io.File;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import org.kiwix.kiwixmobile.core.CoreApp;
|
import org.kiwix.kiwixmobile.core.CoreApp;
|
||||||
import org.kiwix.kiwixmobile.core.reader.ZimReaderContainer;
|
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.CONTENT_PREFIX;
|
||||||
import static org.kiwix.kiwixmobile.core.reader.ZimFileReader.UI_URI;
|
import static org.kiwix.kiwixmobile.core.reader.ZimFileReader.UI_URI;
|
||||||
@ -97,11 +102,22 @@ public class CoreWebViewClient extends WebViewClient {
|
|||||||
private boolean handleEpubAndPdf(String url) {
|
private boolean handleEpubAndPdf(String url) {
|
||||||
String extension = MimeTypeMap.getFileExtensionFromUrl(url);
|
String extension = MimeTypeMap.getFileExtensionFromUrl(url);
|
||||||
if (DOCUMENT_TYPES.containsKey(extension)) {
|
if (DOCUMENT_TYPES.containsKey(extension)) {
|
||||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
File savedFile = FileUtils.downloadFileFromUrl(url, null, zimReaderContainer);
|
||||||
Uri uri = Uri.parse(url);
|
if (savedFile != null && savedFile.exists()) {
|
||||||
intent.setDataAndType(uri, DOCUMENT_TYPES.get(extension));
|
Context context = CoreApp.getInstance();
|
||||||
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
|
Uri uri = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
|
||||||
callback.openExternalUrl(intent);
|
? FileProvider.getUriForFile(
|
||||||
|
context,
|
||||||
|
context.getPackageName() + ".fileprovider", savedFile)
|
||||||
|
: Uri.fromFile(savedFile);
|
||||||
|
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||||
|
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 true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -20,12 +20,9 @@ package org.kiwix.kiwixmobile.core.main
|
|||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.net.Uri
|
|
||||||
import android.os.Environment
|
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Message
|
import android.os.Message
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.util.Log
|
|
||||||
import android.view.ContextMenu
|
import android.view.ContextMenu
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
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.reader.ZimReaderContainer
|
||||||
import org.kiwix.kiwixmobile.core.utils.LanguageUtils.Companion.getCurrentLocale
|
import org.kiwix.kiwixmobile.core.utils.LanguageUtils.Companion.getCurrentLocale
|
||||||
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
|
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
|
||||||
import java.io.File
|
import org.kiwix.kiwixmobile.core.utils.files.FileUtils
|
||||||
import java.io.IOException
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
private const val INITIAL_SCALE = 100
|
private const val INITIAL_SCALE = 100
|
||||||
@ -147,39 +143,16 @@ open class KiwixWebView @SuppressLint("SetJavaScriptEnabled") constructor(
|
|||||||
|
|
||||||
internal class SaveHandler(private val zimReaderContainer: ZimReaderContainer) :
|
internal class SaveHandler(private val zimReaderContainer: ZimReaderContainer) :
|
||||||
Handler() {
|
Handler() {
|
||||||
private fun getDecodedFileName(url: String?, src: String?): String =
|
|
||||||
url?.substringAfterLast("/", "")
|
|
||||||
?.takeIf { it.contains(".") }
|
|
||||||
?: src?.substringAfterLast("/", "")
|
|
||||||
?.substringAfterLast("%3A") ?: ""
|
|
||||||
|
|
||||||
@SuppressWarnings("NestedBlockDepth")
|
@SuppressWarnings("NestedBlockDepth")
|
||||||
override fun handleMessage(msg: Message) {
|
override fun handleMessage(msg: Message) {
|
||||||
val url = msg.data["url"] as? String
|
val url = msg.data["url"] as? String
|
||||||
val src = msg.data["src"] as? String
|
val src = msg.data["src"] as? String
|
||||||
if (url != null || src != null) {
|
if (url != null || src != null) {
|
||||||
val fileName = getDecodedFileName(url, src)
|
val savedFile = FileUtils.downloadFileFromUrl(url, src, zimReaderContainer)
|
||||||
var root =
|
savedFile?.let {
|
||||||
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
|
instance.toast(instance.getString(R.string.save_media_saved, it.name))
|
||||||
if (instance.externalMediaDirs.isNotEmpty()) {
|
} ?: run {
|
||||||
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)
|
|
||||||
instance.toast(R.string.save_media_error)
|
instance.toast(R.string.save_media_error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,11 +28,13 @@ import android.provider.DocumentsContract
|
|||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.documentfile.provider.DocumentFile
|
import androidx.documentfile.provider.DocumentFile
|
||||||
|
import org.kiwix.kiwixmobile.core.CoreApp
|
||||||
import org.kiwix.kiwixmobile.core.R
|
import org.kiwix.kiwixmobile.core.R
|
||||||
import org.kiwix.kiwixmobile.core.downloader.ChunkUtils
|
import org.kiwix.kiwixmobile.core.downloader.ChunkUtils
|
||||||
import org.kiwix.kiwixmobile.core.entity.LibraryNetworkEntity.Book
|
import org.kiwix.kiwixmobile.core.entity.LibraryNetworkEntity.Book
|
||||||
import org.kiwix.kiwixmobile.core.extensions.get
|
import org.kiwix.kiwixmobile.core.extensions.get
|
||||||
import org.kiwix.kiwixmobile.core.extensions.toast
|
import org.kiwix.kiwixmobile.core.extensions.toast
|
||||||
|
import org.kiwix.kiwixmobile.core.reader.ZimReaderContainer
|
||||||
import java.io.BufferedReader
|
import java.io.BufferedReader
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
@ -288,4 +290,48 @@ object FileUtils {
|
|||||||
}
|
}
|
||||||
return null
|
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.path } returns "$fileName$extension"
|
||||||
every { mockFile.exists() } returns fileExists
|
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