diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index b6fb5ccc2..751872132 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -14,6 +14,7 @@
+
- if (!success) {
- toast(org.fossify.commons.R.string.no_storage_permissions)
- finish()
- }
- }
+ handleMediaPermissions()
}
- private fun handleMediaPermissions(callback: (granted: Boolean) -> Unit) {
- handlePermission(getPermissionToRequest()) { granted ->
- callback(granted)
- if (granted && isRPlus()) {
- handlePermission(PERMISSION_MEDIA_LOCATION) {}
- if (isTiramisuPlus()) {
- handlePermission(PERMISSION_READ_MEDIA_VIDEO) {}
- }
-
- if (!mWasMediaManagementPromptShown) {
- mWasMediaManagementPromptShown = true
- handleMediaManagementPrompt { }
- }
+ private fun handleMediaPermissions(callback: (() -> Unit)? = null) {
+ requestMediaPermissions(enableRationale = true) {
+ callback?.invoke()
+ if (isRPlus() && !mWasMediaManagementPromptShown) {
+ mWasMediaManagementPromptShown = true
+ handleMediaManagementPrompt { }
}
}
}
@@ -497,32 +485,27 @@ class MainActivity : SimpleActivity(), DirectoryOperationsListener {
private fun tryLoadGallery() {
// avoid calling anything right after granting the permission, it will be called from onResume()
- val wasMissingPermission = config.appRunCount == 1 && !hasPermission(getPermissionToRequest())
- handleMediaPermissions { success ->
- if (success) {
- if (wasMissingPermission) {
- return@handleMediaPermissions
- }
-
- if (!mWasDefaultFolderChecked) {
- openDefaultFolder()
- mWasDefaultFolderChecked = true
- }
-
- checkOTGPath()
- checkDefaultSpamFolders()
-
- if (config.showAll) {
- showAllMedia()
- } else {
- getDirectories()
- }
-
- setupLayoutManager()
- } else {
- toast(org.fossify.commons.R.string.no_storage_permissions)
- finish()
+ val wasMissingPermission = config.appRunCount == 1 && !hasAllPermissions(getPermissionsToRequest())
+ handleMediaPermissions {
+ if (wasMissingPermission) {
+ return@handleMediaPermissions
}
+
+ if (!mWasDefaultFolderChecked) {
+ openDefaultFolder()
+ mWasDefaultFolderChecked = true
+ }
+
+ checkOTGPath()
+ checkDefaultSpamFolders()
+
+ if (config.showAll) {
+ showAllMedia()
+ } else {
+ getDirectories()
+ }
+
+ setupLayoutManager()
}
}
diff --git a/app/src/main/kotlin/org/fossify/gallery/activities/MediaActivity.kt b/app/src/main/kotlin/org/fossify/gallery/activities/MediaActivity.kt
index 6bc689366..3edfb3692 100644
--- a/app/src/main/kotlin/org/fossify/gallery/activities/MediaActivity.kt
+++ b/app/src/main/kotlin/org/fossify/gallery/activities/MediaActivity.kt
@@ -15,7 +15,6 @@ import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.request.target.SimpleTarget
import com.bumptech.glide.request.transition.Transition
-import org.fossify.commons.dialogs.ConfirmationDialog
import org.fossify.commons.dialogs.CreateNewFolderDialog
import org.fossify.commons.dialogs.RadioGroupDialog
import org.fossify.commons.extensions.*
@@ -370,35 +369,30 @@ class MediaActivity : SimpleActivity(), MediaOperationsListener {
}
private fun tryLoadGallery() {
- handlePermission(getPermissionToRequest()) {
- if (it) {
- val dirName = when {
- mPath == FAVORITES -> getString(org.fossify.commons.R.string.favorites)
- mPath == RECYCLE_BIN -> getString(org.fossify.commons.R.string.recycle_bin)
- mPath == config.OTGPath -> getString(org.fossify.commons.R.string.usb)
- else -> getHumanizedFilename(mPath)
- }
-
- val searchHint = if (mShowAll) {
- getString(org.fossify.commons.R.string.search_files)
- } else {
- getString(org.fossify.commons.R.string.search_in_placeholder, dirName)
- }
-
- binding.mediaMenu.updateHintText(searchHint)
- if (!mShowAll) {
- binding.mediaMenu.toggleForceArrowBackIcon(true)
- binding.mediaMenu.onNavigateBackClickListener = {
- onBackPressed()
- }
- }
-
- getMedia()
- setupLayoutManager()
- } else {
- toast(org.fossify.commons.R.string.no_storage_permissions)
- finish()
+ requestMediaPermissions {
+ val dirName = when (mPath) {
+ FAVORITES -> getString(org.fossify.commons.R.string.favorites)
+ RECYCLE_BIN -> getString(org.fossify.commons.R.string.recycle_bin)
+ config.OTGPath -> getString(org.fossify.commons.R.string.usb)
+ else -> getHumanizedFilename(mPath)
}
+
+ val searchHint = if (mShowAll) {
+ getString(org.fossify.commons.R.string.search_files)
+ } else {
+ getString(org.fossify.commons.R.string.search_in_placeholder, dirName)
+ }
+
+ binding.mediaMenu.updateHintText(searchHint)
+ if (!mShowAll) {
+ binding.mediaMenu.toggleForceArrowBackIcon(true)
+ binding.mediaMenu.onNavigateBackClickListener = {
+ onBackPressed()
+ }
+ }
+
+ getMedia()
+ setupLayoutManager()
}
}
diff --git a/app/src/main/kotlin/org/fossify/gallery/activities/PhotoVideoActivity.kt b/app/src/main/kotlin/org/fossify/gallery/activities/PhotoVideoActivity.kt
index 9134f85e7..d8e531d1d 100644
--- a/app/src/main/kotlin/org/fossify/gallery/activities/PhotoVideoActivity.kt
+++ b/app/src/main/kotlin/org/fossify/gallery/activities/PhotoVideoActivity.kt
@@ -46,13 +46,8 @@ open class PhotoVideoActivity : SimpleActivity(), ViewPagerFragment.FragmentList
setupOptionsMenu()
refreshMenuItems()
- handlePermission(getPermissionToRequest()) {
- if (it) {
- checkIntent(savedInstanceState)
- } else {
- toast(org.fossify.commons.R.string.no_storage_permissions)
- finish()
- }
+ requestMediaPermissions {
+ checkIntent(savedInstanceState)
}
}
diff --git a/app/src/main/kotlin/org/fossify/gallery/activities/SimpleActivity.kt b/app/src/main/kotlin/org/fossify/gallery/activities/SimpleActivity.kt
index 34f075e32..4808dd8da 100644
--- a/app/src/main/kotlin/org/fossify/gallery/activities/SimpleActivity.kt
+++ b/app/src/main/kotlin/org/fossify/gallery/activities/SimpleActivity.kt
@@ -5,20 +5,24 @@ import android.net.Uri
import android.provider.MediaStore.Images
import android.provider.MediaStore.Video
import android.view.WindowManager
+import androidx.appcompat.app.AlertDialog
import org.fossify.commons.activities.BaseSimpleActivity
import org.fossify.commons.dialogs.FilePickerDialog
-import org.fossify.commons.extensions.getParentPath
-import org.fossify.commons.extensions.getRealPathFromURI
-import org.fossify.commons.extensions.scanPathRecursively
+import org.fossify.commons.extensions.*
import org.fossify.commons.helpers.ensureBackgroundThread
import org.fossify.commons.helpers.isPiePlus
import org.fossify.gallery.R
+import org.fossify.gallery.dialogs.StoragePermissionRequiredDialog
import org.fossify.gallery.extensions.addPathToDB
import org.fossify.gallery.extensions.config
import org.fossify.gallery.extensions.updateDirectoryPath
+import org.fossify.gallery.helpers.getPermissionsToRequest
open class SimpleActivity : BaseSimpleActivity() {
- val observer = object : ContentObserver(null) {
+
+ private var dialog: AlertDialog? = null
+
+ private val observer = object : ContentObserver(null) {
override fun onChange(selfChange: Boolean, uri: Uri?) {
super.onChange(selfChange, uri)
if (uri != null) {
@@ -94,4 +98,44 @@ open class SimpleActivity : BaseSimpleActivity() {
}
}
}
+
+ protected fun requestMediaPermissions(enableRationale: Boolean = false, onGranted: () -> Unit) {
+ when {
+ hasAllPermissions(getPermissionsToRequest()) -> onGranted()
+ config.showPermissionRationale -> {
+ if (enableRationale) {
+ showPermissionRationale()
+ } else {
+ onPermissionDenied()
+ }
+ }
+
+ else -> {
+ handlePartialMediaPermissions(getPermissionsToRequest(), force = true) { granted ->
+ if (granted) {
+ onGranted()
+ } else {
+ config.showPermissionRationale = true
+ showPermissionRationale()
+ }
+ }
+ }
+ }
+ }
+
+ private fun showPermissionRationale() {
+ dialog?.dismiss()
+ StoragePermissionRequiredDialog(
+ activity = this,
+ onOkay = ::openDeviceSettings,
+ onCancel = ::onPermissionDenied
+ ) { dialog ->
+ this.dialog = dialog
+ }
+ }
+
+ private fun onPermissionDenied() {
+ toast(org.fossify.commons.R.string.no_storage_permissions)
+ finish()
+ }
}
diff --git a/app/src/main/kotlin/org/fossify/gallery/activities/ViewPagerActivity.kt b/app/src/main/kotlin/org/fossify/gallery/activities/ViewPagerActivity.kt
index 0a5b33715..b5f4a5572 100644
--- a/app/src/main/kotlin/org/fossify/gallery/activities/ViewPagerActivity.kt
+++ b/app/src/main/kotlin/org/fossify/gallery/activities/ViewPagerActivity.kt
@@ -97,15 +97,10 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
checkNotchSupport()
(MediaActivity.mMedia.clone() as ArrayList).filterIsInstanceTo(mMediaFiles, Medium::class.java)
- handlePermission(getPermissionToRequest()) {
- if (it) {
- initViewPager(
- savedPath = savedInstanceState?.getString(SAVED_PATH).orEmpty()
- )
- } else {
- toast(org.fossify.commons.R.string.no_storage_permissions)
- finish()
- }
+ requestMediaPermissions {
+ initViewPager(
+ savedPath = savedInstanceState?.getString(SAVED_PATH).orEmpty()
+ )
}
initFavorites()
diff --git a/app/src/main/kotlin/org/fossify/gallery/dialogs/StoragePermissionRequiredDialog.kt b/app/src/main/kotlin/org/fossify/gallery/dialogs/StoragePermissionRequiredDialog.kt
new file mode 100644
index 000000000..74028a3f8
--- /dev/null
+++ b/app/src/main/kotlin/org/fossify/gallery/dialogs/StoragePermissionRequiredDialog.kt
@@ -0,0 +1,36 @@
+package org.fossify.gallery.dialogs
+
+import androidx.appcompat.app.AlertDialog
+import org.fossify.commons.extensions.getAlertDialogBuilder
+import org.fossify.commons.extensions.setupDialogStuff
+import org.fossify.gallery.activities.SimpleActivity
+import org.fossify.gallery.databinding.DialogStoragePermissionRequiredBinding
+
+class StoragePermissionRequiredDialog(
+ val activity: SimpleActivity,
+ val onOkay: () -> Unit,
+ val onCancel: () -> Unit,
+ val callback: (dialog: AlertDialog) -> Unit
+) {
+
+ init {
+ val binding = DialogStoragePermissionRequiredBinding.inflate(activity.layoutInflater)
+ activity.getAlertDialogBuilder()
+ .setPositiveButton(org.fossify.commons.R.string.go_to_settings) { dialog, _ ->
+ dialog.dismiss()
+ onOkay()
+ }
+ .setNegativeButton(org.fossify.commons.R.string.cancel) { dialog, _ ->
+ dialog.dismiss()
+ onCancel()
+ }
+ .apply {
+ activity.setupDialogStuff(
+ view = binding.root,
+ dialog = this,
+ cancelOnTouchOutside = false,
+ callback = callback
+ )
+ }
+ }
+}
diff --git a/app/src/main/kotlin/org/fossify/gallery/helpers/Config.kt b/app/src/main/kotlin/org/fossify/gallery/helpers/Config.kt
index cf8044251..c721659a6 100644
--- a/app/src/main/kotlin/org/fossify/gallery/helpers/Config.kt
+++ b/app/src/main/kotlin/org/fossify/gallery/helpers/Config.kt
@@ -567,4 +567,8 @@ class Config(context: Context) : BaseConfig(context) {
var lastExportedFavoritesFolder: String
get() = prefs.getString(LAST_EXPORTED_FAVORITES_FOLDER, "")!!
set(lastExportedFavoritesFolder) = prefs.edit().putString(LAST_EXPORTED_FAVORITES_FOLDER, lastExportedFavoritesFolder).apply()
+
+ var showPermissionRationale: Boolean
+ get() = prefs.getBoolean(SHOW_PERMISSION_RATIONALE, false)
+ set(showPermissionRationale) = prefs.edit().putBoolean(SHOW_PERMISSION_RATIONALE, showPermissionRationale).apply()
}
diff --git a/app/src/main/kotlin/org/fossify/gallery/helpers/Constants.kt b/app/src/main/kotlin/org/fossify/gallery/helpers/Constants.kt
index ff34d5e78..af11e1c04 100644
--- a/app/src/main/kotlin/org/fossify/gallery/helpers/Constants.kt
+++ b/app/src/main/kotlin/org/fossify/gallery/helpers/Constants.kt
@@ -98,6 +98,7 @@ const val CUSTOM_FOLDERS_ORDER = "custom_folders_order"
const val AVOID_SHOWING_ALL_FILES_PROMPT = "avoid_showing_all_files_prompt"
const val SEARCH_ALL_FILES_BY_DEFAULT = "search_all_files_by_default"
const val LAST_EXPORTED_FAVORITES_FOLDER = "last_exported_favorites_folder"
+const val SHOW_PERMISSION_RATIONALE = "show_permission_rationale"
// slideshow
const val SLIDESHOW_INTERVAL = "slideshow_interval"
@@ -250,8 +251,6 @@ const val THUMBNAIL_FADE_DURATION_MS = 150
fun getPermissionToRequest() = if (isTiramisuPlus()) PERMISSION_READ_MEDIA_IMAGES else PERMISSION_WRITE_STORAGE
-fun getRequiredPermission() = if (isUpsideDownCakePlus()) PERMISSION_READ_MEDIA_VISUAL_USER_SELECTED else getPermissionToRequest()
-
fun getPermissionsToRequest(): Collection {
val permissions = mutableListOf(getPermissionToRequest())
if (isRPlus()) {
diff --git a/app/src/main/res/layout/dialog_storage_permission_required.xml b/app/src/main/res/layout/dialog_storage_permission_required.xml
new file mode 100644
index 000000000..bdd45d5a8
--- /dev/null
+++ b/app/src/main/res/layout/dialog_storage_permission_required.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 56f4bef57..302a55d00 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -33,6 +33,7 @@
Reorder folders by dragging
Reorder folders by dragging (Pro)
Restoring to \'%s\'
+ Fossify Gallery needs full access to display all your photos and videos. Go to Settings > Permissions > Photos and videos > Allow all.
Filter media