diff --git a/app/src/main/java/io/legado/app/base/BaseService.kt b/app/src/main/java/io/legado/app/base/BaseService.kt index b64aaeb4d..335919bf0 100644 --- a/app/src/main/java/io/legado/app/base/BaseService.kt +++ b/app/src/main/java/io/legado/app/base/BaseService.kt @@ -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() + } } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/lib/permission/ActivitySource.kt b/app/src/main/java/io/legado/app/lib/permission/ActivitySource.kt deleted file mode 100644 index 7db53385e..000000000 --- a/app/src/main/java/io/legado/app/lib/permission/ActivitySource.kt +++ /dev/null @@ -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 = 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/lib/permission/FragmentSource.kt b/app/src/main/java/io/legado/app/lib/permission/FragmentSource.kt deleted file mode 100644 index 3b6bd8830..000000000 --- a/app/src/main/java/io/legado/app/lib/permission/FragmentSource.kt +++ /dev/null @@ -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 = 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/lib/permission/PermissionActivity.kt b/app/src/main/java/io/legado/app/lib/permission/PermissionActivity.kt index c2ab8fd95..224ed97f1 100644 --- a/app/src/main/java/io/legado/app/lib/permission/PermissionActivity.kt +++ b/app/src/main/java/io/legado/app/lib/permission/PermissionActivity.kt @@ -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, + 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" diff --git a/app/src/main/java/io/legado/app/lib/permission/PermissionsCompat.kt b/app/src/main/java/io/legado/app/lib/permission/PermissionsCompat.kt index 7a97f14fc..c29eb31d7 100644 --- a/app/src/main/java/io/legado/app/lib/permission/PermissionsCompat.kt +++ b/app/src/main/java/io/legado/app/lib/permission/PermissionsCompat.kt @@ -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) diff --git a/app/src/main/java/io/legado/app/lib/permission/Request.kt b/app/src/main/java/io/legado/app/lib/permission/Request.kt index 68f0fc815..32bf2f400 100644 --- a/app/src/main/java/io/legado/app/lib/permission/Request.kt +++ b/app/src/main/java/io/legado/app/lib/permission/Request.kt @@ -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? = null + private var permissions: ArrayList = 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? 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 { + appCtx.startActivity { 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?): Array? { - val context = source?.context ?: return permissions - if (permissions != null) { - val deniedPermissionList = ArrayList() - for (permission in permissions) { - when (permission) { - Permissions.POST_NOTIFICATIONS -> { - if (!NotificationManagerCompat.from(appCtx).areNotificationsEnabled()) { - deniedPermissionList.add(permission) - } + fun getDeniedPermissions(permissions: Array): Array? { + val deniedPermissionList = ArrayList() + 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, - 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 { - putExtra( - PermissionActivity.KEY_INPUT_REQUEST_TYPE, - TYPE_REQUEST_SETTING - ) - } - } - - private fun toManageFileSetting() { - source?.context?.startActivity { - 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 { - 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 { + putExtra( + PermissionActivity.KEY_INPUT_REQUEST_TYPE, + TYPE_REQUEST_SETTING + ) + } + } + + private fun toManageFileSetting() { + appCtx.startActivity { + 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 { + 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, 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 } } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/lib/permission/RequestSource.kt b/app/src/main/java/io/legado/app/lib/permission/RequestSource.kt deleted file mode 100644 index 3e029805f..000000000 --- a/app/src/main/java/io/legado/app/lib/permission/RequestSource.kt +++ /dev/null @@ -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) - -} diff --git a/app/src/main/java/io/legado/app/service/AudioPlayService.kt b/app/src/main/java/io/legado/app/service/AudioPlayService.kt index 7fbaa4734..9d04fb58c 100644 --- a/app/src/main/java/io/legado/app/service/AudioPlayService.kt +++ b/app/src/main/java/io/legado/app/service/AudioPlayService.kt @@ -495,7 +495,7 @@ class AudioPlayService : BaseService(), /** * 更新通知 */ - private fun upNotification() { + override fun upNotification() { execute { var nTitle: String = when { pause -> getString(R.string.audio_pause) diff --git a/app/src/main/java/io/legado/app/service/BaseReadAloudService.kt b/app/src/main/java/io/legado/app/service/BaseReadAloudService.kt index b05b1f709..8b3b2bfe7 100644 --- a/app/src/main/java/io/legado/app/service/BaseReadAloudService.kt +++ b/app/src/main/java/io/legado/app/service/BaseReadAloudService.kt @@ -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) diff --git a/app/src/main/java/io/legado/app/service/CheckSourceService.kt b/app/src/main/java/io/legado/app/service/CheckSourceService.kt index d34c83168..cd658e344 100644 --- a/app/src/main/java/io/legado/app/service/CheckSourceService.kt +++ b/app/src/main/java/io/legado/app/service/CheckSourceService.kt @@ -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) diff --git a/app/src/main/java/io/legado/app/service/WebService.kt b/app/src/main/java/io/legado/app/service/WebService.kt index 9d51e622e..4aaebd5d9 100644 --- a/app/src/main/java/io/legado/app/service/WebService.kt +++ b/app/src/main/java/io/legado/app/service/WebService.kt @@ -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) diff --git a/app/src/main/java/io/legado/app/ui/association/FileAssociationActivity.kt b/app/src/main/java/io/legado/app/ui/association/FileAssociationActivity.kt index 058bd9836..02492473a 100644 --- a/app/src/main/java/io/legado/app/ui/association/FileAssociationActivity.kt +++ b/app/src/main/java/io/legado/app/ui/association/FileAssociationActivity.kt @@ -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 { diff --git a/app/src/main/java/io/legado/app/ui/book/import/local/ImportBookActivity.kt b/app/src/main/java/io/legado/app/ui/book/import/local/ImportBookActivity.kt index b1d592d88..080fc2a0e 100644 --- a/app/src/main/java/io/legado/app/ui/book/import/local/ImportBookActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/import/local/ImportBookActivity.kt @@ -189,7 +189,7 @@ class ImportBookActivity : BaseImportBookActivity Unit)? = null) { - PermissionsCompat.Builder(this) + PermissionsCompat.Builder() .addPermissions(*Permissions.Group.STORAGE) .rationale(R.string.tip_perm_request_storage) .onGranted { diff --git a/app/src/main/java/io/legado/app/ui/font/FontSelectDialog.kt b/app/src/main/java/io/legado/app/ui/font/FontSelectDialog.kt index 5a6069301..87e7aea5e 100644 --- a/app/src/main/java/io/legado/app/ui/font/FontSelectDialog.kt +++ b/app/src/main/java/io/legado/app/ui/font/FontSelectDialog.kt @@ -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 { diff --git a/app/src/main/java/io/legado/app/ui/main/MainActivity.kt b/app/src/main/java/io/legado/app/ui/main/MainActivity.kt index 3bb7c53ac..554fd819e 100644 --- a/app/src/main/java/io/legado/app/ui/main/MainActivity.kt +++ b/app/src/main/java/io/legado/app/ui/main/MainActivity.kt @@ -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(), if (!privacyPolicy()) return@launch //版本更新 upVersion() - //检测通知权限 - checkNotificationPermission() //备份同步 backupSync() //自动更新书籍 @@ -198,25 +194,6 @@ class MainActivity : VMBaseActivity(), } } - /** - * 检测通知权限 - */ - 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() - } - /** * 备份同步 */ diff --git a/app/src/main/java/io/legado/app/ui/rss/source/edit/RssSourceEditActivity.kt b/app/src/main/java/io/legado/app/ui/rss/source/edit/RssSourceEditActivity.kt index a4e17e84d..3cd391090 100644 --- a/app/src/main/java/io/legado/app/ui/rss/source/edit/RssSourceEditActivity.kt +++ b/app/src/main/java/io/legado/app/ui/rss/source/edit/RssSourceEditActivity.kt @@ -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 = ArrayList() + private val listEntities: ArrayList = ArrayList() + private val webViewEntities: ArrayList = 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 diff --git a/app/src/main/java/io/legado/app/utils/UriExtensions.kt b/app/src/main/java/io/legado/app/utils/UriExtensions.kt index 26a62715a..2dab574bb 100644 --- a/app/src/main/java/io/legado/app/utils/UriExtensions.kt +++ b/app/src/main/java/io/legado/app/utils/UriExtensions.kt @@ -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 diff --git a/app/src/main/res/layout/activity_rss_source_edit.xml b/app/src/main/res/layout/activity_rss_source_edit.xml index 6a29468af..f8a632381 100644 --- a/app/src/main/res/layout/activity_rss_source_edit.xml +++ b/app/src/main/res/layout/activity_rss_source_edit.xml @@ -87,6 +87,14 @@ + + 跳转其它应用 清除 WebView 数据 清除内置浏览器所有数据 + 列表 diff --git a/app/src/main/res/values-ja-rJP/strings.xml b/app/src/main/res/values-ja-rJP/strings.xml index c113ccd43..189923552 100644 --- a/app/src/main/res/values-ja-rJP/strings.xml +++ b/app/src/main/res/values-ja-rJP/strings.xml @@ -1074,4 +1074,5 @@ 跳转其它应用 清除 WebView 数据 清除内置浏览器所有数据 + 列表 diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index c898eb40c..08d162bd9 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -1074,4 +1074,5 @@ 跳转其它应用 清除 WebView 数据 清除内置浏览器所有数据 + 列表 diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index 688ac37b1..e614b4287 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -1071,4 +1071,5 @@ 跳转其它应用 清除 WebView 数据 清除内置浏览器所有数据 + 列表 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index d85773a60..08a6249fb 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -1073,4 +1073,5 @@ 跳转其它应用 清除 WebView 数据 清除内置浏览器所有数据 + 列表 diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index d75227614..6d14b0347 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -1073,4 +1073,5 @@ 跳转其它应用 清除 WebView 数据 清除内置浏览器所有数据 + 列表 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 60b623db3..ce990fce2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1074,4 +1074,5 @@ Jump to another app 清除 WebView 数据 清除内置浏览器所有数据 + List