This commit is contained in:
kunfei 2023-02-15 22:38:43 +08:00
parent c72e248b91
commit 151c3177cd
27 changed files with 229 additions and 247 deletions

View File

@ -4,8 +4,11 @@ import android.content.Intent
import android.os.IBinder
import androidx.annotation.CallSuper
import androidx.lifecycle.LifecycleService
import io.legado.app.R
import io.legado.app.help.LifecycleHelp
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 kotlin.coroutines.CoroutineContext
@ -22,6 +25,7 @@ abstract class BaseService : LifecycleService(), CoroutineScope by MainScope() {
override fun onCreate() {
super.onCreate()
LifecycleHelp.onServiceCreate(this)
checkNotificationPermission()
}
@CallSuper
@ -41,4 +45,24 @@ abstract class BaseService : LifecycleService(), CoroutineScope by MainScope() {
cancel()
LifecycleHelp.onServiceDestroy(this)
}
/**
* 更新通知
*/
open fun upNotification() {
}
/**
* 检测通知权限
*/
private fun checkNotificationPermission() {
PermissionsCompat.Builder()
.addPermissions(Permissions.POST_NOTIFICATIONS)
.rationale(R.string.notification_permission_rationale)
.onGranted {
upNotification()
}
.request()
}
}

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -7,6 +7,7 @@ import android.os.Bundle
import android.provider.Settings
import android.view.KeyEvent
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import io.legado.app.R
@ -15,6 +16,8 @@ import io.legado.app.utils.toastOnUi
class PermissionActivity : AppCompatActivity() {
private var rationaleDialog: AlertDialog? = null
private val settingActivityResult =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
RequestPlugins.sRequestCallback?.onSettingActivityResult()
@ -23,42 +26,45 @@ class PermissionActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val rationale = intent.getStringExtra(KEY_RATIONALE)
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)) {
//权限请求
Request.TYPE_REQUEST_PERMISSION -> {
if (permissions != null) {
ActivityCompat.requestPermissions(this, permissions, requestCode)
} else {
Request.TYPE_REQUEST_PERMISSION -> showSettingDialog(permissions, rationale){
ActivityCompat.requestPermissions(this, permissions, requestCode)
}
//跳转到设置界面
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()
}
}
//跳转到设置界面
Request.TYPE_REQUEST_SETTING -> openSettingsActivity()
//所有文件的管理权限
Request.TYPE_MANAGE_ALL_FILES_ACCESS_PERMISSION -> 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()
}
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()
Request.TYPE_REQUEST_NOTIFICATIONS -> showSettingDialog(permissions, rationale) {
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)
}
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 {
const val KEY_RATIONALE = "KEY_RATIONALE"
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"

View File

@ -1,8 +1,6 @@
package io.legado.app.lib.permission
import androidx.annotation.StringRes
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
@Suppress("unused")
class PermissionsCompat private constructor() {
@ -14,15 +12,7 @@ class PermissionsCompat private constructor() {
}
class Builder {
private val request: Request
constructor(activity: AppCompatActivity) {
request = Request(activity)
}
constructor(fragment: Fragment) {
request = Request(fragment)
}
private val request: Request = Request()
fun addPermissions(vararg permissions: String): Builder {
request.addPermissions(*permissions)

View File

@ -4,48 +4,29 @@ import android.content.pm.PackageManager
import android.os.Build
import android.os.Environment
import androidx.annotation.StringRes
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.NotificationManagerCompat
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import io.legado.app.R
import io.legado.app.utils.startActivity
import splitties.init.appCtx
@Suppress("MemberVisibilityCanBePrivate")
internal class Request : OnRequestPermissionsResultCallback {
internal val requestTime: Long
internal val requestTime: Long = System.currentTimeMillis()
private var requestCode: Int = TYPE_REQUEST_PERMISSION
private var source: RequestSource? = null
private var permissions: ArrayList<String>? = null
private var permissions: ArrayList<String> = ArrayList()
private var grantedCallback: OnPermissionsGrantedCallback? = null
private var deniedCallback: OnPermissionsDeniedCallback? = null
private var errorCallback: OnErrorCallback? = null
private var rationale: CharSequence? = null
private var rationaleDialog: AlertDialog? = null
private val deniedPermissions: Array<String>?
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) {
this.permissions?.addAll(listOf(*permissions))
this.permissions.addAll(listOf(*permissions))
}
fun setOnGrantedCallback(callback: OnPermissionsGrantedCallback) {
@ -61,7 +42,7 @@ internal class Request : OnRequestPermissionsResultCallback {
}
fun setRationale(@StringRes resId: Int) {
rationale = source?.context?.getString(resId)
rationale = appCtx.getString(resId)
}
fun setRationale(rationale: CharSequence) {
@ -82,22 +63,16 @@ internal class Request : OnRequestPermissionsResultCallback {
return
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
showSettingDialog(deniedPermissions, rationale) {
toSetting()
}
toSetting()
} else {
if (deniedPermissions.contains(Permissions.MANAGE_EXTERNAL_STORAGE)) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
showSettingDialog(deniedPermissions, rationale) {
toManageFileSetting()
}
toManageFileSetting()
}
} else if (deniedPermissions.contains(Permissions.POST_NOTIFICATIONS)) {
showSettingDialog(deniedPermissions, rationale) {
toNotificationSetting()
}
toNotificationSetting()
} 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_PERMISSIONS_CODE, requestCode)
putExtra(PermissionActivity.KEY_INPUT_PERMISSIONS, deniedPermissions)
@ -111,92 +86,39 @@ internal class Request : OnRequestPermissionsResultCallback {
deniedCallback = null
}
fun getDeniedPermissions(permissions: Array<String>?): Array<String>? {
val context = source?.context ?: return permissions
if (permissions != null) {
val deniedPermissionList = ArrayList<String>()
for (permission in permissions) {
when (permission) {
Permissions.POST_NOTIFICATIONS -> {
if (!NotificationManagerCompat.from(appCtx).areNotificationsEnabled()) {
deniedPermissionList.add(permission)
}
fun getDeniedPermissions(permissions: Array<String>): Array<String>? {
val deniedPermissionList = ArrayList<String>()
for (permission in permissions) {
when (permission) {
Permissions.POST_NOTIFICATIONS -> {
if (!NotificationManagerCompat.from(appCtx).areNotificationsEnabled()) {
deniedPermissionList.add(permission)
}
Permissions.MANAGE_EXTERNAL_STORAGE -> {
if (Permissions.isManageExternalStorage()) {
if (!Environment.isExternalStorageManager()) {
deniedPermissionList.add(permission)
}
}
}
else -> {
if (
ContextCompat.checkSelfPermission(context, permission)
!= PackageManager.PERMISSION_GRANTED
) {
}
Permissions.MANAGE_EXTERNAL_STORAGE -> {
if (Permissions.isManageExternalStorage()) {
if (!Environment.isExternalStorageManager()) {
deniedPermissionList.add(permission)
}
}
}
else -> {
if (
ContextCompat.checkSelfPermission(appCtx, permission)
!= PackageManager.PERMISSION_GRANTED
) {
deniedPermissionList.add(permission)
}
}
}
val size = deniedPermissionList.size
if (size > 0) {
return deniedPermissionList.toTypedArray()
}
}
val size = deniedPermissionList.size
if (size > 0) {
return deniedPermissionList.toTypedArray()
}
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() {
try {
grantedCallback?.onPermissionsGranted()
@ -215,20 +137,40 @@ internal class Request : OnRequestPermissionsResultCallback {
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(
permissions: Array<String>,
grantResults: IntArray
) {
val deniedPermissions = getDeniedPermissions(permissions)
if (deniedPermissions != null) {
val rationale = this.rationale
if (rationale != null) {
showSettingDialog(deniedPermissions, rationale) {
}
} else {
onPermissionsDenied(deniedPermissions)
}
onPermissionsDenied(deniedPermissions)
} else {
onPermissionsGranted()
}
@ -251,7 +193,7 @@ internal class Request : OnRequestPermissionsResultCallback {
companion object {
const val TYPE_REQUEST_PERMISSION = 1
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
}
}

View File

@ -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)
}

View File

@ -495,7 +495,7 @@ class AudioPlayService : BaseService(),
/**
* 更新通知
*/
private fun upNotification() {
override fun upNotification() {
execute {
var nTitle: String = when {
pause -> getString(R.string.audio_pause)

View File

@ -355,7 +355,7 @@ abstract class BaseReadAloudService : BaseService(),
/**
* 更新通知
*/
private fun upNotification() {
override fun upNotification() {
execute {
var nTitle: String = when {
pause -> getString(R.string.read_aloud_pause)

View File

@ -260,7 +260,7 @@ class CheckSourceService : BaseService() {
/**
* 更新通知
*/
private fun upNotification() {
override fun upNotification() {
notificationBuilder.setContentText(notificationMsg)
notificationBuilder.setProgress(allIds.size, checkedIds.size, false)
postEvent(EventBus.CHECK_SOURCE, notificationMsg)

View File

@ -144,7 +144,7 @@ class WebService : BaseService() {
/**
* 更新通知
*/
private fun upNotification() {
override fun upNotification() {
val builder = NotificationCompat.Builder(this, AppConst.channelIdWeb)
.setSmallIcon(R.drawable.ic_web_service_noti)
.setOngoing(true)

View File

@ -109,7 +109,7 @@ class FileAssociationActivity :
if (data.isContentScheme()) {
viewModel.dispatchIndent(data)
} else if (!AppConst.isPlayChannel || Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
PermissionsCompat.Builder(this)
PermissionsCompat.Builder()
.addPermissions(*Permissions.Group.STORAGE)
.rationale(R.string.tip_perm_request_storage)
.onGranted {

View File

@ -189,7 +189,7 @@ class ImportBookActivity : BaseImportBookActivity<ActivityImportBookBinding, Imp
private fun initRootPath(path: String) {
binding.tvEmptyMsg.visible()
PermissionsCompat.Builder(this)
PermissionsCompat.Builder()
.addPermissions(*Permissions.Group.STORAGE)
.rationale(R.string.tip_perm_request_storage)
.onGranted {

View File

@ -295,7 +295,7 @@ class BackupConfigFragment : PreferenceFragment(),
}
private fun backupUsePermission(path: String) {
PermissionsCompat.Builder(this)
PermissionsCompat.Builder()
.addPermissions(*Permissions.Group.STORAGE)
.rationale(R.string.tip_perm_request_storage)
.onGranted {
@ -366,7 +366,7 @@ class BackupConfigFragment : PreferenceFragment(),
}
private fun restoreUsePermission(path: String) {
PermissionsCompat.Builder(this)
PermissionsCompat.Builder()
.addPermissions(*Permissions.Group.STORAGE)
.rationale(R.string.tip_perm_request_storage)
.onGranted {

View File

@ -182,7 +182,7 @@ class HandleFileActivity :
}
private fun checkPermissions(success: (() -> Unit)? = null) {
PermissionsCompat.Builder(this)
PermissionsCompat.Builder()
.addPermissions(*Permissions.Group.STORAGE)
.rationale(R.string.tip_perm_request_storage)
.onGranted {

View File

@ -127,7 +127,7 @@ class FontSelectDialog : BaseDialogFragment(R.layout.dialog_font_select),
}
private fun loadFontFilesByPermission(path: String) {
PermissionsCompat.Builder(this@FontSelectDialog)
PermissionsCompat.Builder()
.addPermissions(*Permissions.Group.STORAGE)
.rationale(R.string.tip_perm_request_storage)
.onGranted {

View File

@ -28,8 +28,6 @@ import io.legado.app.help.config.LocalConfig
import io.legado.app.help.coroutine.Coroutine
import io.legado.app.help.storage.Backup
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.primaryColor
import io.legado.app.service.BaseReadAloudService
@ -94,8 +92,6 @@ class MainActivity : VMBaseActivity<ActivityMainBinding, MainViewModel>(),
if (!privacyPolicy()) return@launch
//版本更新
upVersion()
//检测通知权限
checkNotificationPermission()
//备份同步
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()
}
/**
* 备份同步
*/

View File

@ -6,6 +6,7 @@ import android.view.Menu
import android.view.MenuItem
import android.widget.EditText
import androidx.activity.viewModels
import com.google.android.material.tabs.TabLayout
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel
import io.legado.app.R
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.lib.dialogs.SelectItem
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.ui.document.HandleFileContract
import io.legado.app.ui.login.SourceLoginActivity
@ -37,6 +40,8 @@ class RssSourceEditActivity :
}
private val adapter by lazy { RssSourceEditAdapter() }
private val sourceEntities: ArrayList<EditEntity> = ArrayList()
private val listEntities: ArrayList<EditEntity> = ArrayList()
private val webViewEntities: ArrayList<EditEntity> = ArrayList()
private val selectDoc = registerForActivityResult(HandleFileContract()) {
it.uri?.let { uri ->
if (uri.isContentScheme()) {
@ -148,8 +153,41 @@ class RssSourceEditActivity :
}
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.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) {
@ -175,6 +213,9 @@ class RssSourceEditActivity :
add(EditEntity("variableComment", rs?.variableComment, R.string.variable_comment))
add(EditEntity("concurrentRate", rs?.concurrentRate, R.string.concurrent_rate))
add(EditEntity("sortUrl", rs?.sortUrl, R.string.sort_url))
}
listEntities.clear()
listEntities.apply {
add(EditEntity("ruleArticles", rs?.ruleArticles, R.string.r_articles))
add(EditEntity("ruleNextPage", rs?.ruleNextPage, R.string.r_next))
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("ruleImage", rs?.ruleImage, R.string.r_image))
add(EditEntity("ruleLink", rs?.ruleLink, R.string.r_link))
}
webViewEntities.clear()
webViewEntities.apply {
add(EditEntity("ruleContent", rs?.ruleContent, R.string.r_content))
add(EditEntity("style", rs?.style, R.string.r_style))
add(EditEntity("injectJs", rs?.injectJs, R.string.r_inject_js))
add(EditEntity("contentWhitelist", rs?.contentWhitelist, R.string.c_whitelist))
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 {
@ -213,6 +258,10 @@ class RssSourceEditActivity :
"variableComment" -> source.variableComment = it.value
"concurrentRate" -> source.concurrentRate = it.value
"sortUrl" -> source.sortUrl = it.value
}
}
listEntities.forEach {
when (it.key) {
"ruleArticles" -> source.ruleArticles = it.value
"ruleNextPage" -> source.ruleNextPage =
viewModel.ruleComplete(it.value, source.ruleArticles, 2)
@ -226,6 +275,10 @@ class RssSourceEditActivity :
viewModel.ruleComplete(it.value, source.ruleArticles, 3)
"ruleLink" -> source.ruleLink =
viewModel.ruleComplete(it.value, source.ruleArticles)
}
}
webViewEntities.forEach {
when (it.key) {
"ruleContent" -> source.ruleContent =
viewModel.ruleComplete(it.value, source.ruleArticles)
"style" -> source.style = it.value

View File

@ -41,7 +41,7 @@ fun AppCompatActivity.readUri(
success.invoke(fileDoc, inputStream)
}
} else {
PermissionsCompat.Builder(this)
PermissionsCompat.Builder()
.addPermissions(
Permissions.READ_EXTERNAL_STORAGE,
Permissions.WRITE_EXTERNAL_STORAGE
@ -81,7 +81,7 @@ fun Fragment.readUri(uri: Uri?, success: (fileDoc: FileDoc, inputStream: InputSt
success.invoke(fileDoc, inputStream)
}
} else {
PermissionsCompat.Builder(this)
PermissionsCompat.Builder()
.addPermissions(
Permissions.READ_EXTERNAL_STORAGE,
Permissions.WRITE_EXTERNAL_STORAGE

View File

@ -87,6 +87,14 @@
</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
android:id="@+id/recycler_view"
android:layout_width="match_parent"

View File

@ -1071,4 +1071,5 @@
<string name="jump_to_another_app">跳转其它应用</string>
<string name="clear_webview_data">清除 WebView 数据</string>
<string name="clear_webview_data_summary">清除内置浏览器所有数据</string>
<string name="source_tab_list">列表</string>
</resources>

View File

@ -1074,4 +1074,5 @@
<string name="jump_to_another_app">跳转其它应用</string>
<string name="clear_webview_data">清除 WebView 数据</string>
<string name="clear_webview_data_summary">清除内置浏览器所有数据</string>
<string name="source_tab_list">列表</string>
</resources>

View File

@ -1074,4 +1074,5 @@
<string name="jump_to_another_app">跳转其它应用</string>
<string name="clear_webview_data">清除 WebView 数据</string>
<string name="clear_webview_data_summary">清除内置浏览器所有数据</string>
<string name="source_tab_list">列表</string>
</resources>

View File

@ -1071,4 +1071,5 @@
<string name="jump_to_another_app">跳转其它应用</string>
<string name="clear_webview_data">清除 WebView 数据</string>
<string name="clear_webview_data_summary">清除内置浏览器所有数据</string>
<string name="source_tab_list">列表</string>
</resources>

View File

@ -1073,4 +1073,5 @@
<string name="jump_to_another_app">跳转其它应用</string>
<string name="clear_webview_data">清除 WebView 数据</string>
<string name="clear_webview_data_summary">清除内置浏览器所有数据</string>
<string name="source_tab_list">列表</string>
</resources>

View File

@ -1073,4 +1073,5 @@
<string name="jump_to_another_app">跳转其它应用</string>
<string name="clear_webview_data">清除 WebView 数据</string>
<string name="clear_webview_data_summary">清除内置浏览器所有数据</string>
<string name="source_tab_list">列表</string>
</resources>

View File

@ -1074,4 +1074,5 @@
<string name="jump_to_another_app">Jump to another app</string>
<string name="clear_webview_data">清除 WebView 数据</string>
<string name="clear_webview_data_summary">清除内置浏览器所有数据</string>
<string name="source_tab_list">List</string>
</resources>