From 589a54da7d82816fe853663ad80a674745970bdb Mon Sep 17 00:00:00 2001 From: Horis <8674809+821938089@users.noreply.github.com> Date: Sun, 18 Aug 2024 16:02:27 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/legado/app/help/storage/Restore.kt | 14 +++- .../app/lib/permission/PermissionActivity.kt | 66 ++++++++++++++----- .../io/legado/app/utils/ActivityResult.kt | 45 +++++++++++++ 3 files changed, 104 insertions(+), 21 deletions(-) create mode 100644 app/src/main/java/io/legado/app/utils/ActivityResult.kt diff --git a/app/src/main/java/io/legado/app/help/storage/Restore.kt b/app/src/main/java/io/legado/app/help/storage/Restore.kt index ab5eeba1c..34a51271c 100644 --- a/app/src/main/java/io/legado/app/help/storage/Restore.kt +++ b/app/src/main/java/io/legado/app/help/storage/Restore.kt @@ -24,7 +24,6 @@ import io.legado.app.data.entities.RuleSub import io.legado.app.data.entities.SearchKeyword import io.legado.app.data.entities.Server import io.legado.app.data.entities.TxtTocRule -import io.legado.app.help.AppWebDav import io.legado.app.help.DirectLinkUpload import io.legado.app.help.LauncherIconHelp import io.legado.app.help.book.isLocal @@ -36,6 +35,7 @@ import io.legado.app.model.localBook.LocalBook import io.legado.app.utils.ACache import io.legado.app.utils.FileUtils import io.legado.app.utils.GSON +import io.legado.app.utils.LogUtils import io.legado.app.utils.compress.ZipUtils import io.legado.app.utils.defaultSharedPreferences import io.legado.app.utils.fromJsonArray @@ -59,7 +59,10 @@ import java.io.FileInputStream */ object Restore { + private const val TAG = "Restore" + suspend fun restore(context: Context, uri: Uri) { + LogUtils.d(TAG, "开始恢复备份 uri:$uri") kotlin.runCatching { FileUtils.delete(Backup.backupPath) if (uri.isContentScheme()) { @@ -212,7 +215,7 @@ object Restore { AppLog.put("恢复阅读界面出错\n${it.localizedMessage}", it) } } - AppWebDav.downBgs() + //AppWebDav.downBgs() appCtx.getSharedPreferences(path, "config")?.all?.let { map -> val edit = appCtx.defaultSharedPreferences.edit() @@ -266,9 +269,14 @@ object Restore { try { val file = File(path, fileName) if (file.exists()) { + LogUtils.d(TAG, "阅读恢复备份 $fileName 文件大小 ${file.length()}") FileInputStream(file).use { - return GSON.fromJsonArray(it).getOrThrow() + return GSON.fromJsonArray(it).getOrThrow().also { list -> + LogUtils.d(TAG, "阅读恢复备份 $fileName 列表大小 ${list.size}") + } } + } else { + LogUtils.d(TAG, "阅读恢复备份 $fileName 文件不存在") } } catch (e: Exception) { AppLog.put("$fileName\n读取解析出错\n${e.localizedMessage}", e) 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 e49d473ee..1c08584e8 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 @@ -2,6 +2,7 @@ package io.legado.app.lib.permission import android.annotation.SuppressLint import android.content.Intent +import android.content.pm.PackageManager import android.net.Uri import android.os.Build import android.os.Bundle @@ -11,9 +12,12 @@ import androidx.activity.result.contract.ActivityResultContracts import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity import androidx.core.app.ActivityCompat +import androidx.lifecycle.lifecycleScope import io.legado.app.R import io.legado.app.exception.NoStackTraceException +import io.legado.app.utils.registerForActivityResult import io.legado.app.utils.toastOnUi +import kotlinx.coroutines.launch class PermissionActivity : AppCompatActivity() { @@ -24,6 +28,10 @@ class PermissionActivity : AppCompatActivity() { RequestPlugins.sRequestCallback?.onSettingActivityResult() finish() } + private val settingActivityResultAwait = + registerForActivityResult(ActivityResultContracts.StartActivityForResult()) + private val requestPermissionResult = + registerForActivityResult(ActivityResultContracts.RequestPermission()) @SuppressLint("BatteryLife") override fun onCreate(savedInstanceState: Bundle?) { @@ -61,16 +69,23 @@ class PermissionActivity : AppCompatActivity() { } 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() + lifecycleScope.launch { + kotlin.runCatching { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU + && requestPermissionResult.launch(Permissions.POST_NOTIFICATIONS) + ) { + RequestPlugins.sRequestCallback?.onSettingActivityResult() + finish() + } else 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() + } } } } @@ -78,14 +93,29 @@ class PermissionActivity : AppCompatActivity() { Request.TYPE_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS -> showSettingDialog( permissions, rationale ) { - kotlin.runCatching { - val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS) - intent.setData(Uri.parse("package:$packageName")) - intent.setClassName( - "com.android.settings", - "com.android.settings.fuelgauge.RequestIgnoreBatteryOptimizations" - ) - settingActivityResult.launch(intent) + lifecycleScope.launch { + kotlin.runCatching { + val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS) + intent.setData(Uri.parse("package:$packageName")) + val className = + "com.android.settings.fuelgauge.RequestIgnoreBatteryOptimizations" + val activities = packageManager.queryIntentActivities( + intent, + PackageManager.MATCH_DEFAULT_ONLY + ) + if (activities.indexOfFirst { it.activityInfo.name == className } > -1) { + val component = intent.resolveActivity(packageManager) + if (component.className != className) { + intent.setClassName( + "com.android.settings", + className + ) + settingActivityResultAwait.launch(intent) + } + } + intent.component = null + settingActivityResult.launch(intent) + } } } } diff --git a/app/src/main/java/io/legado/app/utils/ActivityResult.kt b/app/src/main/java/io/legado/app/utils/ActivityResult.kt new file mode 100644 index 000000000..653476417 --- /dev/null +++ b/app/src/main/java/io/legado/app/utils/ActivityResult.kt @@ -0,0 +1,45 @@ +package io.legado.app.utils + +import androidx.activity.result.contract.ActivityResultContract +import androidx.appcompat.app.AppCompatActivity +import androidx.core.app.ActivityOptionsCompat +import kotlinx.coroutines.CancellableContinuation +import kotlinx.coroutines.suspendCancellableCoroutine +import kotlin.coroutines.resume + +fun AppCompatActivity.registerForActivityResult(contract: ActivityResultContract): ActivityResultLauncherAwait { + var cout: CancellableContinuation? = null + val launcher = registerForActivityResult(contract) { + cout?.resume(it) + } + return object : ActivityResultLauncherAwait() { + override suspend fun launch(input: I, options: ActivityOptionsCompat?): O { + return suspendCancellableCoroutine { + cout = it + launcher.launch(input, options) + } + } + + override fun unregister() { + launcher.unregister() + } + + override fun getContract(): ActivityResultContract { + return launcher.contract + } + } +} + +abstract class ActivityResultLauncherAwait { + + suspend fun launch(input: I): O { + return launch(input, null) + } + + abstract suspend fun launch(input: I, options: ActivityOptionsCompat?): O + + abstract fun unregister() + + abstract fun getContract(): ActivityResultContract + +}