优化
This commit is contained in:
@@ -4,8 +4,11 @@ import android.content.Intent
|
|||||||
import android.os.IBinder
|
import android.os.IBinder
|
||||||
import androidx.annotation.CallSuper
|
import androidx.annotation.CallSuper
|
||||||
import androidx.lifecycle.LifecycleService
|
import androidx.lifecycle.LifecycleService
|
||||||
|
import io.legado.app.R
|
||||||
import io.legado.app.help.LifecycleHelp
|
import io.legado.app.help.LifecycleHelp
|
||||||
import io.legado.app.help.coroutine.Coroutine
|
import io.legado.app.help.coroutine.Coroutine
|
||||||
|
import io.legado.app.lib.permission.Permissions
|
||||||
|
import io.legado.app.lib.permission.PermissionsCompat
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
@@ -22,6 +25,7 @@ abstract class BaseService : LifecycleService(), CoroutineScope by MainScope() {
|
|||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
LifecycleHelp.onServiceCreate(this)
|
LifecycleHelp.onServiceCreate(this)
|
||||||
|
checkNotificationPermission()
|
||||||
}
|
}
|
||||||
|
|
||||||
@CallSuper
|
@CallSuper
|
||||||
@@ -41,4 +45,24 @@ abstract class BaseService : LifecycleService(), CoroutineScope by MainScope() {
|
|||||||
cancel()
|
cancel()
|
||||||
LifecycleHelp.onServiceDestroy(this)
|
LifecycleHelp.onServiceDestroy(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新通知
|
||||||
|
*/
|
||||||
|
open fun upNotification() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检测通知权限
|
||||||
|
*/
|
||||||
|
private fun checkNotificationPermission() {
|
||||||
|
PermissionsCompat.Builder()
|
||||||
|
.addPermissions(Permissions.POST_NOTIFICATIONS)
|
||||||
|
.rationale(R.string.notification_permission_rationale)
|
||||||
|
.onGranted {
|
||||||
|
upNotification()
|
||||||
|
}
|
||||||
|
.request()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
package io.legado.app.lib.permission
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
|
||||||
|
|
||||||
import java.lang.ref.WeakReference
|
|
||||||
|
|
||||||
internal class ActivitySource(activity: AppCompatActivity) : RequestSource {
|
|
||||||
|
|
||||||
private val actRef: WeakReference<AppCompatActivity> = WeakReference(activity)
|
|
||||||
|
|
||||||
override val context: Context?
|
|
||||||
get() = actRef.get()
|
|
||||||
|
|
||||||
override fun startActivity(intent: Intent) {
|
|
||||||
actRef.get()?.startActivity(intent)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
package io.legado.app.lib.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<Fragment> = WeakReference(fragment)
|
|
||||||
|
|
||||||
override val context: Context?
|
|
||||||
get() = fragRef.get()?.requireContext()
|
|
||||||
|
|
||||||
override fun startActivity(intent: Intent) {
|
|
||||||
fragRef.get()?.startActivity(intent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -7,6 +7,7 @@ import android.os.Bundle
|
|||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
import android.view.KeyEvent
|
import android.view.KeyEvent
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.app.ActivityCompat
|
import androidx.core.app.ActivityCompat
|
||||||
import io.legado.app.R
|
import io.legado.app.R
|
||||||
@@ -15,6 +16,8 @@ import io.legado.app.utils.toastOnUi
|
|||||||
|
|
||||||
class PermissionActivity : AppCompatActivity() {
|
class PermissionActivity : AppCompatActivity() {
|
||||||
|
|
||||||
|
private var rationaleDialog: AlertDialog? = null
|
||||||
|
|
||||||
private val settingActivityResult =
|
private val settingActivityResult =
|
||||||
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
|
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
|
||||||
RequestPlugins.sRequestCallback?.onSettingActivityResult()
|
RequestPlugins.sRequestCallback?.onSettingActivityResult()
|
||||||
@@ -23,42 +26,45 @@ class PermissionActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
val rationale = intent.getStringExtra(KEY_RATIONALE)
|
||||||
val requestCode = intent.getIntExtra(KEY_INPUT_PERMISSIONS_CODE, 1000)
|
val requestCode = intent.getIntExtra(KEY_INPUT_PERMISSIONS_CODE, 1000)
|
||||||
val permissions = intent.getStringArrayExtra(KEY_INPUT_PERMISSIONS)
|
val permissions = intent.getStringArrayExtra(KEY_INPUT_PERMISSIONS)!!
|
||||||
when (intent.getIntExtra(KEY_INPUT_REQUEST_TYPE, Request.TYPE_REQUEST_PERMISSION)) {
|
when (intent.getIntExtra(KEY_INPUT_REQUEST_TYPE, Request.TYPE_REQUEST_PERMISSION)) {
|
||||||
//权限请求
|
//权限请求
|
||||||
Request.TYPE_REQUEST_PERMISSION -> {
|
Request.TYPE_REQUEST_PERMISSION -> showSettingDialog(permissions, rationale){
|
||||||
if (permissions != null) {
|
ActivityCompat.requestPermissions(this, permissions, requestCode)
|
||||||
ActivityCompat.requestPermissions(this, permissions, requestCode)
|
}
|
||||||
} else {
|
//跳转到设置界面
|
||||||
|
Request.TYPE_REQUEST_SETTING -> showSettingDialog(permissions, rationale) {
|
||||||
|
openSettingsActivity()
|
||||||
|
}
|
||||||
|
//所有文件的管理权限
|
||||||
|
Request.TYPE_MANAGE_ALL_FILES_ACCESS -> showSettingDialog(permissions, rationale) {
|
||||||
|
try {
|
||||||
|
if (Permissions.isManageExternalStorage()) {
|
||||||
|
val settingIntent = Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION)
|
||||||
|
settingActivityResult.launch(settingIntent)
|
||||||
|
} else {
|
||||||
|
throw NoStackTraceException("no MANAGE_ALL_FILES_ACCESS_PERMISSION")
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
toastOnUi(e.localizedMessage)
|
||||||
|
RequestPlugins.sRequestCallback?.onError(e)
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//跳转到设置界面
|
Request.TYPE_REQUEST_NOTIFICATIONS -> showSettingDialog(permissions, rationale) {
|
||||||
Request.TYPE_REQUEST_SETTING -> openSettingsActivity()
|
kotlin.runCatching {
|
||||||
//所有文件的管理权限
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
Request.TYPE_MANAGE_ALL_FILES_ACCESS_PERMISSION -> try {
|
//这种方案适用于 API 26, 即8.0(含8.0)以上可以用
|
||||||
if (Permissions.isManageExternalStorage()) {
|
val intent = Intent()
|
||||||
val settingIntent = Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION)
|
intent.action = Settings.ACTION_APP_NOTIFICATION_SETTINGS
|
||||||
settingActivityResult.launch(settingIntent)
|
intent.putExtra(Settings.EXTRA_APP_PACKAGE, packageName)
|
||||||
} else {
|
intent.putExtra(Settings.EXTRA_CHANNEL_ID, applicationInfo.uid)
|
||||||
throw NoStackTraceException("no MANAGE_ALL_FILES_ACCESS_PERMISSION")
|
settingActivityResult.launch(intent)
|
||||||
}
|
} else {
|
||||||
} catch (e: Exception) {
|
openSettingsActivity()
|
||||||
toastOnUi(e.localizedMessage)
|
}
|
||||||
RequestPlugins.sRequestCallback?.onError(e)
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
Request.TYPE_REQUEST_NOTIFICATIONS -> kotlin.runCatching {
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
||||||
//这种方案适用于 API 26, 即8.0(含8.0)以上可以用
|
|
||||||
val intent = Intent()
|
|
||||||
intent.action = Settings.ACTION_APP_NOTIFICATION_SETTINGS
|
|
||||||
intent.putExtra(Settings.EXTRA_APP_PACKAGE, packageName)
|
|
||||||
intent.putExtra(Settings.EXTRA_CHANNEL_ID, applicationInfo.uid)
|
|
||||||
settingActivityResult.launch(intent)
|
|
||||||
} else {
|
|
||||||
openSettingsActivity()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -106,8 +112,34 @@ class PermissionActivity : AppCompatActivity() {
|
|||||||
} else super.onKeyDown(keyCode, event)
|
} else super.onKeyDown(keyCode, event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun showSettingDialog(
|
||||||
|
permissions: Array<String>,
|
||||||
|
rationale: CharSequence?,
|
||||||
|
onOk: () -> Unit
|
||||||
|
) {
|
||||||
|
rationaleDialog?.dismiss()
|
||||||
|
if (rationale.isNullOrEmpty()) {
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
rationaleDialog = AlertDialog.Builder(this)
|
||||||
|
.setTitle(R.string.dialog_title)
|
||||||
|
.setMessage(rationale)
|
||||||
|
.setPositiveButton(R.string.dialog_setting) { _, _ ->
|
||||||
|
onOk.invoke()
|
||||||
|
}
|
||||||
|
.setNegativeButton(R.string.dialog_cancel) { _, _ ->
|
||||||
|
RequestPlugins.sRequestCallback?.onRequestPermissionsResult(
|
||||||
|
permissions,
|
||||||
|
IntArray(0)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
|
const val KEY_RATIONALE = "KEY_RATIONALE"
|
||||||
const val KEY_INPUT_REQUEST_TYPE = "KEY_INPUT_REQUEST_TYPE"
|
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_CODE = "KEY_INPUT_PERMISSIONS_CODE"
|
||||||
const val KEY_INPUT_PERMISSIONS = "KEY_INPUT_PERMISSIONS"
|
const val KEY_INPUT_PERMISSIONS = "KEY_INPUT_PERMISSIONS"
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
package io.legado.app.lib.permission
|
package io.legado.app.lib.permission
|
||||||
|
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
class PermissionsCompat private constructor() {
|
class PermissionsCompat private constructor() {
|
||||||
@@ -14,15 +12,7 @@ class PermissionsCompat private constructor() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Builder {
|
class Builder {
|
||||||
private val request: Request
|
private val request: Request = Request()
|
||||||
|
|
||||||
constructor(activity: AppCompatActivity) {
|
|
||||||
request = Request(activity)
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(fragment: Fragment) {
|
|
||||||
request = Request(fragment)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addPermissions(vararg permissions: String): Builder {
|
fun addPermissions(vararg permissions: String): Builder {
|
||||||
request.addPermissions(*permissions)
|
request.addPermissions(*permissions)
|
||||||
|
|||||||
@@ -4,48 +4,29 @@ import android.content.pm.PackageManager
|
|||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Environment
|
import android.os.Environment
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.appcompat.app.AlertDialog
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
|
||||||
import androidx.core.app.NotificationManagerCompat
|
import androidx.core.app.NotificationManagerCompat
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import io.legado.app.R
|
|
||||||
import io.legado.app.utils.startActivity
|
import io.legado.app.utils.startActivity
|
||||||
import splitties.init.appCtx
|
import splitties.init.appCtx
|
||||||
|
|
||||||
@Suppress("MemberVisibilityCanBePrivate")
|
@Suppress("MemberVisibilityCanBePrivate")
|
||||||
internal class Request : OnRequestPermissionsResultCallback {
|
internal class Request : OnRequestPermissionsResultCallback {
|
||||||
|
|
||||||
internal val requestTime: Long
|
internal val requestTime: Long = System.currentTimeMillis()
|
||||||
private var requestCode: Int = TYPE_REQUEST_PERMISSION
|
private var requestCode: Int = TYPE_REQUEST_PERMISSION
|
||||||
private var source: RequestSource? = null
|
private var permissions: ArrayList<String> = ArrayList()
|
||||||
private var permissions: ArrayList<String>? = null
|
|
||||||
private var grantedCallback: OnPermissionsGrantedCallback? = null
|
private var grantedCallback: OnPermissionsGrantedCallback? = null
|
||||||
private var deniedCallback: OnPermissionsDeniedCallback? = null
|
private var deniedCallback: OnPermissionsDeniedCallback? = null
|
||||||
private var errorCallback: OnErrorCallback? = null
|
private var errorCallback: OnErrorCallback? = null
|
||||||
private var rationale: CharSequence? = null
|
private var rationale: CharSequence? = null
|
||||||
|
|
||||||
private var rationaleDialog: AlertDialog? = null
|
|
||||||
|
|
||||||
private val deniedPermissions: Array<String>?
|
private val deniedPermissions: Array<String>?
|
||||||
get() {
|
get() {
|
||||||
return getDeniedPermissions(this.permissions?.toTypedArray())
|
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) {
|
fun addPermissions(vararg permissions: String) {
|
||||||
this.permissions?.addAll(listOf(*permissions))
|
this.permissions.addAll(listOf(*permissions))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setOnGrantedCallback(callback: OnPermissionsGrantedCallback) {
|
fun setOnGrantedCallback(callback: OnPermissionsGrantedCallback) {
|
||||||
@@ -61,7 +42,7 @@ internal class Request : OnRequestPermissionsResultCallback {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun setRationale(@StringRes resId: Int) {
|
fun setRationale(@StringRes resId: Int) {
|
||||||
rationale = source?.context?.getString(resId)
|
rationale = appCtx.getString(resId)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setRationale(rationale: CharSequence) {
|
fun setRationale(rationale: CharSequence) {
|
||||||
@@ -82,22 +63,16 @@ internal class Request : OnRequestPermissionsResultCallback {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
||||||
showSettingDialog(deniedPermissions, rationale) {
|
toSetting()
|
||||||
toSetting()
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (deniedPermissions.contains(Permissions.MANAGE_EXTERNAL_STORAGE)) {
|
if (deniedPermissions.contains(Permissions.MANAGE_EXTERNAL_STORAGE)) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||||
showSettingDialog(deniedPermissions, rationale) {
|
toManageFileSetting()
|
||||||
toManageFileSetting()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (deniedPermissions.contains(Permissions.POST_NOTIFICATIONS)) {
|
} else if (deniedPermissions.contains(Permissions.POST_NOTIFICATIONS)) {
|
||||||
showSettingDialog(deniedPermissions, rationale) {
|
toNotificationSetting()
|
||||||
toNotificationSetting()
|
|
||||||
}
|
|
||||||
} else if (deniedPermissions.size > 1) {
|
} else if (deniedPermissions.size > 1) {
|
||||||
source?.context?.startActivity<PermissionActivity> {
|
appCtx.startActivity<PermissionActivity> {
|
||||||
putExtra(PermissionActivity.KEY_INPUT_REQUEST_TYPE, TYPE_REQUEST_PERMISSION)
|
putExtra(PermissionActivity.KEY_INPUT_REQUEST_TYPE, TYPE_REQUEST_PERMISSION)
|
||||||
putExtra(PermissionActivity.KEY_INPUT_PERMISSIONS_CODE, requestCode)
|
putExtra(PermissionActivity.KEY_INPUT_PERMISSIONS_CODE, requestCode)
|
||||||
putExtra(PermissionActivity.KEY_INPUT_PERMISSIONS, deniedPermissions)
|
putExtra(PermissionActivity.KEY_INPUT_PERMISSIONS, deniedPermissions)
|
||||||
@@ -111,92 +86,39 @@ internal class Request : OnRequestPermissionsResultCallback {
|
|||||||
deniedCallback = null
|
deniedCallback = null
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getDeniedPermissions(permissions: Array<String>?): Array<String>? {
|
fun getDeniedPermissions(permissions: Array<String>): Array<String>? {
|
||||||
val context = source?.context ?: return permissions
|
val deniedPermissionList = ArrayList<String>()
|
||||||
if (permissions != null) {
|
for (permission in permissions) {
|
||||||
val deniedPermissionList = ArrayList<String>()
|
when (permission) {
|
||||||
for (permission in permissions) {
|
Permissions.POST_NOTIFICATIONS -> {
|
||||||
when (permission) {
|
if (!NotificationManagerCompat.from(appCtx).areNotificationsEnabled()) {
|
||||||
Permissions.POST_NOTIFICATIONS -> {
|
deniedPermissionList.add(permission)
|
||||||
if (!NotificationManagerCompat.from(appCtx).areNotificationsEnabled()) {
|
|
||||||
deniedPermissionList.add(permission)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Permissions.MANAGE_EXTERNAL_STORAGE -> {
|
}
|
||||||
if (Permissions.isManageExternalStorage()) {
|
Permissions.MANAGE_EXTERNAL_STORAGE -> {
|
||||||
if (!Environment.isExternalStorageManager()) {
|
if (Permissions.isManageExternalStorage()) {
|
||||||
deniedPermissionList.add(permission)
|
if (!Environment.isExternalStorageManager()) {
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
if (
|
|
||||||
ContextCompat.checkSelfPermission(context, permission)
|
|
||||||
!= PackageManager.PERMISSION_GRANTED
|
|
||||||
) {
|
|
||||||
deniedPermissionList.add(permission)
|
deniedPermissionList.add(permission)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else -> {
|
||||||
|
if (
|
||||||
|
ContextCompat.checkSelfPermission(appCtx, permission)
|
||||||
|
!= PackageManager.PERMISSION_GRANTED
|
||||||
|
) {
|
||||||
|
deniedPermissionList.add(permission)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
val size = deniedPermissionList.size
|
}
|
||||||
if (size > 0) {
|
val size = deniedPermissionList.size
|
||||||
return deniedPermissionList.toTypedArray()
|
if (size > 0) {
|
||||||
}
|
return deniedPermissionList.toTypedArray()
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showSettingDialog(
|
|
||||||
permissions: Array<String>,
|
|
||||||
rationale: CharSequence,
|
|
||||||
onOk: () -> Unit
|
|
||||||
) {
|
|
||||||
rationaleDialog?.dismiss()
|
|
||||||
source?.context?.let {
|
|
||||||
runCatching {
|
|
||||||
rationaleDialog = AlertDialog.Builder(it)
|
|
||||||
.setTitle(R.string.dialog_title)
|
|
||||||
.setMessage(rationale)
|
|
||||||
.setPositiveButton(R.string.dialog_setting) { _, _ ->
|
|
||||||
onOk.invoke()
|
|
||||||
}
|
|
||||||
.setNegativeButton(R.string.dialog_cancel) { _, _ ->
|
|
||||||
onPermissionsDenied(permissions)
|
|
||||||
}
|
|
||||||
.show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun toSetting() {
|
|
||||||
source?.context?.startActivity<PermissionActivity> {
|
|
||||||
putExtra(
|
|
||||||
PermissionActivity.KEY_INPUT_REQUEST_TYPE,
|
|
||||||
TYPE_REQUEST_SETTING
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun toManageFileSetting() {
|
|
||||||
source?.context?.startActivity<PermissionActivity> {
|
|
||||||
putExtra(
|
|
||||||
PermissionActivity.KEY_INPUT_REQUEST_TYPE,
|
|
||||||
TYPE_MANAGE_ALL_FILES_ACCESS_PERMISSION
|
|
||||||
)
|
|
||||||
putExtra(PermissionActivity.KEY_INPUT_PERMISSIONS_CODE, requestCode)
|
|
||||||
putExtra(PermissionActivity.KEY_INPUT_PERMISSIONS, deniedPermissions)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun toNotificationSetting() {
|
|
||||||
source?.context?.startActivity<PermissionActivity> {
|
|
||||||
putExtra(PermissionActivity.KEY_INPUT_REQUEST_TYPE, TYPE_REQUEST_NOTIFICATIONS)
|
|
||||||
putExtra(PermissionActivity.KEY_INPUT_PERMISSIONS_CODE, requestCode)
|
|
||||||
putExtra(PermissionActivity.KEY_INPUT_PERMISSIONS, deniedPermissions)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun onPermissionsGranted() {
|
private fun onPermissionsGranted() {
|
||||||
try {
|
try {
|
||||||
grantedCallback?.onPermissionsGranted()
|
grantedCallback?.onPermissionsGranted()
|
||||||
@@ -215,20 +137,40 @@ internal class Request : OnRequestPermissionsResultCallback {
|
|||||||
RequestPlugins.sResultCallback?.onPermissionsDenied(deniedPermissions)
|
RequestPlugins.sResultCallback?.onPermissionsDenied(deniedPermissions)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun toSetting() {
|
||||||
|
appCtx.startActivity<PermissionActivity> {
|
||||||
|
putExtra(
|
||||||
|
PermissionActivity.KEY_INPUT_REQUEST_TYPE,
|
||||||
|
TYPE_REQUEST_SETTING
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun toManageFileSetting() {
|
||||||
|
appCtx.startActivity<PermissionActivity> {
|
||||||
|
putExtra(PermissionActivity.KEY_RATIONALE, rationale)
|
||||||
|
putExtra(PermissionActivity.KEY_INPUT_REQUEST_TYPE, TYPE_MANAGE_ALL_FILES_ACCESS)
|
||||||
|
putExtra(PermissionActivity.KEY_INPUT_PERMISSIONS_CODE, requestCode)
|
||||||
|
putExtra(PermissionActivity.KEY_INPUT_PERMISSIONS, deniedPermissions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun toNotificationSetting() {
|
||||||
|
appCtx.startActivity<PermissionActivity> {
|
||||||
|
putExtra(PermissionActivity.KEY_RATIONALE, rationale)
|
||||||
|
putExtra(PermissionActivity.KEY_INPUT_REQUEST_TYPE, TYPE_REQUEST_NOTIFICATIONS)
|
||||||
|
putExtra(PermissionActivity.KEY_INPUT_PERMISSIONS_CODE, requestCode)
|
||||||
|
putExtra(PermissionActivity.KEY_INPUT_PERMISSIONS, deniedPermissions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onRequestPermissionsResult(
|
override fun onRequestPermissionsResult(
|
||||||
permissions: Array<String>,
|
permissions: Array<String>,
|
||||||
grantResults: IntArray
|
grantResults: IntArray
|
||||||
) {
|
) {
|
||||||
val deniedPermissions = getDeniedPermissions(permissions)
|
val deniedPermissions = getDeniedPermissions(permissions)
|
||||||
if (deniedPermissions != null) {
|
if (deniedPermissions != null) {
|
||||||
val rationale = this.rationale
|
onPermissionsDenied(deniedPermissions)
|
||||||
if (rationale != null) {
|
|
||||||
showSettingDialog(deniedPermissions, rationale) {
|
|
||||||
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
onPermissionsDenied(deniedPermissions)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
onPermissionsGranted()
|
onPermissionsGranted()
|
||||||
}
|
}
|
||||||
@@ -251,7 +193,7 @@ internal class Request : OnRequestPermissionsResultCallback {
|
|||||||
companion object {
|
companion object {
|
||||||
const val TYPE_REQUEST_PERMISSION = 1
|
const val TYPE_REQUEST_PERMISSION = 1
|
||||||
const val TYPE_REQUEST_SETTING = 2
|
const val TYPE_REQUEST_SETTING = 2
|
||||||
const val TYPE_MANAGE_ALL_FILES_ACCESS_PERMISSION = 3
|
const val TYPE_MANAGE_ALL_FILES_ACCESS = 3
|
||||||
const val TYPE_REQUEST_NOTIFICATIONS = 4
|
const val TYPE_REQUEST_NOTIFICATIONS = 4
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
package io.legado.app.lib.permission
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
|
||||||
|
|
||||||
interface RequestSource {
|
|
||||||
|
|
||||||
val context: Context?
|
|
||||||
|
|
||||||
fun startActivity(intent: Intent)
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -495,7 +495,7 @@ class AudioPlayService : BaseService(),
|
|||||||
/**
|
/**
|
||||||
* 更新通知
|
* 更新通知
|
||||||
*/
|
*/
|
||||||
private fun upNotification() {
|
override fun upNotification() {
|
||||||
execute {
|
execute {
|
||||||
var nTitle: String = when {
|
var nTitle: String = when {
|
||||||
pause -> getString(R.string.audio_pause)
|
pause -> getString(R.string.audio_pause)
|
||||||
|
|||||||
@@ -355,7 +355,7 @@ abstract class BaseReadAloudService : BaseService(),
|
|||||||
/**
|
/**
|
||||||
* 更新通知
|
* 更新通知
|
||||||
*/
|
*/
|
||||||
private fun upNotification() {
|
override fun upNotification() {
|
||||||
execute {
|
execute {
|
||||||
var nTitle: String = when {
|
var nTitle: String = when {
|
||||||
pause -> getString(R.string.read_aloud_pause)
|
pause -> getString(R.string.read_aloud_pause)
|
||||||
|
|||||||
@@ -260,7 +260,7 @@ class CheckSourceService : BaseService() {
|
|||||||
/**
|
/**
|
||||||
* 更新通知
|
* 更新通知
|
||||||
*/
|
*/
|
||||||
private fun upNotification() {
|
override fun upNotification() {
|
||||||
notificationBuilder.setContentText(notificationMsg)
|
notificationBuilder.setContentText(notificationMsg)
|
||||||
notificationBuilder.setProgress(allIds.size, checkedIds.size, false)
|
notificationBuilder.setProgress(allIds.size, checkedIds.size, false)
|
||||||
postEvent(EventBus.CHECK_SOURCE, notificationMsg)
|
postEvent(EventBus.CHECK_SOURCE, notificationMsg)
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ class WebService : BaseService() {
|
|||||||
/**
|
/**
|
||||||
* 更新通知
|
* 更新通知
|
||||||
*/
|
*/
|
||||||
private fun upNotification() {
|
override fun upNotification() {
|
||||||
val builder = NotificationCompat.Builder(this, AppConst.channelIdWeb)
|
val builder = NotificationCompat.Builder(this, AppConst.channelIdWeb)
|
||||||
.setSmallIcon(R.drawable.ic_web_service_noti)
|
.setSmallIcon(R.drawable.ic_web_service_noti)
|
||||||
.setOngoing(true)
|
.setOngoing(true)
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ class FileAssociationActivity :
|
|||||||
if (data.isContentScheme()) {
|
if (data.isContentScheme()) {
|
||||||
viewModel.dispatchIndent(data)
|
viewModel.dispatchIndent(data)
|
||||||
} else if (!AppConst.isPlayChannel || Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
|
} else if (!AppConst.isPlayChannel || Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
|
||||||
PermissionsCompat.Builder(this)
|
PermissionsCompat.Builder()
|
||||||
.addPermissions(*Permissions.Group.STORAGE)
|
.addPermissions(*Permissions.Group.STORAGE)
|
||||||
.rationale(R.string.tip_perm_request_storage)
|
.rationale(R.string.tip_perm_request_storage)
|
||||||
.onGranted {
|
.onGranted {
|
||||||
|
|||||||
@@ -189,7 +189,7 @@ class ImportBookActivity : BaseImportBookActivity<ActivityImportBookBinding, Imp
|
|||||||
|
|
||||||
private fun initRootPath(path: String) {
|
private fun initRootPath(path: String) {
|
||||||
binding.tvEmptyMsg.visible()
|
binding.tvEmptyMsg.visible()
|
||||||
PermissionsCompat.Builder(this)
|
PermissionsCompat.Builder()
|
||||||
.addPermissions(*Permissions.Group.STORAGE)
|
.addPermissions(*Permissions.Group.STORAGE)
|
||||||
.rationale(R.string.tip_perm_request_storage)
|
.rationale(R.string.tip_perm_request_storage)
|
||||||
.onGranted {
|
.onGranted {
|
||||||
|
|||||||
@@ -295,7 +295,7 @@ class BackupConfigFragment : PreferenceFragment(),
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun backupUsePermission(path: String) {
|
private fun backupUsePermission(path: String) {
|
||||||
PermissionsCompat.Builder(this)
|
PermissionsCompat.Builder()
|
||||||
.addPermissions(*Permissions.Group.STORAGE)
|
.addPermissions(*Permissions.Group.STORAGE)
|
||||||
.rationale(R.string.tip_perm_request_storage)
|
.rationale(R.string.tip_perm_request_storage)
|
||||||
.onGranted {
|
.onGranted {
|
||||||
@@ -366,7 +366,7 @@ class BackupConfigFragment : PreferenceFragment(),
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun restoreUsePermission(path: String) {
|
private fun restoreUsePermission(path: String) {
|
||||||
PermissionsCompat.Builder(this)
|
PermissionsCompat.Builder()
|
||||||
.addPermissions(*Permissions.Group.STORAGE)
|
.addPermissions(*Permissions.Group.STORAGE)
|
||||||
.rationale(R.string.tip_perm_request_storage)
|
.rationale(R.string.tip_perm_request_storage)
|
||||||
.onGranted {
|
.onGranted {
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ class HandleFileActivity :
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun checkPermissions(success: (() -> Unit)? = null) {
|
private fun checkPermissions(success: (() -> Unit)? = null) {
|
||||||
PermissionsCompat.Builder(this)
|
PermissionsCompat.Builder()
|
||||||
.addPermissions(*Permissions.Group.STORAGE)
|
.addPermissions(*Permissions.Group.STORAGE)
|
||||||
.rationale(R.string.tip_perm_request_storage)
|
.rationale(R.string.tip_perm_request_storage)
|
||||||
.onGranted {
|
.onGranted {
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ class FontSelectDialog : BaseDialogFragment(R.layout.dialog_font_select),
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun loadFontFilesByPermission(path: String) {
|
private fun loadFontFilesByPermission(path: String) {
|
||||||
PermissionsCompat.Builder(this@FontSelectDialog)
|
PermissionsCompat.Builder()
|
||||||
.addPermissions(*Permissions.Group.STORAGE)
|
.addPermissions(*Permissions.Group.STORAGE)
|
||||||
.rationale(R.string.tip_perm_request_storage)
|
.rationale(R.string.tip_perm_request_storage)
|
||||||
.onGranted {
|
.onGranted {
|
||||||
|
|||||||
@@ -28,8 +28,6 @@ import io.legado.app.help.config.LocalConfig
|
|||||||
import io.legado.app.help.coroutine.Coroutine
|
import io.legado.app.help.coroutine.Coroutine
|
||||||
import io.legado.app.help.storage.Backup
|
import io.legado.app.help.storage.Backup
|
||||||
import io.legado.app.lib.dialogs.alert
|
import io.legado.app.lib.dialogs.alert
|
||||||
import io.legado.app.lib.permission.Permissions
|
|
||||||
import io.legado.app.lib.permission.PermissionsCompat
|
|
||||||
import io.legado.app.lib.theme.elevation
|
import io.legado.app.lib.theme.elevation
|
||||||
import io.legado.app.lib.theme.primaryColor
|
import io.legado.app.lib.theme.primaryColor
|
||||||
import io.legado.app.service.BaseReadAloudService
|
import io.legado.app.service.BaseReadAloudService
|
||||||
@@ -94,8 +92,6 @@ class MainActivity : VMBaseActivity<ActivityMainBinding, MainViewModel>(),
|
|||||||
if (!privacyPolicy()) return@launch
|
if (!privacyPolicy()) return@launch
|
||||||
//版本更新
|
//版本更新
|
||||||
upVersion()
|
upVersion()
|
||||||
//检测通知权限
|
|
||||||
checkNotificationPermission()
|
|
||||||
//备份同步
|
//备份同步
|
||||||
backupSync()
|
backupSync()
|
||||||
//自动更新书籍
|
//自动更新书籍
|
||||||
@@ -198,25 +194,6 @@ class MainActivity : VMBaseActivity<ActivityMainBinding, MainViewModel>(),
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 检测通知权限
|
|
||||||
*/
|
|
||||||
private suspend fun checkNotificationPermission() = suspendCoroutine { block ->
|
|
||||||
PermissionsCompat.Builder(this)
|
|
||||||
.addPermissions(Permissions.POST_NOTIFICATIONS)
|
|
||||||
.rationale(R.string.notification_permission_rationale)
|
|
||||||
.onDenied {
|
|
||||||
block.resume(null)
|
|
||||||
}
|
|
||||||
.onGranted {
|
|
||||||
block.resume(null)
|
|
||||||
}
|
|
||||||
.onError {
|
|
||||||
block.resume(null)
|
|
||||||
}
|
|
||||||
.request()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 备份同步
|
* 备份同步
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import android.view.Menu
|
|||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.widget.EditText
|
import android.widget.EditText
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
|
import com.google.android.material.tabs.TabLayout
|
||||||
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel
|
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel
|
||||||
import io.legado.app.R
|
import io.legado.app.R
|
||||||
import io.legado.app.base.VMBaseActivity
|
import io.legado.app.base.VMBaseActivity
|
||||||
@@ -14,6 +15,8 @@ import io.legado.app.databinding.ActivityRssSourceEditBinding
|
|||||||
import io.legado.app.help.config.LocalConfig
|
import io.legado.app.help.config.LocalConfig
|
||||||
import io.legado.app.lib.dialogs.SelectItem
|
import io.legado.app.lib.dialogs.SelectItem
|
||||||
import io.legado.app.lib.dialogs.alert
|
import io.legado.app.lib.dialogs.alert
|
||||||
|
import io.legado.app.lib.theme.accentColor
|
||||||
|
import io.legado.app.lib.theme.backgroundColor
|
||||||
import io.legado.app.lib.theme.primaryColor
|
import io.legado.app.lib.theme.primaryColor
|
||||||
import io.legado.app.ui.document.HandleFileContract
|
import io.legado.app.ui.document.HandleFileContract
|
||||||
import io.legado.app.ui.login.SourceLoginActivity
|
import io.legado.app.ui.login.SourceLoginActivity
|
||||||
@@ -37,6 +40,8 @@ class RssSourceEditActivity :
|
|||||||
}
|
}
|
||||||
private val adapter by lazy { RssSourceEditAdapter() }
|
private val adapter by lazy { RssSourceEditAdapter() }
|
||||||
private val sourceEntities: ArrayList<EditEntity> = ArrayList()
|
private val sourceEntities: ArrayList<EditEntity> = ArrayList()
|
||||||
|
private val listEntities: ArrayList<EditEntity> = ArrayList()
|
||||||
|
private val webViewEntities: ArrayList<EditEntity> = ArrayList()
|
||||||
private val selectDoc = registerForActivityResult(HandleFileContract()) {
|
private val selectDoc = registerForActivityResult(HandleFileContract()) {
|
||||||
it.uri?.let { uri ->
|
it.uri?.let { uri ->
|
||||||
if (uri.isContentScheme()) {
|
if (uri.isContentScheme()) {
|
||||||
@@ -148,8 +153,41 @@ class RssSourceEditActivity :
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun initView() {
|
private fun initView() {
|
||||||
|
binding.tabLayout.addTab(binding.tabLayout.newTab().apply {
|
||||||
|
setText(R.string.source_tab_base)
|
||||||
|
})
|
||||||
|
binding.tabLayout.addTab(binding.tabLayout.newTab().apply {
|
||||||
|
setText(R.string.source_tab_list)
|
||||||
|
})
|
||||||
|
binding.tabLayout.addTab(binding.tabLayout.newTab().apply {
|
||||||
|
text = "WEB_VIEW"
|
||||||
|
})
|
||||||
binding.recyclerView.setEdgeEffectColor(primaryColor)
|
binding.recyclerView.setEdgeEffectColor(primaryColor)
|
||||||
binding.recyclerView.adapter = adapter
|
binding.recyclerView.adapter = adapter
|
||||||
|
binding.tabLayout.setBackgroundColor(backgroundColor)
|
||||||
|
binding.tabLayout.setSelectedTabIndicatorColor(accentColor)
|
||||||
|
binding.tabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
|
||||||
|
override fun onTabReselected(tab: TabLayout.Tab?) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTabUnselected(tab: TabLayout.Tab?) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTabSelected(tab: TabLayout.Tab?) {
|
||||||
|
setEditEntities(tab?.position)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setEditEntities(tabPosition: Int?) {
|
||||||
|
when (tabPosition) {
|
||||||
|
1 -> adapter.editEntities = listEntities
|
||||||
|
2 -> adapter.editEntities = webViewEntities
|
||||||
|
else -> adapter.editEntities = sourceEntities
|
||||||
|
}
|
||||||
|
binding.recyclerView.scrollToPosition(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun upSourceView(rs: RssSource? = viewModel.rssSource) {
|
private fun upSourceView(rs: RssSource? = viewModel.rssSource) {
|
||||||
@@ -175,6 +213,9 @@ class RssSourceEditActivity :
|
|||||||
add(EditEntity("variableComment", rs?.variableComment, R.string.variable_comment))
|
add(EditEntity("variableComment", rs?.variableComment, R.string.variable_comment))
|
||||||
add(EditEntity("concurrentRate", rs?.concurrentRate, R.string.concurrent_rate))
|
add(EditEntity("concurrentRate", rs?.concurrentRate, R.string.concurrent_rate))
|
||||||
add(EditEntity("sortUrl", rs?.sortUrl, R.string.sort_url))
|
add(EditEntity("sortUrl", rs?.sortUrl, R.string.sort_url))
|
||||||
|
}
|
||||||
|
listEntities.clear()
|
||||||
|
listEntities.apply {
|
||||||
add(EditEntity("ruleArticles", rs?.ruleArticles, R.string.r_articles))
|
add(EditEntity("ruleArticles", rs?.ruleArticles, R.string.r_articles))
|
||||||
add(EditEntity("ruleNextPage", rs?.ruleNextPage, R.string.r_next))
|
add(EditEntity("ruleNextPage", rs?.ruleNextPage, R.string.r_next))
|
||||||
add(EditEntity("ruleTitle", rs?.ruleTitle, R.string.r_title))
|
add(EditEntity("ruleTitle", rs?.ruleTitle, R.string.r_title))
|
||||||
@@ -182,13 +223,17 @@ class RssSourceEditActivity :
|
|||||||
add(EditEntity("ruleDescription", rs?.ruleDescription, R.string.r_description))
|
add(EditEntity("ruleDescription", rs?.ruleDescription, R.string.r_description))
|
||||||
add(EditEntity("ruleImage", rs?.ruleImage, R.string.r_image))
|
add(EditEntity("ruleImage", rs?.ruleImage, R.string.r_image))
|
||||||
add(EditEntity("ruleLink", rs?.ruleLink, R.string.r_link))
|
add(EditEntity("ruleLink", rs?.ruleLink, R.string.r_link))
|
||||||
|
}
|
||||||
|
webViewEntities.clear()
|
||||||
|
webViewEntities.apply {
|
||||||
add(EditEntity("ruleContent", rs?.ruleContent, R.string.r_content))
|
add(EditEntity("ruleContent", rs?.ruleContent, R.string.r_content))
|
||||||
add(EditEntity("style", rs?.style, R.string.r_style))
|
add(EditEntity("style", rs?.style, R.string.r_style))
|
||||||
add(EditEntity("injectJs", rs?.injectJs, R.string.r_inject_js))
|
add(EditEntity("injectJs", rs?.injectJs, R.string.r_inject_js))
|
||||||
add(EditEntity("contentWhitelist", rs?.contentWhitelist, R.string.c_whitelist))
|
add(EditEntity("contentWhitelist", rs?.contentWhitelist, R.string.c_whitelist))
|
||||||
add(EditEntity("contentBlacklist", rs?.contentBlacklist, R.string.c_blacklist))
|
add(EditEntity("contentBlacklist", rs?.contentBlacklist, R.string.c_blacklist))
|
||||||
}
|
}
|
||||||
adapter.editEntities = sourceEntities
|
binding.tabLayout.selectTab(binding.tabLayout.getTabAt(0))
|
||||||
|
setEditEntities(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getRssSource(): RssSource {
|
private fun getRssSource(): RssSource {
|
||||||
@@ -213,6 +258,10 @@ class RssSourceEditActivity :
|
|||||||
"variableComment" -> source.variableComment = it.value
|
"variableComment" -> source.variableComment = it.value
|
||||||
"concurrentRate" -> source.concurrentRate = it.value
|
"concurrentRate" -> source.concurrentRate = it.value
|
||||||
"sortUrl" -> source.sortUrl = it.value
|
"sortUrl" -> source.sortUrl = it.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
listEntities.forEach {
|
||||||
|
when (it.key) {
|
||||||
"ruleArticles" -> source.ruleArticles = it.value
|
"ruleArticles" -> source.ruleArticles = it.value
|
||||||
"ruleNextPage" -> source.ruleNextPage =
|
"ruleNextPage" -> source.ruleNextPage =
|
||||||
viewModel.ruleComplete(it.value, source.ruleArticles, 2)
|
viewModel.ruleComplete(it.value, source.ruleArticles, 2)
|
||||||
@@ -226,6 +275,10 @@ class RssSourceEditActivity :
|
|||||||
viewModel.ruleComplete(it.value, source.ruleArticles, 3)
|
viewModel.ruleComplete(it.value, source.ruleArticles, 3)
|
||||||
"ruleLink" -> source.ruleLink =
|
"ruleLink" -> source.ruleLink =
|
||||||
viewModel.ruleComplete(it.value, source.ruleArticles)
|
viewModel.ruleComplete(it.value, source.ruleArticles)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
webViewEntities.forEach {
|
||||||
|
when (it.key) {
|
||||||
"ruleContent" -> source.ruleContent =
|
"ruleContent" -> source.ruleContent =
|
||||||
viewModel.ruleComplete(it.value, source.ruleArticles)
|
viewModel.ruleComplete(it.value, source.ruleArticles)
|
||||||
"style" -> source.style = it.value
|
"style" -> source.style = it.value
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ fun AppCompatActivity.readUri(
|
|||||||
success.invoke(fileDoc, inputStream)
|
success.invoke(fileDoc, inputStream)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
PermissionsCompat.Builder(this)
|
PermissionsCompat.Builder()
|
||||||
.addPermissions(
|
.addPermissions(
|
||||||
Permissions.READ_EXTERNAL_STORAGE,
|
Permissions.READ_EXTERNAL_STORAGE,
|
||||||
Permissions.WRITE_EXTERNAL_STORAGE
|
Permissions.WRITE_EXTERNAL_STORAGE
|
||||||
@@ -81,7 +81,7 @@ fun Fragment.readUri(uri: Uri?, success: (fileDoc: FileDoc, inputStream: InputSt
|
|||||||
success.invoke(fileDoc, inputStream)
|
success.invoke(fileDoc, inputStream)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
PermissionsCompat.Builder(this)
|
PermissionsCompat.Builder()
|
||||||
.addPermissions(
|
.addPermissions(
|
||||||
Permissions.READ_EXTERNAL_STORAGE,
|
Permissions.READ_EXTERNAL_STORAGE,
|
||||||
Permissions.WRITE_EXTERNAL_STORAGE
|
Permissions.WRITE_EXTERNAL_STORAGE
|
||||||
|
|||||||
@@ -87,6 +87,14 @@
|
|||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.tabs.TabLayout
|
||||||
|
android:id="@+id/tab_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="36dp"
|
||||||
|
android:background="@color/background"
|
||||||
|
android:elevation="3dp"
|
||||||
|
tools:ignore="SpeakableTextPresentCheck" />
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/recycler_view"
|
android:id="@+id/recycler_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|||||||
@@ -1071,4 +1071,5 @@
|
|||||||
<string name="jump_to_another_app">跳转其它应用</string>
|
<string name="jump_to_another_app">跳转其它应用</string>
|
||||||
<string name="clear_webview_data">清除 WebView 数据</string>
|
<string name="clear_webview_data">清除 WebView 数据</string>
|
||||||
<string name="clear_webview_data_summary">清除内置浏览器所有数据</string>
|
<string name="clear_webview_data_summary">清除内置浏览器所有数据</string>
|
||||||
|
<string name="source_tab_list">列表</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -1074,4 +1074,5 @@
|
|||||||
<string name="jump_to_another_app">跳转其它应用</string>
|
<string name="jump_to_another_app">跳转其它应用</string>
|
||||||
<string name="clear_webview_data">清除 WebView 数据</string>
|
<string name="clear_webview_data">清除 WebView 数据</string>
|
||||||
<string name="clear_webview_data_summary">清除内置浏览器所有数据</string>
|
<string name="clear_webview_data_summary">清除内置浏览器所有数据</string>
|
||||||
|
<string name="source_tab_list">列表</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -1074,4 +1074,5 @@
|
|||||||
<string name="jump_to_another_app">跳转其它应用</string>
|
<string name="jump_to_another_app">跳转其它应用</string>
|
||||||
<string name="clear_webview_data">清除 WebView 数据</string>
|
<string name="clear_webview_data">清除 WebView 数据</string>
|
||||||
<string name="clear_webview_data_summary">清除内置浏览器所有数据</string>
|
<string name="clear_webview_data_summary">清除内置浏览器所有数据</string>
|
||||||
|
<string name="source_tab_list">列表</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -1071,4 +1071,5 @@
|
|||||||
<string name="jump_to_another_app">跳转其它应用</string>
|
<string name="jump_to_another_app">跳转其它应用</string>
|
||||||
<string name="clear_webview_data">清除 WebView 数据</string>
|
<string name="clear_webview_data">清除 WebView 数据</string>
|
||||||
<string name="clear_webview_data_summary">清除内置浏览器所有数据</string>
|
<string name="clear_webview_data_summary">清除内置浏览器所有数据</string>
|
||||||
|
<string name="source_tab_list">列表</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -1073,4 +1073,5 @@
|
|||||||
<string name="jump_to_another_app">跳转其它应用</string>
|
<string name="jump_to_another_app">跳转其它应用</string>
|
||||||
<string name="clear_webview_data">清除 WebView 数据</string>
|
<string name="clear_webview_data">清除 WebView 数据</string>
|
||||||
<string name="clear_webview_data_summary">清除内置浏览器所有数据</string>
|
<string name="clear_webview_data_summary">清除内置浏览器所有数据</string>
|
||||||
|
<string name="source_tab_list">列表</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -1073,4 +1073,5 @@
|
|||||||
<string name="jump_to_another_app">跳转其它应用</string>
|
<string name="jump_to_another_app">跳转其它应用</string>
|
||||||
<string name="clear_webview_data">清除 WebView 数据</string>
|
<string name="clear_webview_data">清除 WebView 数据</string>
|
||||||
<string name="clear_webview_data_summary">清除内置浏览器所有数据</string>
|
<string name="clear_webview_data_summary">清除内置浏览器所有数据</string>
|
||||||
|
<string name="source_tab_list">列表</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -1074,4 +1074,5 @@
|
|||||||
<string name="jump_to_another_app">Jump to another app</string>
|
<string name="jump_to_another_app">Jump to another app</string>
|
||||||
<string name="clear_webview_data">清除 WebView 数据</string>
|
<string name="clear_webview_data">清除 WebView 数据</string>
|
||||||
<string name="clear_webview_data_summary">清除内置浏览器所有数据</string>
|
<string name="clear_webview_data_summary">清除内置浏览器所有数据</string>
|
||||||
|
<string name="source_tab_list">List</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
Reference in New Issue
Block a user