优化
This commit is contained in:
@@ -24,7 +24,6 @@ import io.legado.app.data.entities.RuleSub
|
|||||||
import io.legado.app.data.entities.SearchKeyword
|
import io.legado.app.data.entities.SearchKeyword
|
||||||
import io.legado.app.data.entities.Server
|
import io.legado.app.data.entities.Server
|
||||||
import io.legado.app.data.entities.TxtTocRule
|
import io.legado.app.data.entities.TxtTocRule
|
||||||
import io.legado.app.help.AppWebDav
|
|
||||||
import io.legado.app.help.DirectLinkUpload
|
import io.legado.app.help.DirectLinkUpload
|
||||||
import io.legado.app.help.LauncherIconHelp
|
import io.legado.app.help.LauncherIconHelp
|
||||||
import io.legado.app.help.book.isLocal
|
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.ACache
|
||||||
import io.legado.app.utils.FileUtils
|
import io.legado.app.utils.FileUtils
|
||||||
import io.legado.app.utils.GSON
|
import io.legado.app.utils.GSON
|
||||||
|
import io.legado.app.utils.LogUtils
|
||||||
import io.legado.app.utils.compress.ZipUtils
|
import io.legado.app.utils.compress.ZipUtils
|
||||||
import io.legado.app.utils.defaultSharedPreferences
|
import io.legado.app.utils.defaultSharedPreferences
|
||||||
import io.legado.app.utils.fromJsonArray
|
import io.legado.app.utils.fromJsonArray
|
||||||
@@ -59,7 +59,10 @@ import java.io.FileInputStream
|
|||||||
*/
|
*/
|
||||||
object Restore {
|
object Restore {
|
||||||
|
|
||||||
|
private const val TAG = "Restore"
|
||||||
|
|
||||||
suspend fun restore(context: Context, uri: Uri) {
|
suspend fun restore(context: Context, uri: Uri) {
|
||||||
|
LogUtils.d(TAG, "开始恢复备份 uri:$uri")
|
||||||
kotlin.runCatching {
|
kotlin.runCatching {
|
||||||
FileUtils.delete(Backup.backupPath)
|
FileUtils.delete(Backup.backupPath)
|
||||||
if (uri.isContentScheme()) {
|
if (uri.isContentScheme()) {
|
||||||
@@ -212,7 +215,7 @@ object Restore {
|
|||||||
AppLog.put("恢复阅读界面出错\n${it.localizedMessage}", it)
|
AppLog.put("恢复阅读界面出错\n${it.localizedMessage}", it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AppWebDav.downBgs()
|
//AppWebDav.downBgs()
|
||||||
appCtx.getSharedPreferences(path, "config")?.all?.let { map ->
|
appCtx.getSharedPreferences(path, "config")?.all?.let { map ->
|
||||||
val edit = appCtx.defaultSharedPreferences.edit()
|
val edit = appCtx.defaultSharedPreferences.edit()
|
||||||
|
|
||||||
@@ -266,9 +269,14 @@ object Restore {
|
|||||||
try {
|
try {
|
||||||
val file = File(path, fileName)
|
val file = File(path, fileName)
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
|
LogUtils.d(TAG, "阅读恢复备份 $fileName 文件大小 ${file.length()}")
|
||||||
FileInputStream(file).use {
|
FileInputStream(file).use {
|
||||||
return GSON.fromJsonArray<T>(it).getOrThrow()
|
return GSON.fromJsonArray<T>(it).getOrThrow().also { list ->
|
||||||
|
LogUtils.d(TAG, "阅读恢复备份 $fileName 列表大小 ${list.size}")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
LogUtils.d(TAG, "阅读恢复备份 $fileName 文件不存在")
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
AppLog.put("$fileName\n读取解析出错\n${e.localizedMessage}", e)
|
AppLog.put("$fileName\n读取解析出错\n${e.localizedMessage}", e)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package io.legado.app.lib.permission
|
|||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.content.pm.PackageManager
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
@@ -11,9 +12,12 @@ import androidx.activity.result.contract.ActivityResultContracts
|
|||||||
import androidx.appcompat.app.AlertDialog
|
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 androidx.lifecycle.lifecycleScope
|
||||||
import io.legado.app.R
|
import io.legado.app.R
|
||||||
import io.legado.app.exception.NoStackTraceException
|
import io.legado.app.exception.NoStackTraceException
|
||||||
|
import io.legado.app.utils.registerForActivityResult
|
||||||
import io.legado.app.utils.toastOnUi
|
import io.legado.app.utils.toastOnUi
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
class PermissionActivity : AppCompatActivity() {
|
class PermissionActivity : AppCompatActivity() {
|
||||||
|
|
||||||
@@ -24,6 +28,10 @@ class PermissionActivity : AppCompatActivity() {
|
|||||||
RequestPlugins.sRequestCallback?.onSettingActivityResult()
|
RequestPlugins.sRequestCallback?.onSettingActivityResult()
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
|
private val settingActivityResultAwait =
|
||||||
|
registerForActivityResult(ActivityResultContracts.StartActivityForResult())
|
||||||
|
private val requestPermissionResult =
|
||||||
|
registerForActivityResult(ActivityResultContracts.RequestPermission())
|
||||||
|
|
||||||
@SuppressLint("BatteryLife")
|
@SuppressLint("BatteryLife")
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
@@ -61,16 +69,23 @@ class PermissionActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Request.TYPE_REQUEST_NOTIFICATIONS -> showSettingDialog(permissions, rationale) {
|
Request.TYPE_REQUEST_NOTIFICATIONS -> showSettingDialog(permissions, rationale) {
|
||||||
kotlin.runCatching {
|
lifecycleScope.launch {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
kotlin.runCatching {
|
||||||
//这种方案适用于 API 26, 即8.0(含8.0)以上可以用
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU
|
||||||
val intent = Intent()
|
&& requestPermissionResult.launch(Permissions.POST_NOTIFICATIONS)
|
||||||
intent.action = Settings.ACTION_APP_NOTIFICATION_SETTINGS
|
) {
|
||||||
intent.putExtra(Settings.EXTRA_APP_PACKAGE, packageName)
|
RequestPlugins.sRequestCallback?.onSettingActivityResult()
|
||||||
intent.putExtra(Settings.EXTRA_CHANNEL_ID, applicationInfo.uid)
|
finish()
|
||||||
settingActivityResult.launch(intent)
|
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
} else {
|
//这种方案适用于 API 26, 即8.0(含8.0)以上可以用
|
||||||
openSettingsActivity()
|
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(
|
Request.TYPE_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS -> showSettingDialog(
|
||||||
permissions, rationale
|
permissions, rationale
|
||||||
) {
|
) {
|
||||||
kotlin.runCatching {
|
lifecycleScope.launch {
|
||||||
val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)
|
kotlin.runCatching {
|
||||||
intent.setData(Uri.parse("package:$packageName"))
|
val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)
|
||||||
intent.setClassName(
|
intent.setData(Uri.parse("package:$packageName"))
|
||||||
"com.android.settings",
|
val className =
|
||||||
"com.android.settings.fuelgauge.RequestIgnoreBatteryOptimizations"
|
"com.android.settings.fuelgauge.RequestIgnoreBatteryOptimizations"
|
||||||
)
|
val activities = packageManager.queryIntentActivities(
|
||||||
settingActivityResult.launch(intent)
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 <I, O> AppCompatActivity.registerForActivityResult(contract: ActivityResultContract<I, O>): ActivityResultLauncherAwait<I, O> {
|
||||||
|
var cout: CancellableContinuation<O>? = null
|
||||||
|
val launcher = registerForActivityResult(contract) {
|
||||||
|
cout?.resume(it)
|
||||||
|
}
|
||||||
|
return object : ActivityResultLauncherAwait<I, O>() {
|
||||||
|
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<I, *> {
|
||||||
|
return launcher.contract
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class ActivityResultLauncherAwait<I, O> {
|
||||||
|
|
||||||
|
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<I, *>
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user