cherry pick 3.0.4

This commit is contained in:
Sean Mac Gillicuddy 2019-10-01 16:11:43 +01:00
parent 11db4504f9
commit 8b8764adbe
7 changed files with 79 additions and 60 deletions

View File

@ -1,3 +1,9 @@
3.0.4
BUGFIX: Some users language was causing a crash due to unstable ISO codes
BUGFIX: Some unstable zim files were crashing when opened
BUGFIX: Long titles were rendering off screen on home page
BUGFIX: Issues when opening a file externally
3.0.0 3.0.0
NEW: Androidx support NEW: Androidx support
NEW: In app error reporting NEW: In app error reporting

View File

@ -29,7 +29,7 @@ def buildNumber = System.getenv('TRAVIS_BUILD_NUMBER') ?: "dev"
ext { ext {
versionMajor = 3 versionMajor = 3
versionMinor = 0 versionMinor = 0
versionPatch = 3 versionPatch = 4
} }
private String generateVersionName() { private String generateVersionName() {
@ -260,5 +260,4 @@ dependencies {
// RxJava // RxJava
implementation(Libs.rxandroid) implementation(Libs.rxandroid)
implementation(Libs.rxjava) implementation(Libs.rxjava)
} }

View File

@ -1,13 +1,4 @@
NEW: Androidx support BUGFIX: Some users language was causing a crash due to unstable ISO codes
NEW: In app error reporting BUGFIX: Some unstable zim files were crashing when opened
NEW: Improved bookmarks BUGFIX: Long titles were rendering off screen on home page
NEW: Help screen BUGFIX: Issues when opening a file externally
NEW: Home page
NEW: Zim history
NEW: Introductory screen
NEW: Improved language selection
NEW: Add note to articles
NEW: Tabs
NEW: Share zim files to other Kiwix users
NEW: Host zim files on your phone
+ Bugfixes & Lots More

View File

@ -99,6 +99,7 @@ import org.kiwix.kiwixmobile.core.R2;
import org.kiwix.kiwixmobile.core.base.BaseActivity; import org.kiwix.kiwixmobile.core.base.BaseActivity;
import org.kiwix.kiwixmobile.core.bookmark.BookmarkItem; import org.kiwix.kiwixmobile.core.bookmark.BookmarkItem;
import org.kiwix.kiwixmobile.core.bookmark.BookmarksActivity; import org.kiwix.kiwixmobile.core.bookmark.BookmarksActivity;
import org.kiwix.kiwixmobile.core.extensions.ContextExtensionsKt;
import org.kiwix.kiwixmobile.core.help.HelpActivity; import org.kiwix.kiwixmobile.core.help.HelpActivity;
import org.kiwix.kiwixmobile.core.history.HistoryActivity; import org.kiwix.kiwixmobile.core.history.HistoryActivity;
import org.kiwix.kiwixmobile.core.history.HistoryListItem; import org.kiwix.kiwixmobile.core.history.HistoryListItem;
@ -1067,24 +1068,26 @@ public class MainActivity extends BaseActivity implements WebViewCallback,
&& Build.VERSION.SDK_INT != 23)) { && Build.VERSION.SDK_INT != 23)) {
if (file.exists()) { if (file.exists()) {
zimReaderContainer.setZimFile(file); zimReaderContainer.setZimFile(file);
if (clearHistory) { if (zimReaderContainer.getZimFileReader() != null) {
requestClearHistoryAfterLoad = true; if (clearHistory) {
} requestClearHistoryAfterLoad = true;
if (menu != null) { }
initAllMenuItems(); if (menu != null) {
initAllMenuItems();
} else {
// Menu may not be initialized yet. In this case
// signal to menu create to show
requestInitAllMenuItems = true;
}
openMainPage();
presenter.loadCurrentZimBookmarksUrl();
} else { } else {
// Menu may not be initialized yet. In this case ContextExtensionsKt.toast(this, R.string.error_file_invalid, Toast.LENGTH_LONG);
// signal to menu create to show showHomePage();
requestInitAllMenuItems = true;
} }
openMainPage();
presenter.loadCurrentZimBookmarksUrl();
} else { } else {
Log.w(TAG_KIWIX, "ZIM file doesn't exist at " + file.getAbsolutePath()); Log.w(TAG_KIWIX, "ZIM file doesn't exist at " + file.getAbsolutePath());
ContextExtensionsKt.toast(this, R.string.error_file_not_found, Toast.LENGTH_LONG);
Toast.makeText(this, getResources().getString(R.string.error_file_not_found),
Toast.LENGTH_LONG)
.show();
showHomePage(); showHomePage();
} }
} else { } else {
@ -1638,7 +1641,7 @@ public class MainActivity extends BaseActivity implements WebViewCallback,
toggleActionItemsConfig(); toggleActionItemsConfig();
this.menu = menu; this.menu = menu;
if (tabSwitcherRoot.getVisibility() == View.VISIBLE) { if (tabSwitcherRoot != null && tabSwitcherRoot.getVisibility() == View.VISIBLE) {
menu.findItem(R.id.menu_search).setVisible(false); menu.findItem(R.id.menu_search).setVisible(false);
menu.findItem(R.id.menu_fullscreen).setVisible(false); menu.findItem(R.id.menu_fullscreen).setVisible(false);
menu.findItem(R.id.menu_random_article).setVisible(false); menu.findItem(R.id.menu_random_article).setVisible(false);

View File

@ -17,10 +17,12 @@
*/ */
package org.kiwix.kiwixmobile.core.utils.files package org.kiwix.kiwixmobile.core.utils.files
import android.annotation.TargetApi
import android.content.ContentUris import android.content.ContentUris
import android.content.Context import android.content.Context
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
import android.os.Build.VERSION_CODES
import android.os.Environment import android.os.Environment
import android.provider.DocumentsContract import android.provider.DocumentsContract
import android.util.Log import android.util.Log
@ -40,15 +42,15 @@ object FileUtils {
"${Environment.getExternalStorageDirectory()}${File.separator}Android" + "${Environment.getExternalStorageDirectory()}${File.separator}Android" +
"${File.separator}obb${File.separator}${KiwixApplication.getInstance().packageName}" "${File.separator}obb${File.separator}${KiwixApplication.getInstance().packageName}"
@JvmStatic fun getFileCacheDir(context: Context): File = @JvmStatic fun getFileCacheDir(context: Context): File? =
if (Environment.MEDIA_MOUNTED == Environment.getExternalStorageState()) { if (Environment.MEDIA_MOUNTED == Environment.getExternalStorageState()) {
context.externalCacheDir!! context.externalCacheDir
} else { } else {
context.cacheDir context.cacheDir
} }
@JvmStatic @Synchronized fun deleteCachedFiles(context: Context) { @JvmStatic @Synchronized fun deleteCachedFiles(context: Context) {
getFileCacheDir(context).deleteRecursively() getFileCacheDir(context)?.deleteRecursively()
} }
@JvmStatic @Synchronized fun deleteZimFile(path: String) { @JvmStatic @Synchronized fun deleteZimFile(path: String) {
@ -147,12 +149,12 @@ object FileUtils {
} }
@JvmStatic fun getLocalFilePathByUri( @JvmStatic fun getLocalFilePathByUri(
ctx: Context, context: Context,
uri: Uri uri: Uri
): String? { ): String? {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT &&
DocumentsContract.isDocumentUri(ctx, uri) DocumentsContract.isDocumentUri(context, uri)
) { ) {
if ("com.android.externalstorage.documents" == uri.authority) { if ("com.android.externalstorage.documents" == uri.authority) {
val documentId = DocumentsContract.getDocumentId(uri) val documentId = DocumentsContract.getDocumentId(uri)
@ -161,38 +163,49 @@ object FileUtils {
if (documentId[0] == "primary") { if (documentId[0] == "primary") {
return "${Environment.getExternalStorageDirectory()}/${documentId[1]}" return "${Environment.getExternalStorageDirectory()}/${documentId[1]}"
} }
} else if ("com.android.providers.downloads.documents" == uri.authority } else if ("com.android.providers.downloads.documents" == uri.authority)
) return try {
return contentQuery( documentProviderContentQuery(context, uri)
ctx, } catch (ignore: IllegalArgumentException) {
ContentUris.withAppendedId( null
Uri.parse("content://downloads/public_downloads"), }
try {
DocumentsContract.getDocumentId(uri).toLong()
} catch (ignore: NumberFormatException) {
0L
}
)
)
} else if ("content".equals(uri.scheme!!, ignoreCase = true)) { } else if ("content".equals(uri.scheme!!, ignoreCase = true)) {
return contentQuery(ctx, uri) return contentQuery(context, uri)
} else if ("file".equals(uri.scheme!!, ignoreCase = true)) { } else if ("file".equals(uri.scheme!!, ignoreCase = true)) {
return uri.path return uri.path
} }
return null return null
} }
@TargetApi(VERSION_CODES.KITKAT)
private fun documentProviderContentQuery(context: Context, uri: Uri) =
contentQuery(
context,
ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"),
try {
DocumentsContract.getDocumentId(uri).toLong()
} catch (ignore: NumberFormatException) {
0L
}
)
)
private fun contentQuery( private fun contentQuery(
context: Context, context: Context,
uri: Uri uri: Uri
): String? { ): String? {
val columnName = "_data" val columnName = "_data"
return context.contentResolver.query(uri, arrayOf(columnName), null, null, null) return try {
?.use { context.contentResolver.query(uri, arrayOf(columnName), null, null, null)
if (it.moveToFirst() && it.getColumnIndex(columnName) != -1) { ?.use {
it[columnName] if (it.moveToFirst() && it.getColumnIndex(columnName) != -1) {
} else null it[columnName]
} } else null
}
} catch (ignore: SecurityException) {
null
}
} }
@JvmStatic fun readLocalesFromAssets(context: Context) = @JvmStatic fun readLocalesFromAssets(context: Context) =

View File

@ -26,6 +26,7 @@ import android.webkit.MimeTypeMap
import androidx.core.net.toUri import androidx.core.net.toUri
import io.reactivex.Single import io.reactivex.Single
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
import org.kiwix.kiwixlib.JNIKiwixException
import org.kiwix.kiwixlib.JNIKiwixInt import org.kiwix.kiwixlib.JNIKiwixInt
import org.kiwix.kiwixlib.JNIKiwixReader import org.kiwix.kiwixlib.JNIKiwixReader
import org.kiwix.kiwixlib.JNIKiwixString import org.kiwix.kiwixlib.JNIKiwixString
@ -50,11 +51,15 @@ class ZimFileReader(
private val sharedPreferenceUtil: SharedPreferenceUtil private val sharedPreferenceUtil: SharedPreferenceUtil
) { ) {
interface Factory { interface Factory {
fun create(file: File): ZimFileReader fun create(file: File): ZimFileReader?
class Impl @Inject constructor(val sharedPreferenceUtil: SharedPreferenceUtil) : Factory { class Impl @Inject constructor(val sharedPreferenceUtil: SharedPreferenceUtil) : Factory {
override fun create(file: File) = override fun create(file: File) =
ZimFileReader(file, sharedPreferenceUtil = sharedPreferenceUtil) try {
ZimFileReader(file, sharedPreferenceUtil = sharedPreferenceUtil)
} catch (ignore: JNIKiwixException) {
null
}
} }
} }

View File

@ -18,6 +18,7 @@
package org.kiwix.kiwixmobile.core.zim_manager.fileselect_view package org.kiwix.kiwixmobile.core.zim_manager.fileselect_view
import io.reactivex.Flowable
import io.reactivex.functions.BiFunction import io.reactivex.functions.BiFunction
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
import org.kiwix.kiwixmobile.core.downloader.model.DownloadModel import org.kiwix.kiwixmobile.core.downloader.model.DownloadModel
@ -34,10 +35,10 @@ class StorageObserver @Inject constructor(
private val zimReaderFactory: ZimFileReader.Factory private val zimReaderFactory: ZimFileReader.Factory
) { ) {
val booksOnFileSystem val booksOnFileSystem: Flowable<List<BookOnDisk>>
get() = scanFiles() get() = scanFiles()
.withLatestFrom(downloadDao.downloads(), BiFunction(::toFilesThatAreNotDownloading)) .withLatestFrom(downloadDao.downloads(), BiFunction(::toFilesThatAreNotDownloading))
.map { it.map(::convertToBookOnDisk) } .map { it.mapNotNull(::convertToBookOnDisk) }
private fun scanFiles() = fileSearch.scan().subscribeOn(Schedulers.io()) private fun scanFiles() = fileSearch.scan().subscribeOn(Schedulers.io())
@ -47,5 +48,6 @@ class StorageObserver @Inject constructor(
private fun fileHasNoMatchingDownload(downloads: List<DownloadModel>, file: File) = private fun fileHasNoMatchingDownload(downloads: List<DownloadModel>, file: File) =
downloads.firstOrNull { file.absolutePath.endsWith(it.fileNameFromUrl) } == null downloads.firstOrNull { file.absolutePath.endsWith(it.fileNameFromUrl) } == null
private fun convertToBookOnDisk(file: File) = BookOnDisk(file, zimReaderFactory.create(file)) private fun convertToBookOnDisk(file: File) =
zimReaderFactory.create(file)?.let { BookOnDisk(file, it) }
} }