Adding a popup to tell users to enable all files access on A11

For now I'm just committing this so translators can get a headstart, but it's too soon to tell if target/compile to sdk 30 in the last commit will stay
This commit is contained in:
Jays2Kings 2021-05-26 23:12:33 -04:00
parent e2d3164c51
commit 47c2f5f97f
8 changed files with 100 additions and 16 deletions

View File

@ -1,6 +1,8 @@
package eu.kanade.tachiyomi.data.download
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.graphics.BitmapFactory
import androidx.core.app.NotificationCompat
import androidx.core.content.ContextCompat
@ -141,7 +143,10 @@ internal class DownloadNotifier(private val context: Context) {
val title = download.manga.title.chop(15)
val quotedTitle = Pattern.quote(title)
val chapter = download.chapter.name.replaceFirst("$quotedTitle[\\s]*[-]*[\\s]*".toRegex(RegexOption.IGNORE_CASE), "")
val chapter = download.chapter.name.replaceFirst(
"$quotedTitle[\\s]*[-]*[\\s]*".toRegex(RegexOption.IGNORE_CASE),
""
)
setContentTitle("$title - $chapter".chop(30))
setContentText(
context.getString(R.string.downloading_progress)
@ -218,17 +223,36 @@ internal class DownloadNotifier(private val context: Context) {
* @param error string containing error information.
* @param chapter string containing chapter title.
*/
fun onError(error: String? = null, chapter: String? = null) {
fun onError(
error: String? = null,
chapter: String? = null,
customIntent: Intent? = null
) {
// Create notification
with(notification) {
setContentTitle(chapter ?: context.getString(R.string.download_error))
setContentText(error ?: context.getString(R.string.could_not_download_unexpected_error))
setStyle(NotificationCompat.BigTextStyle().bigText(error ?: context.getString(R.string.could_not_download_unexpected_error)))
setStyle(
NotificationCompat.BigTextStyle().bigText(
error ?: context.getString(R.string.could_not_download_unexpected_error)
)
)
setSmallIcon(android.R.drawable.stat_sys_warning)
setCategory(NotificationCompat.CATEGORY_ERROR)
clearActions()
setAutoCancel(true)
if (customIntent != null) {
setContentIntent(
PendingIntent.getActivity(
context,
0,
customIntent,
PendingIntent.FLAG_UPDATE_CURRENT
)
)
} else {
setContentIntent(NotificationHandler.openDownloadManagerPendingActivity(context))
}
color = ContextCompat.getColor(context, R.color.colorAccent)
setProgress(0, 0, false)
}

View File

@ -1,7 +1,12 @@
package eu.kanade.tachiyomi.data.download
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.Environment
import android.provider.Settings
import android.webkit.MimeTypeMap
import androidx.core.net.toUri
import com.hippo.unifile.UniFile
import com.jakewharton.rxrelay.BehaviorRelay
import com.jakewharton.rxrelay.PublishRelay
@ -298,7 +303,21 @@ class Downloader(
notifier.onError(context.getString(R.string.couldnt_download_low_space), download.chapter.name)
return@defer Observable.just(download)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R &&
!Environment.isExternalStorageManager()
) {
val intent = Intent(
Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION,
"package:${context.packageName}".toUri()
)
notifier.onError(
context.getString(R.string.external_storage_download_notice),
download.chapter.name,
intent
)
return@defer Observable.just(download)
}
val chapterDirname = provider.getChapterDirName(download.chapter)
val tmpDir = mangaDir.createDirectory(chapterDirname + TMP_DIR_SUFFIX)

View File

@ -1,6 +1,5 @@
package eu.kanade.tachiyomi.ui.manga
import android.Manifest.permission.WRITE_EXTERNAL_STORAGE
import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.AnimatorSet
@ -103,7 +102,7 @@ import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.util.view.activityBinding
import eu.kanade.tachiyomi.util.view.doOnApplyWindowInsets
import eu.kanade.tachiyomi.util.view.getText
import eu.kanade.tachiyomi.util.view.requestPermissionsSafe
import eu.kanade.tachiyomi.util.view.requestFilePermissionsSafe
import eu.kanade.tachiyomi.util.view.scrollViewWith
import eu.kanade.tachiyomi.util.view.setOnQueryTextChangeListener
import eu.kanade.tachiyomi.util.view.setStyle
@ -215,7 +214,7 @@ class MangaDetailsController :
presenter.onCreate()
binding.swipeRefresh.isRefreshing = presenter.isLoading
binding.swipeRefresh.setOnRefreshListener { presenter.refreshAll() }
requestPermissionsSafe(arrayOf(WRITE_EXTERNAL_STORAGE), 301)
requestFilePermissionsSafe(301)
}
/** Check if device is tablet, and use a second recycler to hold the details header if so */

View File

@ -1,6 +1,5 @@
package eu.kanade.tachiyomi.ui.recents
import android.Manifest.permission.WRITE_EXTERNAL_STORAGE
import android.app.Activity
import android.content.res.ColorStateList
import android.os.Bundle
@ -52,7 +51,7 @@ import eu.kanade.tachiyomi.util.view.activityBinding
import eu.kanade.tachiyomi.util.view.expand
import eu.kanade.tachiyomi.util.view.isCollapsed
import eu.kanade.tachiyomi.util.view.isExpanded
import eu.kanade.tachiyomi.util.view.requestPermissionsSafe
import eu.kanade.tachiyomi.util.view.requestFilePermissionsSafe
import eu.kanade.tachiyomi.util.view.scrollViewWith
import eu.kanade.tachiyomi.util.view.setOnQueryTextChangeListener
import eu.kanade.tachiyomi.util.view.setStyle
@ -364,7 +363,7 @@ class RecentsController(bundle: Bundle? = null) :
binding.downloadBottomSheet.dlBottomSheet.sheetBehavior?.expand()
}
setPadding(binding.downloadBottomSheet.dlBottomSheet.sheetBehavior?.isHideable == true)
requestPermissionsSafe(arrayOf(WRITE_EXTERNAL_STORAGE), 301)
requestFilePermissionsSafe(301)
}
fun updateTitleAndMenu() {

View File

@ -1,6 +1,5 @@
package eu.kanade.tachiyomi.ui.setting
import android.Manifest.permission.WRITE_EXTERNAL_STORAGE
import android.app.Activity
import android.app.Dialog
import android.content.ActivityNotFoundException
@ -29,7 +28,7 @@ import eu.kanade.tachiyomi.data.preference.asImmediateFlow
import eu.kanade.tachiyomi.ui.base.controller.DialogController
import eu.kanade.tachiyomi.util.system.getFilePicker
import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.util.view.requestPermissionsSafe
import eu.kanade.tachiyomi.util.view.requestFilePermissionsSafe
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import eu.kanade.tachiyomi.data.preference.PreferenceKeys as Keys
@ -43,7 +42,7 @@ class SettingsBackupController : SettingsController() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
requestPermissionsSafe(arrayOf(WRITE_EXTERNAL_STORAGE), 500)
requestFilePermissionsSafe(500)
}
override fun setupPreferenceScreen(screen: PreferenceScreen) = screen.apply {

View File

@ -1,6 +1,5 @@
package eu.kanade.tachiyomi.ui.source
import android.Manifest.permission.WRITE_EXTERNAL_STORAGE
import android.animation.ValueAnimator
import android.app.Activity
import android.content.res.ColorStateList
@ -48,7 +47,7 @@ import eu.kanade.tachiyomi.util.view.collapse
import eu.kanade.tachiyomi.util.view.expand
import eu.kanade.tachiyomi.util.view.isCollapsed
import eu.kanade.tachiyomi.util.view.isExpanded
import eu.kanade.tachiyomi.util.view.requestPermissionsSafe
import eu.kanade.tachiyomi.util.view.requestFilePermissionsSafe
import eu.kanade.tachiyomi.util.view.scrollViewWith
import eu.kanade.tachiyomi.util.view.setOnQueryTextChangeListener
import eu.kanade.tachiyomi.util.view.snack
@ -159,7 +158,7 @@ class BrowseController :
updateTitleAndMenu()
}
requestPermissionsSafe(arrayOf(WRITE_EXTERNAL_STORAGE), 301)
requestFilePermissionsSafe(301)
binding.bottomSheet.root.onCreate(this)
binding.shadow.alpha =

View File

@ -1,9 +1,13 @@
package eu.kanade.tachiyomi.util.view
import android.Manifest
import android.animation.ValueAnimator
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.os.Environment
import android.provider.Settings
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
@ -18,6 +22,7 @@ import androidx.core.net.toUri
import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.afollestad.materialdialogs.MaterialDialog
import com.bluelinelabs.conductor.Controller
import com.bluelinelabs.conductor.ControllerChangeHandler
import com.bluelinelabs.conductor.ControllerChangeType
@ -480,6 +485,42 @@ fun Controller.requestPermissionsSafe(permissions: Array<String>, requestCode: I
}
}
fun Controller.requestFilePermissionsSafe(requestCode: Int) {
val activity = activity ?: return
val permissions = mutableListOf(Manifest.permission.WRITE_EXTERNAL_STORAGE)
permissions.forEach { permission ->
if (ContextCompat.checkSelfPermission(
activity,
permission
) != PackageManager.PERMISSION_GRANTED
) {
requestPermissions(arrayOf(permission), requestCode)
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R &&
!Environment.isExternalStorageManager()
) {
MaterialDialog(activity)
.title(R.string.all_files_permission_required)
.message(R.string.external_storage_permission_notice)
.cancelOnTouchOutside(false)
.positiveButton(android.R.string.ok) {
val intent = Intent(
Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION,
"package:${activity.packageName}".toUri()
)
try {
activity.startActivity(intent)
} catch (_: Exception) {
val intent2 = Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION)
activity.startActivity(intent2)
}
}
.negativeButton(android.R.string.cancel)
.show()
}
}
fun Controller.withFadeTransaction(): RouterTransaction {
return RouterTransaction.with(this)
.pushChangeHandler(OneWayFadeChangeHandler())

View File

@ -3,6 +3,10 @@
<string name="app_name" translatable="false">TachiyomiJ2K</string>
<string name="app_short_name" translatable="false">TachiJ2K</string>
<string name="all_files_permission_required">File permissions required</string>
<string name="external_storage_permission_notice">TachiyomiJ2K requires access to all files in Android 11 to download chapters, create automatic backups, and read local manga. \n\nOn the next screen, enable \"Allow access to manage all files.\"</string>
<string name="external_storage_download_notice">TachiyomiJ2K requires access to all files to download chapters. Tap here, then enable \"Allow access to manage all files.\"</string>
<!--Models-->
<!-- Manga Type -->