mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-11-20 04:29:18 +01:00
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:
parent
e2d3164c51
commit
47c2f5f97f
@ -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)
|
||||
setContentIntent(NotificationHandler.openDownloadManagerPendingActivity(context))
|
||||
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)
|
||||
}
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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() {
|
||||
|
@ -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 {
|
||||
|
@ -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 =
|
||||
|
@ -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())
|
||||
|
@ -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 -->
|
||||
|
Loading…
Reference in New Issue
Block a user