pref: 后台限制提示

This commit is contained in:
HuanCheng65 2023-03-10 13:12:11 +08:00
parent 6f05be2eca
commit fedb6180fd
No known key found for this signature in database
GPG Key ID: E9031EF91A805148
6 changed files with 100 additions and 33 deletions

View File

@ -20,10 +20,13 @@ import androidx.compose.animation.core.VisibilityThreshold
import androidx.compose.animation.core.spring import androidx.compose.animation.core.spring
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Surface import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.staticCompositionLocalOf import androidx.compose.runtime.staticCompositionLocalOf
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
@ -47,11 +50,17 @@ import com.huanchengfly.tieba.post.ui.page.destinations.MainPageDestination
import com.huanchengfly.tieba.post.ui.utils.DevicePosture import com.huanchengfly.tieba.post.ui.utils.DevicePosture
import com.huanchengfly.tieba.post.ui.utils.isBookPosture import com.huanchengfly.tieba.post.ui.utils.isBookPosture
import com.huanchengfly.tieba.post.ui.utils.isSeparating import com.huanchengfly.tieba.post.ui.utils.isSeparating
import com.huanchengfly.tieba.post.ui.widgets.compose.AlertDialog
import com.huanchengfly.tieba.post.ui.widgets.compose.DialogNegativeButton
import com.huanchengfly.tieba.post.ui.widgets.compose.DialogPositiveButton
import com.huanchengfly.tieba.post.ui.widgets.compose.rememberDialogState
import com.huanchengfly.tieba.post.utils.AccountUtil import com.huanchengfly.tieba.post.utils.AccountUtil
import com.huanchengfly.tieba.post.utils.JobServiceUtil import com.huanchengfly.tieba.post.utils.JobServiceUtil
import com.huanchengfly.tieba.post.utils.PermissionUtils import com.huanchengfly.tieba.post.utils.PermissionUtils
import com.huanchengfly.tieba.post.utils.TiebaUtil import com.huanchengfly.tieba.post.utils.TiebaUtil
import com.huanchengfly.tieba.post.utils.isIgnoringBatteryOptimizations
import com.huanchengfly.tieba.post.utils.newIntentFilter import com.huanchengfly.tieba.post.utils.newIntentFilter
import com.huanchengfly.tieba.post.utils.requestIgnoreBatteryOptimizations
import com.huanchengfly.tieba.post.utils.requestPermission import com.huanchengfly.tieba.post.utils.requestPermission
import com.ramcosta.composedestinations.DestinationsNavHost import com.ramcosta.composedestinations.DestinationsNavHost
import com.ramcosta.composedestinations.animations.defaults.RootNavGraphDefaultAnimations import com.ramcosta.composedestinations.animations.defaults.RootNavGraphDefaultAnimations
@ -178,6 +187,34 @@ class MainActivityV2 : BaseComposeActivity() {
@OptIn(ExperimentalAnimationApi::class, ExperimentalMaterialNavigationApi::class) @OptIn(ExperimentalAnimationApi::class, ExperimentalMaterialNavigationApi::class)
@Composable @Composable
override fun createContent() { override fun createContent() {
val okSignAlertDialogState = rememberDialogState()
AlertDialog(
dialogState = okSignAlertDialogState,
title = { Text(text = stringResource(id = R.string.title_dialog_oksign_battery_optimization)) },
content = { Text(text = stringResource(id = R.string.message_dialog_oksign_battery_optimization)) },
buttons = {
DialogPositiveButton(
text = stringResource(id = R.string.button_go_to_ignore_battery_optimization),
onClick = {
requestIgnoreBatteryOptimizations()
}
)
DialogNegativeButton(
text = stringResource(id = R.string.button_cancel)
)
DialogNegativeButton(
text = stringResource(id = R.string.button_dont_remind_again),
onClick = {
appPreferences.ignoreBatteryOptimizationsDialog = true
}
)
},
)
LaunchedEffect(Unit) {
if (appPreferences.autoSign && !isIgnoringBatteryOptimizations() && !appPreferences.ignoreBatteryOptimizationsDialog) {
okSignAlertDialogState.show()
}
}
CompositionLocalProvider(LocalNotificationCountFlow provides notificationCountFlow) { CompositionLocalProvider(LocalNotificationCountFlow provides notificationCountFlow) {
Surface( Surface(
color = ExtendedTheme.colors.background color = ExtendedTheme.colors.background

View File

@ -174,16 +174,17 @@ open class MainActivity : BaseActivity(), NavigationBarView.OnItemSelectedListen
} }
} }
mViewPager.post { mViewPager.post {
Crashes.hasCrashedInLastSession().thenAccept { hasCrashed -> Crashes.hasCrashedInLastSession()
if (hasCrashed) { .thenAccept { hasCrashed ->
Crashes.getLastSessionCrashReport().thenAccept { if (hasCrashed) {
val device = it.device Crashes.getLastSessionCrashReport().thenAccept {
showDialog { val device = it.device
setTitle(R.string.title_dialog_copy_crash_report) showDialog {
setMessage(R.string.message_dialog_crash) setTitle(R.string.title_dialog_copy_crash_report)
setPositiveButton(R.string.button_copy_crash) { _, _ -> setMessage(R.string.message_dialog_crash)
TiebaUtil.copyText( setPositiveButton(R.string.button_copy_crash) { _, _ ->
this@MainActivity, """ TiebaUtil.copyText(
this@MainActivity, """
App 版本${device.appVersion} App 版本${device.appVersion}
系统版本${device.osVersion} 系统版本${device.osVersion}
机型${device.oemName} ${device.model} 机型${device.oemName} ${device.model}
@ -191,30 +192,42 @@ open class MainActivity : BaseActivity(), NavigationBarView.OnItemSelectedListen
崩溃 崩溃
${it.stackTrace} ${it.stackTrace}
""".trimIndent() """.trimIndent()
) )
}
setNegativeButton(R.string.button_cancel, null)
} }
setNegativeButton(R.string.button_cancel, null)
} }
} }
} }
}
if (!SharedPreferencesUtil.get(SharedPreferencesUtil.SP_APP_DATA) if (!SharedPreferencesUtil.get(SharedPreferencesUtil.SP_APP_DATA)
.getBoolean("notice_dialog", false) .getBoolean("notice_dialog", false)
) { ) {
showDialog( showDialog {
DialogUtil.build(this) setTitle(R.string.title_dialog_notice)
.setTitle(R.string.title_dialog_notice) setMessage(R.string.message_dialog_notice)
.setMessage(R.string.message_dialog_notice) setPositiveButton(R.string.button_sure_default) { _, _ ->
.setPositiveButton(R.string.button_sure_default) { _, _ -> SharedPreferencesUtil.put(
SharedPreferencesUtil.put( this@MainActivity,
this, SharedPreferencesUtil.SP_APP_DATA,
SharedPreferencesUtil.SP_APP_DATA, "notice_dialog",
"notice_dialog", true
true )
) }
} setCancelable(false)
.setCancelable(false) }
.create()) }
if (appPreferences.autoSign && !isIgnoringBatteryOptimizations() && !appPreferences.ignoreBatteryOptimizationsDialog) {
showDialog {
title = getString(R.string.title_dialog_oksign_battery_optimization)
setMessage(R.string.message_dialog_oksign_battery_optimization)
setPositiveButton(R.string.button_go_to_ignore_battery_optimization) { _, _ ->
requestIgnoreBatteryOptimizations()
}
setNeutralButton(R.string.button_cancel, null)
setNegativeButton(R.string.button_dont_remind_again) { _, _ ->
appPreferences.ignoreBatteryOptimizationsDialog = true
}
}
} }
if (shouldShowSwitchSnackBar()) { if (shouldShowSwitchSnackBar()) {
Util.createSnackbar( Util.createSnackbar(

View File

@ -8,7 +8,11 @@ import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.Text import androidx.compose.material.Text
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.* import androidx.compose.material.icons.outlined.BatteryAlert
import androidx.compose.material.icons.outlined.BrowseGallery
import androidx.compose.material.icons.outlined.OfflinePin
import androidx.compose.material.icons.outlined.Speed
import androidx.compose.material.icons.outlined.WatchLater
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.ExperimentalComposeUiApi
@ -32,10 +36,15 @@ import com.huanchengfly.tieba.post.ui.common.prefs.widgets.TextPref
import com.huanchengfly.tieba.post.ui.common.prefs.widgets.TimePickerPerf import com.huanchengfly.tieba.post.ui.common.prefs.widgets.TimePickerPerf
import com.huanchengfly.tieba.post.ui.common.theme.compose.ExtendedTheme import com.huanchengfly.tieba.post.ui.common.theme.compose.ExtendedTheme
import com.huanchengfly.tieba.post.ui.page.settings.LeadingIcon import com.huanchengfly.tieba.post.ui.page.settings.LeadingIcon
import com.huanchengfly.tieba.post.ui.widgets.compose.* import com.huanchengfly.tieba.post.ui.widgets.compose.AvatarIcon
import com.huanchengfly.tieba.post.utils.ignoreBatteryOptimization import com.huanchengfly.tieba.post.ui.widgets.compose.BackNavigationIcon
import com.huanchengfly.tieba.post.ui.widgets.compose.LocalSnackbarHostState
import com.huanchengfly.tieba.post.ui.widgets.compose.MyScaffold
import com.huanchengfly.tieba.post.ui.widgets.compose.Sizes
import com.huanchengfly.tieba.post.ui.widgets.compose.TitleCentredToolbar
import com.huanchengfly.tieba.post.utils.isIgnoringBatteryOptimizations import com.huanchengfly.tieba.post.utils.isIgnoringBatteryOptimizations
import com.huanchengfly.tieba.post.utils.powerManager import com.huanchengfly.tieba.post.utils.powerManager
import com.huanchengfly.tieba.post.utils.requestIgnoreBatteryOptimizations
import com.ramcosta.composedestinations.annotation.Destination import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.navigation.DestinationsNavigator import com.ramcosta.composedestinations.navigation.DestinationsNavigator
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -160,7 +169,7 @@ fun OKSignSettingsPage(
onClick = { onClick = {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!context.powerManager.isIgnoringBatteryOptimizations(context.packageName)) { if (!context.powerManager.isIgnoringBatteryOptimizations(context.packageName)) {
context.ignoreBatteryOptimization() context.requestIgnoreBatteryOptimizations()
} else { } else {
coroutineScope.launch { coroutineScope.launch {
snackbarHostState.showSnackbar(context.getString(R.string.toast_ignore_battery_optimization_already)) snackbarHostState.showSnackbar(context.getString(R.string.toast_ignore_battery_optimization_already))

View File

@ -32,6 +32,8 @@ open class AppPreferencesUtils(context: Context) {
var userLikeLastRequestUnix by DataStoreDelegates.long(defaultValue = 0L) var userLikeLastRequestUnix by DataStoreDelegates.long(defaultValue = 0L)
var ignoreBatteryOptimizationsDialog by DataStoreDelegates.boolean(defaultValue = false)
var appIcon by DataStoreDelegates.string( var appIcon by DataStoreDelegates.string(
defaultValue = Icons.DEFAULT_ICON, defaultValue = Icons.DEFAULT_ICON,
key = AppIconUtil.PREF_KEY_APP_ICON key = AppIconUtil.PREF_KEY_APP_ICON

View File

@ -1,5 +1,6 @@
package com.huanchengfly.tieba.post.utils package com.huanchengfly.tieba.post.utils
import android.annotation.SuppressLint
import android.content.ActivityNotFoundException import android.content.ActivityNotFoundException
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
@ -245,7 +246,8 @@ fun calcStatusBarColorInt(context: Context, @ColorInt originColor: Int): Int {
val Context.powerManager: PowerManager val Context.powerManager: PowerManager
get() = getSystemService(Context.POWER_SERVICE) as PowerManager get() = getSystemService(Context.POWER_SERVICE) as PowerManager
fun Context.ignoreBatteryOptimization() { @SuppressLint("BatteryLife")
fun Context.requestIgnoreBatteryOptimizations() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!powerManager.isIgnoringBatteryOptimizations(packageName)) { if (!powerManager.isIgnoringBatteryOptimizations(packageName)) {
val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS) val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)

View File

@ -204,7 +204,7 @@
<string name="summary_auto_sign">开启后,将每天定时运行一键签到</string> <string name="summary_auto_sign">开启后,将每天定时运行一键签到</string>
<string name="summary_auto_sign_on">自动签到已开启</string> <string name="summary_auto_sign_on">自动签到已开启</string>
<string name="summary_auto_sign_time">当前设置为 %1$s</string> <string name="summary_auto_sign_time">当前设置为 %1$s</string>
<string name="tip_auto_sign">请允许贴吧 Lite 的自启动,否则可能无法正常唤醒签到。\n若使用的是 MIUI 等国产定制 UI你还需要在系统设置中进行相应修改。</string> <string name="tip_auto_sign">请允许贴吧 Lite 的自启动并忽略“电池优化”,否则可能无法正常唤醒签到。\n若使用的是 MIUI 等国产定制 UI你还需要在系统设置中进行相应修改。</string>
<string name="update_tip_no_content">点击查看完整更新日志</string> <string name="update_tip_no_content">点击查看完整更新日志</string>
<string name="title_forum">%1$s吧</string> <string name="title_forum">%1$s吧</string>
<string name="menu_edit_info">编辑资料</string> <string name="menu_edit_info">编辑资料</string>
@ -638,4 +638,8 @@
<string name="emoticon">表情 %s</string> <string name="emoticon">表情 %s</string>
<string name="summary_enable_new_ui">(实验性特性)启用新版 UI。仅少部分页面完成BUG 可能较多,仅供尝鲜使用!</string> <string name="summary_enable_new_ui">(实验性特性)启用新版 UI。仅少部分页面完成BUG 可能较多,仅供尝鲜使用!</string>
<string name="title_enable_new_ui">启用新版 UI</string> <string name="title_enable_new_ui">启用新版 UI</string>
<string name="title_dialog_oksign_battery_optimization">请忽略“电池优化”</string>
<string name="message_dialog_oksign_battery_optimization">在 Android 12 及以上版本中,后台启动前台服务被严格限制。为了避免一键签到无法正常启动,请忽略本应用的“电池优化”。</string>
<string name="button_go_to_ignore_battery_optimization">好的,去忽略</string>
<string name="button_dont_remind_again">不再提示</string>
</resources> </resources>