diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 9a149a441..85914dd9d 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -171,6 +171,10 @@
+
+
= WeakReference(activity)
+
+ override val context: Context?
+ get() = actRef.get()
+
+ override fun startActivity(intent: Intent) {
+ actRef.get()?.startActivity(intent)
+ }
+
+}
diff --git a/app/src/main/java/io/legado/app/help/permission/FragmentSource.kt b/app/src/main/java/io/legado/app/help/permission/FragmentSource.kt
new file mode 100644
index 000000000..b66e11b98
--- /dev/null
+++ b/app/src/main/java/io/legado/app/help/permission/FragmentSource.kt
@@ -0,0 +1,19 @@
+package io.legado.app.help.permission
+
+import android.content.Context
+import android.content.Intent
+import androidx.fragment.app.Fragment
+
+import java.lang.ref.WeakReference
+
+internal class FragmentSource(fragment: Fragment) : RequestSource {
+
+ private val fragRef: WeakReference = WeakReference(fragment)
+
+ override val context: Context?
+ get() = fragRef.get()?.requireContext()
+
+ override fun startActivity(intent: Intent) {
+ fragRef.get()?.startActivity(intent)
+ }
+}
diff --git a/app/src/main/java/io/legado/app/help/permission/OnPermissionsDeniedCallback.kt b/app/src/main/java/io/legado/app/help/permission/OnPermissionsDeniedCallback.kt
new file mode 100644
index 000000000..4a51881b0
--- /dev/null
+++ b/app/src/main/java/io/legado/app/help/permission/OnPermissionsDeniedCallback.kt
@@ -0,0 +1,7 @@
+package io.legado.app.help.permission
+
+interface OnPermissionsDeniedCallback {
+
+ fun onPermissionsDenied(requestCode: Int, deniedPermissions: Array)
+
+}
diff --git a/app/src/main/java/io/legado/app/help/permission/OnPermissionsGrantedCallback.kt b/app/src/main/java/io/legado/app/help/permission/OnPermissionsGrantedCallback.kt
new file mode 100644
index 000000000..59f6977d4
--- /dev/null
+++ b/app/src/main/java/io/legado/app/help/permission/OnPermissionsGrantedCallback.kt
@@ -0,0 +1,7 @@
+package io.legado.app.help.permission
+
+interface OnPermissionsGrantedCallback {
+
+ fun onPermissionsGranted(requestCode: Int)
+
+}
diff --git a/app/src/main/java/io/legado/app/help/permission/OnPermissionsResultCallback.kt b/app/src/main/java/io/legado/app/help/permission/OnPermissionsResultCallback.kt
new file mode 100644
index 000000000..3d7afa600
--- /dev/null
+++ b/app/src/main/java/io/legado/app/help/permission/OnPermissionsResultCallback.kt
@@ -0,0 +1,9 @@
+package io.legado.app.help.permission
+
+interface OnPermissionsResultCallback {
+
+ fun onPermissionsGranted(requestCode: Int)
+
+ fun onPermissionsDenied(requestCode: Int, deniedPermissions: Array)
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/io/legado/app/help/permission/OnRequestPermissionsResultCallback.kt b/app/src/main/java/io/legado/app/help/permission/OnRequestPermissionsResultCallback.kt
new file mode 100644
index 000000000..fde78ae82
--- /dev/null
+++ b/app/src/main/java/io/legado/app/help/permission/OnRequestPermissionsResultCallback.kt
@@ -0,0 +1,14 @@
+package io.legado.app.help.permission
+
+import android.content.Intent
+
+interface OnRequestPermissionsResultCallback {
+
+ fun onRequestPermissionsResult(
+ requestCode: Int,
+ permissions: Array,
+ grantResults: IntArray
+ )
+
+ fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?)
+}
diff --git a/app/src/main/java/io/legado/app/help/permission/PermissionActivity.kt b/app/src/main/java/io/legado/app/help/permission/PermissionActivity.kt
new file mode 100644
index 000000000..095f7e164
--- /dev/null
+++ b/app/src/main/java/io/legado/app/help/permission/PermissionActivity.kt
@@ -0,0 +1,84 @@
+package io.legado.app.help.permission
+
+import android.content.Intent
+import android.net.Uri
+import android.os.Bundle
+import android.provider.Settings
+import android.view.KeyEvent
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.app.ActivityCompat
+import io.legado.app.R
+import io.legado.app.utils.toastOnUi
+
+class PermissionActivity : AppCompatActivity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ when (intent.getIntExtra(KEY_INPUT_REQUEST_TYPE, Request.TYPE_REQUEST_PERMISSION)) {
+ Request.TYPE_REQUEST_PERMISSION//权限请求
+ -> {
+ val requestCode = intent.getIntExtra(KEY_INPUT_PERMISSIONS_CODE, 1000)
+ val permissions = intent.getStringArrayExtra(KEY_INPUT_PERMISSIONS)
+ if (permissions != null) {
+ ActivityCompat.requestPermissions(this, permissions, requestCode)
+ } else {
+ finish()
+ }
+ }
+ Request.TYPE_REQUEST_SETTING//跳转到设置界面
+ -> try {
+ val settingIntent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
+ settingIntent.data = Uri.fromParts("package", packageName, null)
+ startActivityForResult(settingIntent, Request.TYPE_REQUEST_SETTING)
+ } catch (e: Exception) {
+ toastOnUi(R.string.tip_cannot_jump_setting_page)
+ finish()
+ }
+
+ }
+ }
+
+ override fun onRequestPermissionsResult(
+ requestCode: Int,
+ permissions: Array,
+ grantResults: IntArray
+ ) {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults)
+ RequestPlugins.sRequestCallback?.onRequestPermissionsResult(
+ requestCode,
+ permissions,
+ grantResults
+ )
+ finish()
+ }
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ super.onActivityResult(requestCode, resultCode, data)
+ RequestPlugins.sRequestCallback?.onActivityResult(requestCode, resultCode, data)
+ finish()
+ }
+
+ override fun startActivity(intent: Intent) {
+ super.startActivity(intent)
+ overridePendingTransition(0, 0)
+ }
+
+ override fun finish() {
+ super.finish()
+ overridePendingTransition(0, 0)
+ }
+
+ override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
+ return if (keyCode == KeyEvent.KEYCODE_BACK) {
+ true
+ } else super.onKeyDown(keyCode, event)
+ }
+
+ companion object {
+
+ const val KEY_INPUT_REQUEST_TYPE = "KEY_INPUT_REQUEST_TYPE"
+ const val KEY_INPUT_PERMISSIONS_CODE = "KEY_INPUT_PERMISSIONS_CODE"
+ const val KEY_INPUT_PERMISSIONS = "KEY_INPUT_PERMISSIONS"
+ }
+}
diff --git a/app/src/main/java/io/legado/app/constant/Permissions.kt b/app/src/main/java/io/legado/app/help/permission/Permissions.kt
similarity index 98%
rename from app/src/main/java/io/legado/app/constant/Permissions.kt
rename to app/src/main/java/io/legado/app/help/permission/Permissions.kt
index c78bfeb4c..978541f69 100644
--- a/app/src/main/java/io/legado/app/constant/Permissions.kt
+++ b/app/src/main/java/io/legado/app/help/permission/Permissions.kt
@@ -1,4 +1,4 @@
-package io.legado.app.constant
+package io.legado.app.help.permission
@Suppress("unused")
object Permissions {
diff --git a/app/src/main/java/io/legado/app/help/permission/PermissionsCompat.kt b/app/src/main/java/io/legado/app/help/permission/PermissionsCompat.kt
new file mode 100644
index 000000000..6875b9e19
--- /dev/null
+++ b/app/src/main/java/io/legado/app/help/permission/PermissionsCompat.kt
@@ -0,0 +1,94 @@
+package io.legado.app.help.permission
+
+import androidx.annotation.StringRes
+import androidx.appcompat.app.AppCompatActivity
+import androidx.fragment.app.Fragment
+import java.util.*
+
+@Suppress("unused")
+class PermissionsCompat private constructor() {
+
+ private var request: Request? = null
+
+ fun request() {
+ RequestManager.pushRequest(request)
+ }
+
+ companion object {
+ // 检查权限, 如果已经拥有返回 true
+ fun check(activity: AppCompatActivity, vararg permissions: String): Boolean {
+ val request = Request(activity)
+ val pers = ArrayList()
+ pers.addAll(listOf(*permissions))
+ val data = request.getDeniedPermissions(pers.toTypedArray())
+ return data == null
+ }
+ }
+
+ class Builder {
+ private val request: Request
+
+ constructor(activity: AppCompatActivity) {
+ request = Request(activity)
+ }
+
+ constructor(fragment: Fragment) {
+ request = Request(fragment)
+ }
+
+ fun addPermissions(vararg permissions: String): Builder {
+ request.addPermissions(*permissions)
+ return this
+ }
+
+ fun requestCode(requestCode: Int): Builder {
+ request.setRequestCode(requestCode)
+ return this
+ }
+
+ fun onGranted(callback: (requestCode: Int) -> Unit): Builder {
+ request.setOnGrantedCallback(object : OnPermissionsGrantedCallback {
+ override fun onPermissionsGranted(requestCode: Int) {
+ callback(requestCode)
+ }
+ })
+ return this
+ }
+
+ fun onDenied(callback: (requestCode: Int, deniedPermissions: Array) -> Unit): Builder {
+ request.setOnDeniedCallback(object : OnPermissionsDeniedCallback {
+ override fun onPermissionsDenied(
+ requestCode: Int,
+ deniedPermissions: Array
+ ) {
+ callback(requestCode, deniedPermissions)
+ }
+ })
+ return this
+ }
+
+ fun rationale(rationale: CharSequence): Builder {
+ request.setRationale(rationale)
+ return this
+ }
+
+ fun rationale(@StringRes resId: Int): Builder {
+ request.setRationale(resId)
+ return this
+ }
+
+ fun build(): PermissionsCompat {
+ val compat = PermissionsCompat()
+ compat.request = request
+ return compat
+ }
+
+ fun request(): PermissionsCompat {
+ val compat = build()
+ compat.request = request
+ compat.request()
+ return compat
+ }
+ }
+
+}
diff --git a/app/src/main/java/io/legado/app/help/permission/Request.kt b/app/src/main/java/io/legado/app/help/permission/Request.kt
new file mode 100644
index 000000000..7a26f521f
--- /dev/null
+++ b/app/src/main/java/io/legado/app/help/permission/Request.kt
@@ -0,0 +1,204 @@
+package io.legado.app.help.permission
+
+import android.content.Intent
+import android.content.pm.PackageManager
+import android.os.Build
+import androidx.annotation.StringRes
+import androidx.appcompat.app.AlertDialog
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.content.ContextCompat
+import androidx.fragment.app.Fragment
+import io.legado.app.R
+import io.legado.app.utils.startActivity
+import java.util.*
+
+internal class Request : OnRequestPermissionsResultCallback {
+
+ internal val requestTime: Long
+ private var requestCode: Int = TYPE_REQUEST_PERMISSION
+ private var source: RequestSource? = null
+ private var permissions: ArrayList? = null
+ private var grantedCallback: OnPermissionsGrantedCallback? = null
+ private var deniedCallback: OnPermissionsDeniedCallback? = null
+ private var rationaleResId: Int = 0
+ private var rationale: CharSequence? = null
+
+ private var rationaleDialog: AlertDialog? = null
+
+ private val deniedPermissions: Array?
+ get() {
+ return getDeniedPermissions(this.permissions?.toTypedArray())
+ }
+
+ constructor(activity: AppCompatActivity) {
+ source = ActivitySource(activity)
+ permissions = ArrayList()
+ requestTime = System.currentTimeMillis()
+ }
+
+ constructor(fragment: Fragment) {
+ source = FragmentSource(fragment)
+ permissions = ArrayList()
+ requestTime = System.currentTimeMillis()
+ }
+
+ fun addPermissions(vararg permissions: String) {
+ this.permissions?.addAll(listOf(*permissions))
+ }
+
+ fun setRequestCode(requestCode: Int) {
+ this.requestCode = requestCode
+ }
+
+ fun setOnGrantedCallback(callback: OnPermissionsGrantedCallback) {
+ grantedCallback = callback
+ }
+
+ fun setOnDeniedCallback(callback: OnPermissionsDeniedCallback) {
+ deniedCallback = callback
+ }
+
+ fun setRationale(@StringRes resId: Int) {
+ rationaleResId = resId
+ rationale = null
+ }
+
+ fun setRationale(rationale: CharSequence) {
+ this.rationale = rationale
+ rationaleResId = 0
+ }
+
+ fun start() {
+ RequestPlugins.setOnRequestPermissionsCallback(this)
+
+ val deniedPermissions = deniedPermissions
+
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
+ if (deniedPermissions == null) {
+ onPermissionsGranted(requestCode)
+ } else {
+ val rationale =
+ if (rationaleResId != 0) source?.context?.getText(rationaleResId) else rationale
+ if (rationale != null) {
+ showSettingDialog(rationale) {
+ onPermissionsDenied(
+ requestCode,
+ deniedPermissions
+ )
+ }
+ } else {
+ onPermissionsDenied(requestCode, deniedPermissions)
+ }
+ }
+ } else {
+ if (deniedPermissions != null) {
+ source?.context?.startActivity {
+ putExtra(PermissionActivity.KEY_INPUT_REQUEST_TYPE, TYPE_REQUEST_PERMISSION)
+ putExtra(PermissionActivity.KEY_INPUT_PERMISSIONS_CODE, requestCode)
+ putExtra(PermissionActivity.KEY_INPUT_PERMISSIONS, deniedPermissions)
+ }
+ } else {
+ onPermissionsGranted(requestCode)
+ }
+ }
+ }
+
+ fun clear() {
+ grantedCallback = null
+ deniedCallback = null
+ }
+
+ fun getDeniedPermissions(permissions: Array?): Array? {
+ if (permissions != null) {
+ val deniedPermissionList = ArrayList()
+ for (permission in permissions) {
+ if (source?.context?.let {
+ ContextCompat.checkSelfPermission(
+ it,
+ permission
+ )
+ } != PackageManager.PERMISSION_GRANTED
+ ) {
+ deniedPermissionList.add(permission)
+ }
+ }
+ val size = deniedPermissionList.size
+ if (size > 0) {
+ return deniedPermissionList.toTypedArray()
+ }
+ }
+ return null
+ }
+
+ private fun showSettingDialog(rationale: CharSequence, cancel: () -> Unit) {
+ rationaleDialog?.dismiss()
+ source?.context?.let {
+ runCatching {
+ rationaleDialog = AlertDialog.Builder(it)
+ .setTitle(R.string.dialog_title)
+ .setMessage(rationale)
+ .setPositiveButton(R.string.dialog_setting) { _, _ ->
+ it.startActivity {
+ putExtra(
+ PermissionActivity.KEY_INPUT_REQUEST_TYPE,
+ TYPE_REQUEST_SETTING
+ )
+ }
+ }
+ .setNegativeButton(R.string.dialog_cancel) { _, _ -> cancel() }
+ .show()
+ }
+ }
+ }
+
+ private fun onPermissionsGranted(requestCode: Int) {
+ try {
+ grantedCallback?.onPermissionsGranted(requestCode)
+ } catch (ignore: Exception) {
+ }
+
+ RequestPlugins.sResultCallback?.onPermissionsGranted(requestCode)
+ }
+
+ private fun onPermissionsDenied(requestCode: Int, deniedPermissions: Array) {
+ try {
+ deniedCallback?.onPermissionsDenied(requestCode, deniedPermissions)
+ } catch (ignore: Exception) {
+ }
+
+ RequestPlugins.sResultCallback?.onPermissionsDenied(requestCode, deniedPermissions)
+ }
+
+ override fun onRequestPermissionsResult(
+ requestCode: Int,
+ permissions: Array,
+ grantResults: IntArray
+ ) {
+ val deniedPermissions = getDeniedPermissions(permissions)
+ if (deniedPermissions != null) {
+ val rationale =
+ if (rationaleResId != 0) source?.context?.getText(rationaleResId) else rationale
+ if (rationale != null) {
+ showSettingDialog(rationale) { onPermissionsDenied(requestCode, deniedPermissions) }
+ } else {
+ onPermissionsDenied(requestCode, deniedPermissions)
+ }
+ } else {
+ onPermissionsGranted(requestCode)
+ }
+ }
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ val deniedPermissions = deniedPermissions
+ if (deniedPermissions == null) {
+ onPermissionsGranted(this.requestCode)
+ } else {
+ onPermissionsDenied(this.requestCode, deniedPermissions)
+ }
+ }
+
+ companion object {
+ const val TYPE_REQUEST_PERMISSION = 1
+ const val TYPE_REQUEST_SETTING = 2
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/io/legado/app/help/permission/RequestManager.kt b/app/src/main/java/io/legado/app/help/permission/RequestManager.kt
new file mode 100644
index 000000000..eb28b9e6c
--- /dev/null
+++ b/app/src/main/java/io/legado/app/help/permission/RequestManager.kt
@@ -0,0 +1,69 @@
+package io.legado.app.help.permission
+
+import android.os.Handler
+import android.os.Looper
+import java.util.*
+
+internal object RequestManager : OnPermissionsResultCallback {
+
+ private var requests: Stack? = null
+ private var request: Request? = null
+
+ private val handler = Handler(Looper.getMainLooper())
+
+ private val requestRunnable = Runnable {
+ request?.start()
+ }
+
+ private val isCurrentRequestInvalid: Boolean
+ get() = request?.let { System.currentTimeMillis() - it.requestTime > 5 * 1000L } ?: true
+
+ init {
+ RequestPlugins.setOnPermissionsResultCallback(this)
+ }
+
+ fun pushRequest(request: Request?) {
+ if (request == null) return
+
+ if (requests == null) {
+ requests = Stack()
+ }
+
+ requests?.let {
+ val index = it.indexOf(request)
+ if (index >= 0) {
+ val to = it.size - 1
+ if (index != to) {
+ @Suppress("NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS")
+ Collections.swap(requests, index, to)
+ }
+ } else {
+ it.push(request)
+ }
+
+ if (!it.empty() && isCurrentRequestInvalid) {
+ this.request = it.pop()
+ handler.post(requestRunnable)
+ }
+ }
+ }
+
+ private fun startNextRequest() {
+ request?.clear()
+ request = null
+
+ requests?.let {
+ request = if (it.empty()) null else it.pop()
+ request?.let { handler.post(requestRunnable) }
+ }
+ }
+
+ override fun onPermissionsGranted(requestCode: Int) {
+ startNextRequest()
+ }
+
+ override fun onPermissionsDenied(requestCode: Int, deniedPermissions: Array) {
+ startNextRequest()
+ }
+
+}
diff --git a/app/src/main/java/io/legado/app/help/permission/RequestPlugins.kt b/app/src/main/java/io/legado/app/help/permission/RequestPlugins.kt
new file mode 100644
index 000000000..16370193f
--- /dev/null
+++ b/app/src/main/java/io/legado/app/help/permission/RequestPlugins.kt
@@ -0,0 +1,20 @@
+package io.legado.app.help.permission
+
+internal object RequestPlugins {
+
+ @Volatile
+ var sRequestCallback: OnRequestPermissionsResultCallback? = null
+
+ @Volatile
+ var sResultCallback: OnPermissionsResultCallback? = null
+
+ fun setOnRequestPermissionsCallback(callback: OnRequestPermissionsResultCallback) {
+ sRequestCallback = callback
+ }
+
+ fun setOnPermissionsResultCallback(callback: OnPermissionsResultCallback) {
+ sResultCallback = callback
+ }
+
+
+}
diff --git a/app/src/main/java/io/legado/app/help/permission/RequestSource.kt b/app/src/main/java/io/legado/app/help/permission/RequestSource.kt
new file mode 100644
index 000000000..a822ff5ad
--- /dev/null
+++ b/app/src/main/java/io/legado/app/help/permission/RequestSource.kt
@@ -0,0 +1,12 @@
+package io.legado.app.help.permission
+
+import android.content.Context
+import android.content.Intent
+
+interface RequestSource {
+
+ val context: Context?
+
+ fun startActivity(intent: Intent)
+
+}
diff --git a/app/src/main/java/io/legado/app/ui/book/info/BookInfoViewModel.kt b/app/src/main/java/io/legado/app/ui/book/info/BookInfoViewModel.kt
index 3cb698ef3..8348dca02 100644
--- a/app/src/main/java/io/legado/app/ui/book/info/BookInfoViewModel.kt
+++ b/app/src/main/java/io/legado/app/ui/book/info/BookInfoViewModel.kt
@@ -68,7 +68,7 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
toastOnUi(R.string.error_get_book_info)
}
} ?: let {
- chapterListData.postValue(emptyList())
+ chapterListData.postValue(null)
toastOnUi(R.string.error_no_source)
}
}
@@ -104,11 +104,11 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
toastOnUi(R.string.chapter_list_empty)
}
}.onError {
- chapterListData.postValue(emptyList())
+ chapterListData.postValue(null)
toastOnUi(R.string.error_get_chapter_list)
}
} ?: let {
- chapterListData.postValue(emptyList())
+ chapterListData.postValue(null)
toastOnUi(R.string.error_no_source)
}
}
diff --git a/app/src/main/java/io/legado/app/ui/book/info/edit/BookInfoEditActivity.kt b/app/src/main/java/io/legado/app/ui/book/info/edit/BookInfoEditActivity.kt
index ee0e50d23..4d16ba6bd 100644
--- a/app/src/main/java/io/legado/app/ui/book/info/edit/BookInfoEditActivity.kt
+++ b/app/src/main/java/io/legado/app/ui/book/info/edit/BookInfoEditActivity.kt
@@ -1,18 +1,19 @@
package io.legado.app.ui.book.info.edit
import android.app.Activity
+import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
-import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
import androidx.documentfile.provider.DocumentFile
import io.legado.app.R
import io.legado.app.base.VMBaseActivity
-import io.legado.app.constant.Permissions
import io.legado.app.data.entities.Book
import io.legado.app.databinding.ActivityBookInfoEditBinding
+import io.legado.app.help.permission.Permissions
+import io.legado.app.help.permission.PermissionsCompat
import io.legado.app.ui.book.changecover.ChangeCoverDialog
import io.legado.app.utils.*
import java.io.File
@@ -21,9 +22,7 @@ class BookInfoEditActivity :
VMBaseActivity(),
ChangeCoverDialog.CallBack {
- private val selectCover = registerForActivityResult(ActivityResultContracts.GetContent()) {
- coverChangeTo(it)
- }
+ private val resultSelectCover = 132
override val viewModel: BookInfoEditViewModel
by viewModels()
@@ -61,7 +60,7 @@ class BookInfoEditActivity :
}
}
tvSelectCover.setOnClickListener {
- selectCover.launch("image/*")
+ selectImage()
}
tvRefreshCover.setOnClickListener {
viewModel.book?.customCoverUrl = tieCoverUrl.text?.toString()
@@ -97,6 +96,13 @@ class BookInfoEditActivity :
}
}
+ private fun selectImage() {
+ val intent = Intent(Intent.ACTION_GET_CONTENT)
+ intent.addCategory(Intent.CATEGORY_OPENABLE)
+ intent.type = "image/*"
+ startActivityForResult(intent, resultSelectCover)
+ }
+
override fun coverChangeTo(coverUrl: String) {
viewModel.book?.customCoverUrl = coverUrl
binding.tieCoverUrl.setText(coverUrl)
@@ -117,15 +123,13 @@ class BookInfoEditActivity :
} ?: toastOnUi("获取文件出错")
}
} else {
- registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) {
- var hasPermission = true
- it.forEach { (t, u) ->
- if (!u) {
- hasPermission = false
- toastOnUi(t)
- }
- }
- if (hasPermission) {
+ PermissionsCompat.Builder(this)
+ .addPermissions(
+ Permissions.READ_EXTERNAL_STORAGE,
+ Permissions.WRITE_EXTERNAL_STORAGE
+ )
+ .rationale(R.string.bg_image_per)
+ .onGranted {
RealPathUtil.getPath(this, uri)?.let { path ->
val imgFile = File(path)
if (imgFile.exists()) {
@@ -136,8 +140,20 @@ class BookInfoEditActivity :
}
}
}
- }.launch(Permissions.Group.STORAGE)
+ .request()
}
}
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ super.onActivityResult(requestCode, resultCode, data)
+ when (requestCode) {
+ resultSelectCover -> {
+ if (resultCode == Activity.RESULT_OK) {
+ data?.data?.let { uri ->
+ coverChangeTo(uri)
+ }
+ }
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/io/legado/app/ui/book/local/ImportBookActivity.kt b/app/src/main/java/io/legado/app/ui/book/local/ImportBookActivity.kt
index 5c5de45e5..776d980c5 100644
--- a/app/src/main/java/io/legado/app/ui/book/local/ImportBookActivity.kt
+++ b/app/src/main/java/io/legado/app/ui/book/local/ImportBookActivity.kt
@@ -8,7 +8,6 @@ import android.os.Bundle
import android.provider.DocumentsContract
import android.view.Menu
import android.view.MenuItem
-import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
import androidx.appcompat.widget.PopupMenu
import androidx.documentfile.provider.DocumentFile
@@ -16,10 +15,11 @@ import androidx.lifecycle.LiveData
import androidx.recyclerview.widget.LinearLayoutManager
import io.legado.app.R
import io.legado.app.base.VMBaseActivity
-import io.legado.app.constant.Permissions
import io.legado.app.data.appDb
import io.legado.app.databinding.ActivityImportBookBinding
import io.legado.app.help.AppConfig
+import io.legado.app.help.permission.Permissions
+import io.legado.app.help.permission.PermissionsCompat
import io.legado.app.lib.theme.backgroundColor
import io.legado.app.ui.filepicker.FilePicker
import io.legado.app.ui.filepicker.FilePickerDialog
@@ -148,21 +148,16 @@ class ImportBookActivity : VMBaseActivity {
binding.tvEmptyMsg.visible()
- registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) {
- var hasPermission = true
- it.forEach { (t, u) ->
- if (!u) {
- hasPermission = false
- toastOnUi(t)
- }
- }
- if (hasPermission) {
+ PermissionsCompat.Builder(this)
+ .addPermissions(*Permissions.Group.STORAGE)
+ .rationale(R.string.tip_perm_request_storage)
+ .onGranted {
rootDoc = null
subDocs.clear()
path = lastPath
upPath()
}
- }.launch(Permissions.Group.STORAGE)
+ .request()
}
}
}
diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt
index e9d8775de..7b4eee738 100644
--- a/app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt
+++ b/app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt
@@ -8,17 +8,17 @@ import android.graphics.Color
import android.net.Uri
import android.os.Bundle
import android.view.*
-import androidx.activity.result.contract.ActivityResultContracts
import androidx.documentfile.provider.DocumentFile
import com.jaredrummler.android.colorpicker.ColorPickerDialog
import io.legado.app.R
import io.legado.app.base.BaseDialogFragment
import io.legado.app.constant.EventBus
-import io.legado.app.constant.Permissions
import io.legado.app.databinding.DialogEditTextBinding
import io.legado.app.databinding.DialogReadBgTextBinding
import io.legado.app.databinding.ItemBgImageBinding
import io.legado.app.help.ReadBookConfig
+import io.legado.app.help.permission.Permissions
+import io.legado.app.help.permission.PermissionsCompat
import io.legado.app.lib.dialogs.alert
import io.legado.app.lib.theme.bottomBackground
import io.legado.app.lib.theme.getPrimaryTextColor
@@ -40,6 +40,7 @@ class BgTextConfigDialog : BaseDialogFragment(), FilePickerDialog.CallBack {
}
private val binding by viewBinding(DialogReadBgTextBinding::bind)
+ private val requestCodeBg = 123
private val requestCodeExport = 131
private val requestCodeImport = 132
private val configFileName = "readConfig.zip"
@@ -190,9 +191,10 @@ class BgTextConfigDialog : BaseDialogFragment(), FilePickerDialog.CallBack {
}
private fun selectImage() {
- registerForActivityResult(ActivityResultContracts.GetContent()) {
- setBgFromUri(it)
- }.launch("image/*")
+ val intent = Intent(Intent.ACTION_GET_CONTENT)
+ intent.addCategory(Intent.CATEGORY_OPENABLE)
+ intent.type = "image/*"
+ startActivityForResult(intent, requestCodeBg)
}
@Suppress("BlockingMethodInNonBlockingContext")
@@ -369,7 +371,13 @@ class BgTextConfigDialog : BaseDialogFragment(), FilePickerDialog.CallBack {
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
+ requestCodeBg -> if (resultCode == RESULT_OK) {
+ data?.data?.let { uri ->
+ setBgFromUri(uri)
+ }
+ }
requestCodeImport -> if (resultCode == RESULT_OK) {
data?.data?.let { uri ->
importConfig(uri)
@@ -399,13 +407,20 @@ class BgTextConfigDialog : BaseDialogFragment(), FilePickerDialog.CallBack {
} ?: toastOnUi("获取文件出错")
}
} else {
- registerForActivityResult(ActivityResultContracts.RequestPermission()) {
- RealPathUtil.getPath(requireContext(), uri)?.let { path ->
- ReadBookConfig.durConfig.setCurBg(2, path)
- ReadBookConfig.upBg()
- postEvent(EventBus.UP_CONFIG, false)
+ PermissionsCompat.Builder(this)
+ .addPermissions(
+ Permissions.READ_EXTERNAL_STORAGE,
+ Permissions.WRITE_EXTERNAL_STORAGE
+ )
+ .rationale(R.string.bg_image_per)
+ .onGranted {
+ RealPathUtil.getPath(requireContext(), uri)?.let { path ->
+ ReadBookConfig.durConfig.setCurBg(2, path)
+ ReadBookConfig.upBg()
+ postEvent(EventBus.UP_CONFIG, false)
+ }
}
- }.launch(Permissions.READ_EXTERNAL_STORAGE)
+ .request()
}
}
}
\ No newline at end of file
diff --git a/app/src/main/java/io/legado/app/ui/config/BackupRestoreUi.kt b/app/src/main/java/io/legado/app/ui/config/BackupRestoreUi.kt
index 85cb3cb82..5204ef6c1 100644
--- a/app/src/main/java/io/legado/app/ui/config/BackupRestoreUi.kt
+++ b/app/src/main/java/io/legado/app/ui/config/BackupRestoreUi.kt
@@ -7,10 +7,11 @@ import androidx.activity.result.contract.ActivityResultContracts
import androidx.documentfile.provider.DocumentFile
import androidx.fragment.app.Fragment
import io.legado.app.R
-import io.legado.app.constant.Permissions
import io.legado.app.constant.PreferKey
import io.legado.app.help.AppConfig
import io.legado.app.help.coroutine.Coroutine
+import io.legado.app.help.permission.Permissions
+import io.legado.app.help.permission.PermissionsCompat
import io.legado.app.help.storage.Backup
import io.legado.app.help.storage.BookWebDav
import io.legado.app.help.storage.ImportOldData
@@ -56,15 +57,10 @@ object BackupRestoreUi {
fragment: Fragment,
path: String
) {
- fragment.registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) {
- var hasPermission = true
- it.forEach { (t, u) ->
- if (!u) {
- hasPermission = false
- fragment.toastOnUi(t)
- }
- }
- if (hasPermission) {
+ PermissionsCompat.Builder(fragment)
+ .addPermissions(*Permissions.Group.STORAGE)
+ .rationale(R.string.tip_perm_request_storage)
+ .onGranted {
Coroutine.async {
AppConfig.backupPath = path
Backup.backup(fragment.requireContext(), path)
@@ -72,7 +68,7 @@ object BackupRestoreUi {
fragment.toastOnUi(R.string.backup_success)
}
}
- }.launch(Permissions.Group.STORAGE)
+ .request()
}
fun selectBackupFolder(fragment: Fragment, requestCode: Int = selectFolderRequestCode) {
diff --git a/app/src/main/java/io/legado/app/ui/config/OtherConfigFragment.kt b/app/src/main/java/io/legado/app/ui/config/OtherConfigFragment.kt
index 5d94d55e9..b44909711 100644
--- a/app/src/main/java/io/legado/app/ui/config/OtherConfigFragment.kt
+++ b/app/src/main/java/io/legado/app/ui/config/OtherConfigFragment.kt
@@ -10,18 +10,18 @@ import android.net.Uri
import android.os.Bundle
import android.os.Process
import android.view.View
-import androidx.activity.result.contract.ActivityResultContracts
import androidx.documentfile.provider.DocumentFile
import androidx.preference.ListPreference
import androidx.preference.Preference
import io.legado.app.R
import io.legado.app.base.BasePreferenceFragment
import io.legado.app.constant.EventBus
-import io.legado.app.constant.Permissions
import io.legado.app.constant.PreferKey
import io.legado.app.databinding.DialogEditTextBinding
import io.legado.app.help.AppConfig
import io.legado.app.help.BookHelp
+import io.legado.app.help.permission.Permissions
+import io.legado.app.help.permission.PermissionsCompat
import io.legado.app.lib.dialogs.alert
import io.legado.app.lib.dialogs.selector
import io.legado.app.lib.theme.ATH
@@ -224,18 +224,25 @@ class OtherConfigFragment : BasePreferenceFragment(),
} ?: toastOnUi("获取文件出错")
}
} else {
- registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) {
- RealPathUtil.getPath(requireContext(), uri)?.let { path ->
- val imgFile = File(path)
- if (imgFile.exists()) {
- var file = requireContext().externalFilesDir
- file = FileUtils.createFileIfNotExist(file, "covers", imgFile.name)
- file.writeBytes(imgFile.readBytes())
- putPrefString(PreferKey.defaultCover, file.absolutePath)
- CoverImageView.upDefaultCover()
+ PermissionsCompat.Builder(this)
+ .addPermissions(
+ Permissions.READ_EXTERNAL_STORAGE,
+ Permissions.WRITE_EXTERNAL_STORAGE
+ )
+ .rationale(R.string.bg_image_per)
+ .onGranted {
+ RealPathUtil.getPath(requireContext(), uri)?.let { path ->
+ val imgFile = File(path)
+ if (imgFile.exists()) {
+ var file = requireContext().externalFilesDir
+ file = FileUtils.createFileIfNotExist(file, "covers", imgFile.name)
+ file.writeBytes(imgFile.readBytes())
+ putPrefString(PreferKey.defaultCover, file.absolutePath)
+ CoverImageView.upDefaultCover()
+ }
}
}
- }.launch(Permissions.Group.STORAGE)
+ .request()
}
}
diff --git a/app/src/main/java/io/legado/app/ui/config/ThemeConfigFragment.kt b/app/src/main/java/io/legado/app/ui/config/ThemeConfigFragment.kt
index 18eee75ae..834e53eb9 100644
--- a/app/src/main/java/io/legado/app/ui/config/ThemeConfigFragment.kt
+++ b/app/src/main/java/io/legado/app/ui/config/ThemeConfigFragment.kt
@@ -1,6 +1,8 @@
package io.legado.app.ui.config
import android.annotation.SuppressLint
+import android.app.Activity
+import android.content.Intent
import android.content.SharedPreferences
import android.net.Uri
import android.os.Build
@@ -9,19 +11,19 @@ import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
-import androidx.activity.result.contract.ActivityResultContracts
import androidx.documentfile.provider.DocumentFile
import androidx.preference.Preference
import io.legado.app.R
import io.legado.app.base.BasePreferenceFragment
import io.legado.app.constant.AppConst
import io.legado.app.constant.EventBus
-import io.legado.app.constant.Permissions
import io.legado.app.constant.PreferKey
import io.legado.app.databinding.DialogEditTextBinding
import io.legado.app.help.AppConfig
import io.legado.app.help.LauncherIconHelp
import io.legado.app.help.ThemeConfig
+import io.legado.app.help.permission.Permissions
+import io.legado.app.help.permission.PermissionsCompat
import io.legado.app.lib.dialogs.alert
import io.legado.app.lib.dialogs.selector
import io.legado.app.lib.theme.ATH
@@ -36,17 +38,8 @@ import java.io.File
class ThemeConfigFragment : BasePreferenceFragment(),
SharedPreferences.OnSharedPreferenceChangeListener {
- private val setLightBgImage = registerForActivityResult(ActivityResultContracts.GetContent()) {
- setBgFromUri(it, PreferKey.bgImage) {
- upTheme(false)
- }
- }
-
- private val setDarkBgImage = registerForActivityResult(ActivityResultContracts.GetContent()) {
- setBgFromUri(it, PreferKey.bgImageN) {
- upTheme(false)
- }
- }
+ private val requestCodeBgImage = 234
+ private val requestCodeBgImageN = 342
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
addPreferencesFromResource(R.xml.pref_config_theme)
@@ -193,26 +186,26 @@ class ThemeConfigFragment : BasePreferenceFragment(),
"themeList" -> ThemeListDialog().show(childFragmentManager, "themeList")
"saveDayTheme", "saveNightTheme" -> saveThemeAlert(key)
PreferKey.bgImage -> if (getPrefString(PreferKey.bgImage).isNullOrEmpty()) {
- setLightBgImage.launch("image/*")
+ selectImage(requestCodeBgImage)
} else {
selector(items = arrayListOf("删除图片", "选择图片")) { _, i ->
if (i == 0) {
removePref(PreferKey.bgImage)
upTheme(false)
} else {
- setLightBgImage.launch("image/*")
+ selectImage(requestCodeBgImage)
}
}
}
PreferKey.bgImageN -> if (getPrefString(PreferKey.bgImageN).isNullOrEmpty()) {
- setDarkBgImage.launch("image/*")
+ selectImage(requestCodeBgImageN)
} else {
selector(items = arrayListOf("删除图片", "选择图片")) { _, i ->
if (i == 0) {
removePref(PreferKey.bgImageN)
upTheme(true)
} else {
- setDarkBgImage.launch("image/*")
+ selectImage(requestCodeBgImageN)
}
}
}
@@ -220,6 +213,13 @@ class ThemeConfigFragment : BasePreferenceFragment(),
return super.onPreferenceTreeClick(preference)
}
+ private fun selectImage(requestCode: Int) {
+ val intent = Intent(Intent.ACTION_GET_CONTENT)
+ intent.addCategory(Intent.CATEGORY_OPENABLE)
+ intent.type = "image/*"
+ startActivityForResult(intent, requestCode)
+ }
+
@SuppressLint("InflateParams")
private fun saveThemeAlert(key: String) {
alert(R.string.theme_name) {
@@ -279,15 +279,13 @@ class ThemeConfigFragment : BasePreferenceFragment(),
} ?: toastOnUi("获取文件出错")
}
} else {
- registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) {
- var hasPermission = true
- it.forEach { (t, u) ->
- if (!u) {
- hasPermission = false
- toastOnUi(t)
- }
- }
- if (hasPermission) {
+ PermissionsCompat.Builder(this)
+ .addPermissions(
+ Permissions.READ_EXTERNAL_STORAGE,
+ Permissions.WRITE_EXTERNAL_STORAGE
+ )
+ .rationale(R.string.bg_image_per)
+ .onGranted {
RealPathUtil.getPath(requireContext(), uri)?.let { path ->
val imgFile = File(path)
if (imgFile.exists()) {
@@ -300,7 +298,27 @@ class ThemeConfigFragment : BasePreferenceFragment(),
}
}
}
- }.launch(Permissions.Group.STORAGE)
+ .request()
+ }
+ }
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ super.onActivityResult(requestCode, resultCode, data)
+ when (requestCode) {
+ requestCodeBgImage -> if (resultCode == Activity.RESULT_OK) {
+ data?.data?.let { uri ->
+ setBgFromUri(uri, PreferKey.bgImage) {
+ upTheme(false)
+ }
+ }
+ }
+ requestCodeBgImageN -> if (resultCode == Activity.RESULT_OK) {
+ data?.data?.let { uri ->
+ setBgFromUri(uri, PreferKey.bgImageN) {
+ upTheme(true)
+ }
+ }
+ }
}
}
diff --git a/app/src/main/java/io/legado/app/ui/filepicker/FilePicker.kt b/app/src/main/java/io/legado/app/ui/filepicker/FilePicker.kt
index e05687953..ff099f9ff 100644
--- a/app/src/main/java/io/legado/app/ui/filepicker/FilePicker.kt
+++ b/app/src/main/java/io/legado/app/ui/filepicker/FilePicker.kt
@@ -5,6 +5,8 @@ import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import io.legado.app.R
+import io.legado.app.help.permission.Permissions
+import io.legado.app.help.permission.PermissionsCompat
import io.legado.app.lib.dialogs.alert
@Suppress("unused")
@@ -32,21 +34,25 @@ object FilePicker {
val intent = createSelectDirIntent()
activity.startActivityForResult(intent, requestCode)
}.onFailure {
- FilePickerDialog.show(
- activity.supportFragmentManager,
- requestCode,
- mode = FilePickerDialog.DIRECTORY
- )
+ checkPermissions(activity) {
+ FilePickerDialog.show(
+ activity.supportFragmentManager,
+ requestCode,
+ mode = FilePickerDialog.DIRECTORY
+ )
+ }
}
}
else -> {
val selectText = selectList[index]
if (selectText == activity.getString(R.string.app_folder_picker)) {
- FilePickerDialog.show(
- activity.supportFragmentManager,
- requestCode,
- mode = FilePickerDialog.DIRECTORY
- )
+ checkPermissions(activity) {
+ FilePickerDialog.show(
+ activity.supportFragmentManager,
+ requestCode,
+ mode = FilePickerDialog.DIRECTORY
+ )
+ }
} else {
otherFun?.invoke(selectText)
}
@@ -78,21 +84,25 @@ object FilePicker {
val intent = createSelectDirIntent()
fragment.startActivityForResult(intent, requestCode)
}.onFailure {
- FilePickerDialog.show(
- fragment.childFragmentManager,
- requestCode,
- mode = FilePickerDialog.DIRECTORY
- )
+ checkPermissions(fragment) {
+ FilePickerDialog.show(
+ fragment.childFragmentManager,
+ requestCode,
+ mode = FilePickerDialog.DIRECTORY
+ )
+ }
}
}
else -> {
val selectText = selectList[index]
if (selectText == fragment.getString(R.string.app_folder_picker)) {
- FilePickerDialog.show(
- fragment.childFragmentManager,
- requestCode,
- mode = FilePickerDialog.DIRECTORY
- )
+ checkPermissions(fragment) {
+ FilePickerDialog.show(
+ fragment.childFragmentManager,
+ requestCode,
+ mode = FilePickerDialog.DIRECTORY
+ )
+ }
} else {
otherFun?.invoke(selectText)
}
@@ -129,23 +139,27 @@ object FilePicker {
)
activity.startActivityForResult(intent, requestCode)
}.onFailure {
- FilePickerDialog.show(
- activity.supportFragmentManager,
- requestCode,
- mode = FilePickerDialog.FILE,
- allowExtensions = allowExtensions
- )
+ checkPermissions(activity) {
+ FilePickerDialog.show(
+ activity.supportFragmentManager,
+ requestCode,
+ mode = FilePickerDialog.FILE,
+ allowExtensions = allowExtensions
+ )
+ }
}
}
else -> {
val selectText = selectList[index]
if (selectText == activity.getString(R.string.app_file_picker)) {
- FilePickerDialog.show(
- activity.supportFragmentManager,
- requestCode,
- mode = FilePickerDialog.FILE,
- allowExtensions = allowExtensions
- )
+ checkPermissions(activity) {
+ FilePickerDialog.show(
+ activity.supportFragmentManager,
+ requestCode,
+ mode = FilePickerDialog.FILE,
+ allowExtensions = allowExtensions
+ )
+ }
} else {
otherFun?.invoke(selectText)
}
@@ -182,23 +196,27 @@ object FilePicker {
)
fragment.startActivityForResult(intent, requestCode)
}.onFailure {
- FilePickerDialog.show(
- fragment.childFragmentManager,
- requestCode,
- mode = FilePickerDialog.FILE,
- allowExtensions = allowExtensions
- )
+ checkPermissions(fragment) {
+ FilePickerDialog.show(
+ fragment.childFragmentManager,
+ requestCode,
+ mode = FilePickerDialog.FILE,
+ allowExtensions = allowExtensions
+ )
+ }
}
}
else -> {
val selectText = selectList[index]
if (selectText == fragment.getString(R.string.app_file_picker)) {
- FilePickerDialog.show(
- fragment.childFragmentManager,
- requestCode,
- mode = FilePickerDialog.FILE,
- allowExtensions = allowExtensions
- )
+ checkPermissions(fragment) {
+ FilePickerDialog.show(
+ fragment.childFragmentManager,
+ requestCode,
+ mode = FilePickerDialog.FILE,
+ allowExtensions = allowExtensions
+ )
+ }
} else {
otherFun?.invoke(selectText)
}
@@ -228,6 +246,26 @@ object FilePicker {
return intent
}
+ private fun checkPermissions(fragment: Fragment, success: (() -> Unit)? = null) {
+ PermissionsCompat.Builder(fragment)
+ .addPermissions(*Permissions.Group.STORAGE)
+ .rationale(R.string.tip_perm_request_storage)
+ .onGranted {
+ success?.invoke()
+ }
+ .request()
+ }
+
+ private fun checkPermissions(activity: AppCompatActivity, success: (() -> Unit)? = null) {
+ PermissionsCompat.Builder(activity)
+ .addPermissions(*Permissions.Group.STORAGE)
+ .rationale(R.string.tip_perm_request_storage)
+ .onGranted {
+ success?.invoke()
+ }
+ .request()
+ }
+
private fun typesOfExtensions(allowExtensions: Array): Array {
val types = hashSetOf()
if (allowExtensions.isNullOrEmpty()) {
diff --git a/app/src/main/java/io/legado/app/ui/filepicker/FilePickerDialog.kt b/app/src/main/java/io/legado/app/ui/filepicker/FilePickerDialog.kt
index 5e0762775..ba708b677 100644
--- a/app/src/main/java/io/legado/app/ui/filepicker/FilePickerDialog.kt
+++ b/app/src/main/java/io/legado/app/ui/filepicker/FilePickerDialog.kt
@@ -15,8 +15,8 @@ import androidx.fragment.app.FragmentManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import io.legado.app.R
-import io.legado.app.constant.Permissions
import io.legado.app.databinding.DialogFileChooserBinding
+import io.legado.app.help.permission.Permissions
import io.legado.app.lib.theme.primaryColor
import io.legado.app.ui.filepicker.adapter.FileAdapter
import io.legado.app.ui.filepicker.adapter.PathAdapter
diff --git a/app/src/main/java/io/legado/app/ui/rss/read/ReadRssViewModel.kt b/app/src/main/java/io/legado/app/ui/rss/read/ReadRssViewModel.kt
index cf3574f2e..f4cc85fff 100644
--- a/app/src/main/java/io/legado/app/ui/rss/read/ReadRssViewModel.kt
+++ b/app/src/main/java/io/legado/app/ui/rss/read/ReadRssViewModel.kt
@@ -53,7 +53,7 @@ class ReadRssViewModel(application: Application) : BaseViewModel(application),
rssArticle = rssStar?.toRssArticle() ?: appDb.rssArticleDao.get(origin, link)
rssArticle?.let { rssArticle ->
if (!rssArticle.description.isNullOrBlank()) {
- contentLiveData.postValue(rssArticle.description!!)
+ contentLiveData.postValue(rssArticle.description)
} else {
rssSource?.let {
val ruleContent = it.ruleContent
diff --git a/app/src/main/java/io/legado/app/ui/widget/font/FontSelectDialog.kt b/app/src/main/java/io/legado/app/ui/widget/font/FontSelectDialog.kt
index e14f27591..004d3204b 100644
--- a/app/src/main/java/io/legado/app/ui/widget/font/FontSelectDialog.kt
+++ b/app/src/main/java/io/legado/app/ui/widget/font/FontSelectDialog.kt
@@ -8,16 +8,16 @@ import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
-import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.widget.Toolbar
import androidx.documentfile.provider.DocumentFile
import androidx.recyclerview.widget.LinearLayoutManager
import io.legado.app.R
import io.legado.app.base.BaseDialogFragment
-import io.legado.app.constant.Permissions
import io.legado.app.constant.PreferKey
import io.legado.app.databinding.DialogFontSelectBinding
import io.legado.app.help.AppConfig
+import io.legado.app.help.permission.Permissions
+import io.legado.app.help.permission.PermissionsCompat
import io.legado.app.lib.dialogs.alert
import io.legado.app.lib.theme.primaryColor
import io.legado.app.ui.filepicker.FilePicker
@@ -162,18 +162,13 @@ class FontSelectDialog : BaseDialogFragment(),
}
private fun loadFontFilesByPermission(path: String) {
- registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) {
- var hasPermission = true
- it.forEach { (t, u) ->
- if (!u) {
- hasPermission = false
- toastOnUi(t)
- }
- }
- if (hasPermission) {
+ PermissionsCompat.Builder(this@FontSelectDialog)
+ .addPermissions(*Permissions.Group.STORAGE)
+ .rationale(R.string.tip_perm_request_storage)
+ .onGranted {
loadFontFiles(path)
}
- }.launch(Permissions.Group.STORAGE)
+ .request()
}
private fun loadFontFiles(path: String) {