diff --git a/app/detekt_baseline.xml b/app/detekt_baseline.xml
index 40e2c3c8a..2c43a15d6 100644
--- a/app/detekt_baseline.xml
+++ b/app/detekt_baseline.xml
@@ -11,7 +11,7 @@
MagicNumber:ShareFiles.kt$ShareFiles$24
MagicNumber:ZimManageViewModel.kt$ZimManageViewModel$5
MagicNumber:ZimManageViewModel.kt$ZimManageViewModel$500
- MagicNumber:ZimHostFragment.kt$ZimHostFragment$4
+ NestedBlockDepth:LocalLibraryFragment.kt$LocalLibraryFragment$checkPermissions
NestedBlockDepth:PeerGroupHandshake.kt$PeerGroupHandshake$readHandshakeAndExchangeMetaData
NestedBlockDepth:ReceiverHandShake.kt$ReceiverHandShake$exchangeFileTransferMetadata
PackageNaming:AvailableSpaceCalculator.kt$package org.kiwix.kiwixmobile.zim_manager.library_view
diff --git a/app/src/main/java/org/kiwix/kiwixmobile/nav/destination/library/LocalLibraryFragment.kt b/app/src/main/java/org/kiwix/kiwixmobile/nav/destination/library/LocalLibraryFragment.kt
index 592471fc5..59790c3ee 100644
--- a/app/src/main/java/org/kiwix/kiwixmobile/nav/destination/library/LocalLibraryFragment.kt
+++ b/app/src/main/java/org/kiwix/kiwixmobile/nav/destination/library/LocalLibraryFragment.kt
@@ -20,7 +20,9 @@ package org.kiwix.kiwixmobile.nav.destination.library
import android.Manifest
import android.content.pm.PackageManager
+import android.os.Build
import android.os.Bundle
+import android.os.Environment
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
@@ -62,6 +64,12 @@ import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel.FileSelectActions.Re
import org.kiwix.kiwixmobile.zim_manager.ZimManageViewModel.FileSelectActions.RequestSelect
import org.kiwix.kiwixmobile.zim_manager.fileselect_view.FileSelectListState
import javax.inject.Inject
+import android.content.Intent
+import android.net.Uri
+import android.provider.Settings
+import androidx.annotation.RequiresApi
+import org.kiwix.kiwixmobile.core.utils.dialog.DialogShower
+import org.kiwix.kiwixmobile.core.utils.dialog.KiwixDialog
private const val WAS_IN_ACTION_MODE = "WAS_IN_ACTION_MODE"
@@ -69,6 +77,7 @@ class LocalLibraryFragment : BaseFragment() {
@Inject lateinit var viewModelFactory: ViewModelProvider.Factory
@Inject lateinit var sharedPreferenceUtil: SharedPreferenceUtil
+ @Inject lateinit var dialogShower: DialogShower
private var actionMode: ActionMode? = null
private val disposable = CompositeDisposable()
@@ -202,7 +211,25 @@ class LocalLibraryFragment : BaseFragment() {
REQUEST_STORAGE_PERMISSION
)
} else {
- requestFileSystemCheck()
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
+ if (Environment.isExternalStorageManager()) {
+ // We already have permission!!
+ requestFileSystemCheck()
+ } else {
+ if (sharedPreferenceUtil.manageExternalFilesPermissionDialog) {
+ // We should only ask for first time, If the users wants to revoke settings
+ // then they can directly toggle this feature from settings screen
+ sharedPreferenceUtil.manageExternalFilesPermissionDialog = false
+ // Show Dialog and Go to settings to give permission
+ dialogShower.show(
+ KiwixDialog.ManageExternalFilesPermissionDialog,
+ ::navigateToSettings
+ )
+ }
+ }
+ } else {
+ requestFileSystemCheck()
+ }
}
}
@@ -217,4 +244,13 @@ class LocalLibraryFragment : BaseFragment() {
private fun navigateToLocalFileTransferFragment() {
requireActivity().navigate(R.id.localFileTransferFragment)
}
+
+ @RequiresApi(Build.VERSION_CODES.R)
+ private fun navigateToSettings() {
+ val intent = Intent().apply {
+ action = Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION
+ data = Uri.fromParts("package", requireActivity().packageName, null)
+ }
+ startActivity(intent)
+ }
}
diff --git a/core/src/main/AndroidManifest.xml b/core/src/main/AndroidManifest.xml
index da773d305..f9b3b51b1 100644
--- a/core/src/main/AndroidManifest.xml
+++ b/core/src/main/AndroidManifest.xml
@@ -8,6 +8,8 @@
+
diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/settings/CorePrefsFragment.java b/core/src/main/java/org/kiwix/kiwixmobile/core/settings/CorePrefsFragment.java
index badbf0f49..11d52e618 100644
--- a/core/src/main/java/org/kiwix/kiwixmobile/core/settings/CorePrefsFragment.java
+++ b/core/src/main/java/org/kiwix/kiwixmobile/core/settings/CorePrefsFragment.java
@@ -20,16 +20,23 @@ package org.kiwix.kiwixmobile.core.settings;
import android.Manifest;
import android.annotation.SuppressLint;
+import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.os.Build;
import android.os.Bundle;
+import android.os.Environment;
+import android.provider.Settings;
import android.view.LayoutInflater;
import android.webkit.WebView;
+import androidx.annotation.RequiresApi;
import androidx.core.content.ContextCompat;
import androidx.navigation.NavController;
import androidx.preference.EditTextPreference;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
+import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceFragmentCompat;
import com.google.android.material.snackbar.Snackbar;
import eu.mhutti1.utils.storage.StorageDevice;
@@ -62,6 +69,9 @@ public abstract class CorePrefsFragment extends PreferenceFragmentCompat impleme
public static final String PREF_CLEAR_ALL_HISTORY = "pref_clear_all_history";
public static final String PREF_CLEAR_ALL_NOTES = "pref_clear_all_notes";
public static final String PREF_CREDITS = "pref_credits";
+ public static final String PREF_MANAGE_EXTERNAL_STORAGE_PERMISSION =
+ "pref_manage_external_storage";
+ public static final String PREF_PERMISSION = "pref_permissions";
private static final int ZOOM_OFFSET = 2;
private static final int ZOOM_SCALE = 25;
private static final String INTERNAL_TEXT_ZOOM = "text_zoom";
@@ -87,6 +97,7 @@ public abstract class CorePrefsFragment extends PreferenceFragmentCompat impleme
setStorage();
setUpSettings();
setupZoom();
+ setMangeExternalStoragePermission();
new LanguageUtils(getActivity()).changeFont(getActivity().getLayoutInflater(),
sharedPreferenceUtil);
}
@@ -174,6 +185,28 @@ public abstract class CorePrefsFragment extends PreferenceFragmentCompat impleme
versionPref.setSummary(getVersionName() + " Build: " + getVersionCode());
}
+ private void setMangeExternalStoragePermission() {
+ Preference permissionPref = findPreference(PREF_MANAGE_EXTERNAL_STORAGE_PERMISSION);
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
+ showPermissionPreference();
+ boolean externalStorageManager = Environment.isExternalStorageManager();
+ if (externalStorageManager) {
+ permissionPref.setSummary(R.string.allowed);
+ } else {
+ permissionPref.setSummary(R.string.not_allowed);
+ }
+ permissionPref.setOnPreferenceClickListener(
+ preference -> {
+ navigateToSettings();
+ return true;
+ });
+ }
+ }
+ private void showPermissionPreference() {
+ PreferenceCategory preferenceCategory = findPreference(PREF_PERMISSION);
+ preferenceCategory.setVisible(true);
+ }
+
private int getVersionCode() {
try {
return getActivity().getPackageManager()
@@ -282,4 +315,14 @@ public abstract class CorePrefsFragment extends PreferenceFragmentCompat impleme
}
return Unit.INSTANCE;
}
+
+ // TODO: 28/10/21 Refactor the code. We are using it twice.
+ @RequiresApi(Build.VERSION_CODES.R)
+ private void navigateToSettings() {
+ Intent intent = new Intent();
+ intent.setAction(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
+ Uri uri = Uri.fromParts("package", getActivity().getPackageName(), null);
+ intent.setData(uri);
+ startActivity(intent);
+ }
}
diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/utils/SharedPreferenceUtil.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/utils/SharedPreferenceUtil.kt
index 8c7cc8ea9..19c4d0ac7 100644
--- a/core/src/main/java/org/kiwix/kiwixmobile/core/utils/SharedPreferenceUtil.kt
+++ b/core/src/main/java/org/kiwix/kiwixmobile/core/utils/SharedPreferenceUtil.kt
@@ -140,6 +140,13 @@ class SharedPreferenceUtil @Inject constructor(val context: Context) {
fun updateNightMode() = nightModes.offer(nightMode)
+ var manageExternalFilesPermissionDialog: Boolean
+ get() = sharedPreferences.getBoolean(PREF_MANAGE_EXTERNAL_FILES, true)
+ set(prefManageExternalFilesPermissionDialog) =
+ sharedPreferences.edit {
+ putBoolean(PREF_MANAGE_EXTERNAL_FILES, prefManageExternalFilesPermissionDialog)
+ }
+
var hostedBooks: Set
get() = sharedPreferences.getStringSet(PREF_HOSTED_BOOKS, null)?.toHashSet() ?: HashSet()
set(hostedBooks) {
@@ -172,5 +179,6 @@ class SharedPreferenceUtil @Inject constructor(val context: Context) {
const val PREF_NIGHT_MODE = "pref_night_mode"
private const val TEXT_ZOOM = "true_text_zoom"
private const val DEFAULT_ZOOM = 100
+ private const val PREF_MANAGE_EXTERNAL_FILES = "pref_manage_external_files"
}
}
diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/utils/dialog/KiwixDialog.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/utils/dialog/KiwixDialog.kt
index 53ce42151..7bb1139ac 100644
--- a/core/src/main/java/org/kiwix/kiwixmobile/core/utils/dialog/KiwixDialog.kt
+++ b/core/src/main/java/org/kiwix/kiwixmobile/core/utils/dialog/KiwixDialog.kt
@@ -84,6 +84,14 @@ sealed class KiwixDialog(
cancelable = false
)
+ object ManageExternalFilesPermissionDialog : KiwixDialog(
+ R.string.all_files_permission_needed,
+ R.string.all_files_permission_needed_message,
+ R.string.yes,
+ R.string.no,
+ cancelable = false
+ )
+
data class ShowHotspotDetails(override val args: List) : KiwixDialog(
R.string.hotspot_turned_on,
R.string.hotspot_details_message,
diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml
index af11074bc..4a7c1289b 100644
--- a/core/src/main/res/values/strings.xml
+++ b/core/src/main/res/values/strings.xml
@@ -68,6 +68,7 @@
Clear history
Clear recent searches and tabs history
Notes
+ Permissions
All History Cleared
Clear bookmarks
Clear All History?
@@ -255,6 +256,7 @@
Status
Clears all notes on all articles
Clear all notes
+ Allow to read/write ZIM file\'s on SD card
Change text size with 25\% increments.
Pic
Vid
@@ -289,6 +291,10 @@
Close Drawer
How to update content?
To update content (a zim file) you need to download the full latest version of this very same content. You can do that via the download section.
+ All Files Permission Needed
+ In order to access all the zim files across device we need to have All Files Permission
+ Allowed
+ Not allowed
- @string/on
- @string/off
diff --git a/core/src/main/res/xml/preferences.xml b/core/src/main/res/xml/preferences.xml
index e8e0c52cb..081a15b34 100644
--- a/core/src/main/res/xml/preferences.xml
+++ b/core/src/main/res/xml/preferences.xml
@@ -95,6 +95,18 @@
android:title="@string/pref_clear_all_notes_title"
app:iconSpaceReserved="false" />
+
+
+
+
+