mirror of
https://github.com/kiwix/kiwix-android.git
synced 2025-08-03 18:56:44 -04:00
a) Directory changed from app specific to public now its sharable. b) Library androidx document addition c) this resolve issue file deleting after uninstall the app d) this also resolve bug related to zim file not able to load from app specific folder in android 10 and above.
This commit is contained in:
parent
d25929a78a
commit
16f3dd2e64
@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
package org.kiwix.kiwixmobile.nav.destination.library
|
package org.kiwix.kiwixmobile.nav.destination.library
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.app.Activity
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.ConnectivityManager
|
import android.net.ConnectivityManager
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
@ -31,6 +33,7 @@ import android.view.ViewGroup
|
|||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.appcompat.widget.SearchView
|
import androidx.appcompat.widget.SearchView
|
||||||
import androidx.appcompat.widget.Toolbar
|
import androidx.appcompat.widget.Toolbar
|
||||||
|
import androidx.documentfile.provider.DocumentFile
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
@ -53,7 +56,10 @@ import org.kiwix.kiwixmobile.core.extensions.closeKeyboard
|
|||||||
import org.kiwix.kiwixmobile.core.extensions.snack
|
import org.kiwix.kiwixmobile.core.extensions.snack
|
||||||
import org.kiwix.kiwixmobile.core.main.CoreMainActivity
|
import org.kiwix.kiwixmobile.core.main.CoreMainActivity
|
||||||
import org.kiwix.kiwixmobile.core.utils.BookUtils
|
import org.kiwix.kiwixmobile.core.utils.BookUtils
|
||||||
|
import org.kiwix.kiwixmobile.core.utils.EXTERNAL_SELECT_POSITION
|
||||||
|
import org.kiwix.kiwixmobile.core.utils.INTERNAL_SELECT_POSITION
|
||||||
import org.kiwix.kiwixmobile.core.utils.NetworkUtils
|
import org.kiwix.kiwixmobile.core.utils.NetworkUtils
|
||||||
|
import org.kiwix.kiwixmobile.core.utils.REQUEST_SELECT_FOLDER_PERMISSION
|
||||||
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
|
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
|
||||||
import org.kiwix.kiwixmobile.core.utils.SimpleRecyclerViewScrollListener
|
import org.kiwix.kiwixmobile.core.utils.SimpleRecyclerViewScrollListener
|
||||||
import org.kiwix.kiwixmobile.core.utils.SimpleTextListener
|
import org.kiwix.kiwixmobile.core.utils.SimpleTextListener
|
||||||
@ -66,6 +72,7 @@ import org.kiwix.kiwixmobile.zim_manager.library_view.AvailableSpaceCalculator
|
|||||||
import org.kiwix.kiwixmobile.zim_manager.library_view.adapter.LibraryAdapter
|
import org.kiwix.kiwixmobile.zim_manager.library_view.adapter.LibraryAdapter
|
||||||
import org.kiwix.kiwixmobile.zim_manager.library_view.adapter.LibraryDelegate
|
import org.kiwix.kiwixmobile.zim_manager.library_view.adapter.LibraryDelegate
|
||||||
import org.kiwix.kiwixmobile.zim_manager.library_view.adapter.LibraryListItem
|
import org.kiwix.kiwixmobile.zim_manager.library_view.adapter.LibraryListItem
|
||||||
|
import java.io.File
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class OnlineLibraryFragment : BaseFragment(), FragmentActivityExtensions {
|
class OnlineLibraryFragment : BaseFragment(), FragmentActivityExtensions {
|
||||||
@ -243,7 +250,52 @@ class OnlineLibraryFragment : BaseFragment(), FragmentActivityExtensions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun storeDeviceInPreferences(storageDevice: StorageDevice) {
|
private fun storeDeviceInPreferences(storageDevice: StorageDevice) {
|
||||||
sharedPreferenceUtil.putPrefStorage(storageDevice.name)
|
if (storageDevice.isInternal) {
|
||||||
|
sharedPreferenceUtil.putPrefStorage(
|
||||||
|
sharedPreferenceUtil.getActualPath(storageDevice.name)
|
||||||
|
)
|
||||||
|
sharedPreferenceUtil.putStoragePosition(INTERNAL_SELECT_POSITION)
|
||||||
|
} else {
|
||||||
|
setFolder()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setFolder() {
|
||||||
|
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
|
||||||
|
intent.putExtra("android.content.extra.SHOW_ADVANCED", true)
|
||||||
|
startActivityForResult(intent, REQUEST_SELECT_FOLDER_PERMISSION)
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("WrongConstant") override fun onActivityResult(
|
||||||
|
requestCode: Int,
|
||||||
|
resultCode: Int,
|
||||||
|
data: Intent?
|
||||||
|
) {
|
||||||
|
super.onActivityResult(requestCode, resultCode, data)
|
||||||
|
if (requestCode == REQUEST_SELECT_FOLDER_PERMISSION && resultCode == Activity.RESULT_OK) {
|
||||||
|
val uri = data!!.data
|
||||||
|
val takeFlags = data.flags and (Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||||
|
or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
|
||||||
|
requireActivity().grantUriPermission(
|
||||||
|
requireActivity().packageName, uri,
|
||||||
|
Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
||||||
|
)
|
||||||
|
requireActivity().contentResolver.takePersistableUriPermission(uri!!, takeFlags)
|
||||||
|
val dfile = DocumentFile.fromTreeUri(requireActivity(), uri)
|
||||||
|
val meraPath = dfile!!.uri.path!!.substring(
|
||||||
|
dfile.uri.path!!.lastIndexOf(":") + 1
|
||||||
|
)
|
||||||
|
var path = "${requireActivity().getExternalFilesDirs("")[1]}"
|
||||||
|
val separator = "/Android"
|
||||||
|
val sepPos = path.indexOf(separator)
|
||||||
|
if (sepPos == -1) {
|
||||||
|
} else {
|
||||||
|
path = path.substring(0, sepPos)
|
||||||
|
}
|
||||||
|
path = path + File.separator + meraPath
|
||||||
|
sharedPreferenceUtil.putPrefStorage(path)
|
||||||
|
sharedPreferenceUtil.putStoragePosition(EXTERNAL_SELECT_POSITION)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onBookItemClick(item: LibraryListItem.BookItem) {
|
private fun onBookItemClick(item: LibraryListItem.BookItem) {
|
||||||
|
@ -41,7 +41,7 @@ class KiwixPrefsFragment : CorePrefsFragment() {
|
|||||||
|
|
||||||
override fun setStorage() {
|
override fun setStorage() {
|
||||||
findPreference<Preference>(PREF_STORAGE)?.title = getString(
|
findPreference<Preference>(PREF_STORAGE)?.title = getString(
|
||||||
if (sharedPreferenceUtil.prefStorage == internalStorage()) R.string.internal_storage
|
if (sharedPreferenceUtil.prefStorage == internalStorage()?.let(sharedPreferenceUtil::getActualPath)) R.string.internal_storage
|
||||||
else R.string.external_storage
|
else R.string.external_storage
|
||||||
)
|
)
|
||||||
findPreference<Preference>(PREF_STORAGE)?.summary = storageCalculator.calculateAvailableSpace()
|
findPreference<Preference>(PREF_STORAGE)?.summary = storageCalculator.calculateAvailableSpace()
|
||||||
|
@ -7,6 +7,14 @@ import kotlin.String
|
|||||||
* `$ ./gradlew buildSrcVersions`
|
* `$ ./gradlew buildSrcVersions`
|
||||||
*/
|
*/
|
||||||
object Libs {
|
object Libs {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For Getting Path of Selected Folder
|
||||||
|
**/
|
||||||
|
|
||||||
|
const val select_folder_document_file =
|
||||||
|
"androidx.documentfile:documentfile:" + Versions.document_file_version
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* https://github.com/Kotlin/kotlinx.coroutines
|
* https://github.com/Kotlin/kotlinx.coroutines
|
||||||
*/
|
*/
|
||||||
|
@ -11,6 +11,9 @@ import org.gradle.plugin.use.PluginDependencySpec
|
|||||||
* YOU are responsible for updating manually the dependency version.
|
* YOU are responsible for updating manually the dependency version.
|
||||||
*/
|
*/
|
||||||
object Versions {
|
object Versions {
|
||||||
|
|
||||||
|
const val document_file_version: String = "1.0.1"
|
||||||
|
|
||||||
const val org_jetbrains_kotlinx_kotlinx_coroutines: String = "1.4.1"
|
const val org_jetbrains_kotlinx_kotlinx_coroutines: String = "1.4.1"
|
||||||
|
|
||||||
const val androidx_test_espresso: String = "3.3.0"
|
const val androidx_test_espresso: String = "3.3.0"
|
||||||
|
@ -47,6 +47,9 @@ dependencies {
|
|||||||
implementation(Libs.squidb_annotations)
|
implementation(Libs.squidb_annotations)
|
||||||
add("kapt", Libs.squidb_processor)
|
add("kapt", Libs.squidb_processor)
|
||||||
|
|
||||||
|
// Document File
|
||||||
|
implementation(Libs.select_folder_document_file)
|
||||||
|
|
||||||
// Square
|
// Square
|
||||||
implementation(Libs.converter_simplexml) {
|
implementation(Libs.converter_simplexml) {
|
||||||
exclude(group = "xpp3", module = "xpp3")
|
exclude(group = "xpp3", module = "xpp3")
|
||||||
|
@ -43,7 +43,9 @@ internal class StorageViewHolder(
|
|||||||
else R.string.external_storage
|
else R.string.external_storage
|
||||||
)
|
)
|
||||||
|
|
||||||
file_name.isChecked = sharedPreferenceUtil.prefStorage == item.name
|
if (adapterPosition == sharedPreferenceUtil.storagePosition) {
|
||||||
|
file_name.isChecked = true
|
||||||
|
}
|
||||||
file_size.text = storageCalculator.calculateAvailableSpace(item.file) + " / " +
|
file_size.text = storageCalculator.calculateAvailableSpace(item.file) + " / " +
|
||||||
storageCalculator.calculateTotalSpace(item.file) + " "
|
storageCalculator.calculateTotalSpace(item.file) + " "
|
||||||
clickOverlay.setOnClickListener {
|
clickOverlay.setOnClickListener {
|
||||||
|
@ -20,12 +20,17 @@ package org.kiwix.kiwixmobile.core.settings;
|
|||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.webkit.WebView;
|
import android.webkit.WebView;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
|
import androidx.documentfile.provider.DocumentFile;
|
||||||
import androidx.navigation.NavController;
|
import androidx.navigation.NavController;
|
||||||
import androidx.preference.EditTextPreference;
|
import androidx.preference.EditTextPreference;
|
||||||
import androidx.preference.ListPreference;
|
import androidx.preference.ListPreference;
|
||||||
@ -51,6 +56,10 @@ import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil;
|
|||||||
import org.kiwix.kiwixmobile.core.utils.dialog.DialogShower;
|
import org.kiwix.kiwixmobile.core.utils.dialog.DialogShower;
|
||||||
import org.kiwix.kiwixmobile.core.utils.dialog.KiwixDialog;
|
import org.kiwix.kiwixmobile.core.utils.dialog.KiwixDialog;
|
||||||
|
|
||||||
|
import static android.app.Activity.RESULT_OK;
|
||||||
|
import static org.kiwix.kiwixmobile.core.utils.ConstantsKt.EXTERNAL_SELECT_POSITION;
|
||||||
|
import static org.kiwix.kiwixmobile.core.utils.ConstantsKt.INTERNAL_SELECT_POSITION;
|
||||||
|
import static org.kiwix.kiwixmobile.core.utils.ConstantsKt.REQUEST_SELECT_FOLDER_PERMISSION;
|
||||||
import static org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil.PREF_NIGHT_MODE;
|
import static org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil.PREF_NIGHT_MODE;
|
||||||
import static org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil.PREF_STORAGE;
|
import static org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil.PREF_STORAGE;
|
||||||
|
|
||||||
@ -175,9 +184,6 @@ public abstract class CorePrefsFragment extends PreferenceFragmentCompat impleme
|
|||||||
versionPref.setSummary(getVersionName() + " Build: " + getVersionCode());
|
versionPref.setSummary(getVersionName() + " Build: " + getVersionCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private int getVersionCode() {
|
private int getVersionCode() {
|
||||||
try {
|
try {
|
||||||
return getActivity().getPackageManager()
|
return getActivity().getPackageManager()
|
||||||
@ -278,13 +284,52 @@ public abstract class CorePrefsFragment extends PreferenceFragmentCompat impleme
|
|||||||
findPreference(PREF_STORAGE).setSummary(
|
findPreference(PREF_STORAGE).setSummary(
|
||||||
storageCalculator.calculateAvailableSpace(storageDevice.getFile())
|
storageCalculator.calculateAvailableSpace(storageDevice.getFile())
|
||||||
);
|
);
|
||||||
sharedPreferenceUtil.putPrefStorage(storageDevice.getName());
|
|
||||||
if (storageDevice.isInternal()) {
|
if (storageDevice.isInternal()) {
|
||||||
|
sharedPreferenceUtil.putPrefStorage(
|
||||||
|
sharedPreferenceUtil.getActualPath(storageDevice.getName()));
|
||||||
findPreference(PREF_STORAGE).setTitle(getString(R.string.internal_storage));
|
findPreference(PREF_STORAGE).setTitle(getString(R.string.internal_storage));
|
||||||
|
sharedPreferenceUtil.putStoragePosition(INTERNAL_SELECT_POSITION);
|
||||||
} else {
|
} else {
|
||||||
findPreference(PREF_STORAGE).setTitle(getString(R.string.external_storage));
|
setFolder();
|
||||||
}
|
}
|
||||||
return Unit.INSTANCE;
|
return Unit.INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setFolder() {
|
||||||
|
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
|
||||||
|
intent.putExtra("android.content.extra.SHOW_ADVANCED", true);
|
||||||
|
startActivityForResult(intent, REQUEST_SELECT_FOLDER_PERMISSION);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("WrongConstant") @Override
|
||||||
|
public void onActivityResult(int requestCode, int resultCode,
|
||||||
|
@Nullable Intent data) {
|
||||||
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
|
if (requestCode == REQUEST_SELECT_FOLDER_PERMISSION && resultCode == RESULT_OK) {
|
||||||
|
Uri uri = data.getData();
|
||||||
|
int takeFlags = data.getFlags() & (Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||||
|
| Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
|
||||||
|
getActivity().grantUriPermission(getActivity().getPackageName(), uri,
|
||||||
|
Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
|
||||||
|
getActivity().getContentResolver().takePersistableUriPermission(uri, takeFlags);
|
||||||
|
|
||||||
|
DocumentFile dfile = DocumentFile.fromTreeUri(getActivity(), uri);
|
||||||
|
String meraPath =
|
||||||
|
dfile.getUri().getPath().substring(dfile.getUri().getPath().lastIndexOf(":") + 1);
|
||||||
|
|
||||||
|
String path = getActivity().getExternalFilesDirs("")[1].toString();
|
||||||
|
String separator = "/Android";
|
||||||
|
int sepPos = path.indexOf(separator);
|
||||||
|
if (sepPos == -1) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
path = path.substring(0, sepPos);
|
||||||
|
}
|
||||||
|
path = path + File.separator + meraPath;
|
||||||
|
sharedPreferenceUtil.putPrefStorage(path);
|
||||||
|
findPreference(PREF_STORAGE).setTitle(getString(R.string.external_storage));
|
||||||
|
sharedPreferenceUtil.putStoragePosition(EXTERNAL_SELECT_POSITION);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ const val CONTACT_EMAIL_ADDRESS = "android@kiwix.org"
|
|||||||
// Request stuff
|
// Request stuff
|
||||||
const val REQUEST_STORAGE_PERMISSION = 1
|
const val REQUEST_STORAGE_PERMISSION = 1
|
||||||
const val REQUEST_WRITE_STORAGE_PERMISSION_ADD_NOTE = 3
|
const val REQUEST_WRITE_STORAGE_PERMISSION_ADD_NOTE = 3
|
||||||
|
const val REQUEST_SELECT_FOLDER_PERMISSION = 4
|
||||||
|
|
||||||
// Tags
|
// Tags
|
||||||
const val TAG_FILE_SEARCHED = "searchedarticle"
|
const val TAG_FILE_SEARCHED = "searchedarticle"
|
||||||
@ -37,3 +38,8 @@ const val TAG_FROM_TAB_SWITCHER = "fromtabswitcher"
|
|||||||
const val EXTRA_IS_WIDGET_VOICE = "isWidgetVoice"
|
const val EXTRA_IS_WIDGET_VOICE = "isWidgetVoice"
|
||||||
const val HOTSPOT_SERVICE_CHANNEL_ID = "hotspotService"
|
const val HOTSPOT_SERVICE_CHANNEL_ID = "hotspotService"
|
||||||
const val OLD_PROVIDER_DOMAIN = "org.kiwix.zim.base"
|
const val OLD_PROVIDER_DOMAIN = "org.kiwix.zim.base"
|
||||||
|
|
||||||
|
|
||||||
|
// For Storage select dialog
|
||||||
|
const val INTERNAL_SELECT_POSITION = 0
|
||||||
|
const val EXTERNAL_SELECT_POSITION = 1
|
||||||
|
@ -76,12 +76,15 @@ class SharedPreferenceUtil @Inject constructor(val context: Context) {
|
|||||||
get() {
|
get() {
|
||||||
val storage = sharedPreferences.getString(PREF_STORAGE, null)
|
val storage = sharedPreferences.getString(PREF_STORAGE, null)
|
||||||
return when {
|
return when {
|
||||||
storage == null -> defaultStorage().also(::putPrefStorage)
|
storage == null -> getActualPath(defaultStorage()).also(::putPrefStorage)
|
||||||
!File(storage).exists() -> defaultStorage()
|
!File(storage).exists() -> getActualPath(defaultStorage())
|
||||||
else -> storage
|
else -> storage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val storagePosition: Int
|
||||||
|
get() = sharedPreferences.getInt(STORAGE_POSITION, 0)
|
||||||
|
|
||||||
private fun defaultStorage(): String =
|
private fun defaultStorage(): String =
|
||||||
getExternalFilesDirs(context, null)[0]?.path
|
getExternalFilesDirs(context, null)[0]?.path
|
||||||
?: context.filesDir.path // a workaround for emulators
|
?: context.filesDir.path // a workaround for emulators
|
||||||
@ -108,6 +111,10 @@ class SharedPreferenceUtil @Inject constructor(val context: Context) {
|
|||||||
_prefStorages.onNext(storage)
|
_prefStorages.onNext(storage)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun putStoragePosition(pos: Int) {
|
||||||
|
sharedPreferences.edit { putInt(STORAGE_POSITION, pos) }
|
||||||
|
}
|
||||||
|
|
||||||
fun putPrefFullScreen(fullScreen: Boolean) =
|
fun putPrefFullScreen(fullScreen: Boolean) =
|
||||||
sharedPreferences.edit { putBoolean(PREF_FULLSCREEN, fullScreen) }
|
sharedPreferences.edit { putBoolean(PREF_FULLSCREEN, fullScreen) }
|
||||||
|
|
||||||
@ -160,10 +167,22 @@ class SharedPreferenceUtil @Inject constructor(val context: Context) {
|
|||||||
_textZooms.offer(textZoom)
|
_textZooms.offer(textZoom)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getActualPath(path: String): String {
|
||||||
|
var s = path
|
||||||
|
val separator = "/Android"
|
||||||
|
val sepPos = path.indexOf(separator)
|
||||||
|
if (sepPos == -1) {
|
||||||
|
} else {
|
||||||
|
s = path.substring(0, sepPos)
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
// Prefs
|
// Prefs
|
||||||
const val PREF_LANG = "pref_language_chooser"
|
const val PREF_LANG = "pref_language_chooser"
|
||||||
const val PREF_STORAGE = "pref_select_folder"
|
const val PREF_STORAGE = "pref_select_folder"
|
||||||
|
const val STORAGE_POSITION = "storage_position"
|
||||||
const val PREF_WIFI_ONLY = "pref_wifi_only"
|
const val PREF_WIFI_ONLY = "pref_wifi_only"
|
||||||
const val PREF_KIWIX_MOBILE = "kiwix-mobile"
|
const val PREF_KIWIX_MOBILE = "kiwix-mobile"
|
||||||
const val PREF_SHOW_INTRO = "showIntro"
|
const val PREF_SHOW_INTRO = "showIntro"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user