diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 9cda6cddb0..b5f7f7ffa0 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -358,10 +358,6 @@ android:windowSoftInputMode="adjustResize|stateAlwaysHidden" android:launchMode="singleTop" android:theme="@style/AppTheme.Blur" /> - = Build.VERSION_CODES.P && !RomUtil.isEmui) { + getSystemService()?.isBackgroundRestricted == true } else { - openIgnoreBatteryOptimizationSetting(newTask) + getSystemService()?.isIgnoringBatteryOptimizations(packageName) == false } } -fun Context.requestIgnoreBatteryOptimization(newTask: Boolean = false) { - Intent().apply { - action = Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS - data = Uri.parse("package:$packageName") - if (newTask) { - addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) +@SuppressLint("BatteryLife") +fun Context.openBatteryOptimizationSetting() { + val appDetailsIntent = + Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply { + data = Uri.parse("package:$packageName") } - try { - startActivity(this) - } catch (e: ActivityNotFoundException) { - Timber.w("Battery optimization activity not found") + val requestIntent = + Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS).apply { + data = Uri.parse("package:$packageName") + } + val intents = + if (RomUtil.isOneUi) { + listOf(appDetailsIntent, requestIntent) + } else if ( + Build.MANUFACTURER.equals("google", ignoreCase = true) || + Build.MANUFACTURER.equals("samsung", ignoreCase = true) || + Build.MANUFACTURER.equals("huawei", ignoreCase = true) || + Build.MANUFACTURER.equals("honor", ignoreCase = true) + ) { + listOf(requestIntent, appDetailsIntent) + } else { + listOf(appDetailsIntent, requestIntent) } + + if (!intents.any(::tryStartActivity)) { + Timber.w("Battery optimization page activity not found") } } -fun Context.openIgnoreBatteryOptimizationSetting(newTask: Boolean = false) { - Intent().apply { - action = Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS - if (newTask) { - addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - } - try { - startActivity(this) - } catch (e: ActivityNotFoundException) { - Timber.w("Power setting activity not found") +private fun Context.tryStartActivity(intent: Intent): Boolean { + val launchIntent = + Intent(intent).apply { + if (this@tryStartActivity !is Activity) { + addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + } } + if (launchIntent.resolveActivity(packageManager) == null) { + return false + } + return try { + startActivity(launchIntent) + true + } catch (e: ActivityNotFoundException) { + false + } catch (e: SecurityException) { + false } } diff --git a/app/src/main/java/one/mixin/android/job/BlazeMessageService.kt b/app/src/main/java/one/mixin/android/job/BlazeMessageService.kt index 0669d7edf6..1f3773288d 100644 --- a/app/src/main/java/one/mixin/android/job/BlazeMessageService.kt +++ b/app/src/main/java/one/mixin/android/job/BlazeMessageService.kt @@ -1,18 +1,14 @@ package one.mixin.android.job import android.annotation.SuppressLint -import android.app.ActivityManager import android.app.PendingIntent import android.content.Context import android.content.Intent import android.content.pm.ServiceInfo -import android.os.Build import android.os.IBinder -import android.os.PowerManager import androidx.core.app.NotificationCompat import androidx.core.app.ServiceCompat import androidx.core.content.ContextCompat -import androidx.core.content.getSystemService import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleService import androidx.lifecycle.lifecycleScope @@ -53,6 +49,7 @@ import one.mixin.android.db.pending.PendingDatabase import one.mixin.android.event.ExpiredEvent import one.mixin.android.extension.base64Encode import one.mixin.android.extension.currentTimeSeconds +import one.mixin.android.extension.isBatteryOptimizationRestricted import one.mixin.android.extension.networkConnected import one.mixin.android.extension.notificationManager import one.mixin.android.extension.supportsOreo @@ -65,11 +62,9 @@ import one.mixin.android.messenger.Hedwig import one.mixin.android.messenger.HedwigImp import one.mixin.android.receiver.ExitBroadcastReceiver import one.mixin.android.session.Session -import one.mixin.android.ui.common.BatteryOptimizationDialogActivity import one.mixin.android.ui.home.MainActivity import one.mixin.android.util.ChannelManager.Companion.createNodeChannel import one.mixin.android.util.GsonHelper -import one.mixin.android.util.RomUtil import one.mixin.android.util.reportException import one.mixin.android.vo.CallStateLiveData import one.mixin.android.vo.MessageStatus @@ -170,8 +165,6 @@ class BlazeMessageService : LifecycleService(), NetworkEventProvider.Listener, C private val accountId = Session.getAccountId() private val gson = GsonHelper.customGson - private val powerManager by lazy { getSystemService() } - private val activityManager by lazy { getSystemService() } private var isIgnoringBatteryOptimizations = false private var disposable: Disposable? = null private val destroyScope = scope(Lifecycle.Event.ON_DESTROY) @@ -241,9 +234,6 @@ class BlazeMessageService : LifecycleService(), NetworkEventProvider.Listener, C if (intent.action == ACTION_TO_BACKGROUND) { stopForeground(STOP_FOREGROUND_REMOVE) - if (!isIgnoringBatteryOptimizations) { - BatteryOptimizationDialogActivity.show(this, true) - } return START_STICKY } @@ -288,11 +278,7 @@ class BlazeMessageService : LifecycleService(), NetworkEventProvider.Listener, C } private fun updateIgnoringBatteryOptimizations() { - isIgnoringBatteryOptimizations = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && !RomUtil.isEmui) { - activityManager?.isBackgroundRestricted?.not() - } else { - powerManager?.isIgnoringBatteryOptimizations(packageName) - } ?: false + isIgnoringBatteryOptimizations = !applicationContext.isBatteryOptimizationRestricted() } @SuppressLint("NewApi") diff --git a/app/src/main/java/one/mixin/android/ui/common/BatteryOptimizationDialogActivity.kt b/app/src/main/java/one/mixin/android/ui/common/BatteryOptimizationDialogActivity.kt deleted file mode 100644 index 103388159a..0000000000 --- a/app/src/main/java/one/mixin/android/ui/common/BatteryOptimizationDialogActivity.kt +++ /dev/null @@ -1,106 +0,0 @@ -package one.mixin.android.ui.common - -import android.content.Context -import android.content.Intent -import android.content.Intent.FLAG_ACTIVITY_NEW_TASK -import android.graphics.Typeface -import android.os.Build -import android.os.Bundle -import android.text.Spannable -import android.text.SpannableStringBuilder -import android.text.style.StyleSpan -import one.mixin.android.R -import one.mixin.android.extension.alertDialogBuilder -import one.mixin.android.extension.handleIgnoreBatteryOptimization -import one.mixin.android.session.Session -import one.mixin.android.util.RomUtil -import timber.log.Timber - -class BatteryOptimizationDialogActivity : BaseActivity() { - companion object { - const val ARGS_NEW_TASK = "args_new_task" - - fun show( - context: Context, - newTask: Boolean = false, - ) { - if (!Session.hasSafe()) return - Intent(context, BatteryOptimizationDialogActivity::class.java).apply { - putExtra(ARGS_NEW_TASK, newTask) - if (newTask) { - addFlags(FLAG_ACTIVITY_NEW_TASK) - } - context.startActivity(this) - } - } - } - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - val newTask = intent.getBooleanExtra(ARGS_NEW_TASK, false) - alertDialogBuilder() - .setMessage( - replaceTags( - getString( - if (RomUtil.isOneUi) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - R.string.setting_battery_optimize_title_one_ui_above_s - } else { - R.string.setting_battery_optimize_title_one_ui_below_s - } - } else { - R.string.setting_battery_optimize_title - }, - ), - ), - ) - .setCancelable(false) - .setNegativeButton(R.string.Cancel) { dialog, _ -> - dialog.dismiss() - finish() - } - .setPositiveButton(R.string.Go_settings) { dialog, _ -> - handleIgnoreBatteryOptimization(newTask) - dialog.dismiss() - finish() - } - .show() - } - - private fun replaceTags(str: String): SpannableStringBuilder { - try { - var start: Int - var end: Int - val stringBuilder = StringBuilder(str) - val bolds: ArrayList = ArrayList() - while (stringBuilder.indexOf("").also { start = it } != -1) { - stringBuilder.replace(start, start + 3, "") - end = stringBuilder.indexOf("") - if (end == -1) { - end = stringBuilder.indexOf("") - } - stringBuilder.replace(end, end + 4, "") - bolds.add(start) - bolds.add(end) - } - while (stringBuilder.indexOf("**").also { start = it } != -1) { - stringBuilder.replace(start, start + 2, "") - end = stringBuilder.indexOf("**") - if (end >= 0) { - stringBuilder.replace(end, end + 2, "") - bolds.add(start) - bolds.add(end) - } - } - - val spannableStringBuilder = SpannableStringBuilder(stringBuilder) - for (a in 0 until bolds.count() / 2) { - spannableStringBuilder.setSpan(StyleSpan(Typeface.BOLD), bolds[a * 2], bolds[a * 2 + 1], Spannable.SPAN_INCLUSIVE_EXCLUSIVE) - } - return spannableStringBuilder - } catch (e: Exception) { - Timber.e(e) - } - return SpannableStringBuilder(str) - } -} diff --git a/app/src/main/java/one/mixin/android/ui/home/MainActivity.kt b/app/src/main/java/one/mixin/android/ui/home/MainActivity.kt index f5076dd4d7..d4c484bae3 100644 --- a/app/src/main/java/one/mixin/android/ui/home/MainActivity.kt +++ b/app/src/main/java/one/mixin/android/ui/home/MainActivity.kt @@ -3,7 +3,6 @@ package one.mixin.android.ui.home import android.Manifest import android.annotation.SuppressLint import android.app.Activity -import android.app.ActivityManager import android.app.Dialog import android.app.NotificationManager import android.content.Context @@ -11,7 +10,6 @@ import android.content.Intent import android.content.IntentSender import android.os.Build import android.os.Bundle -import android.os.PowerManager import androidx.activity.result.contract.ActivityResultContracts import androidx.core.content.getSystemService import androidx.fragment.app.DialogFragment @@ -50,7 +48,6 @@ import one.mixin.android.Constants import one.mixin.android.Constants.APP_VERSION import one.mixin.android.Constants.Account import one.mixin.android.Constants.Account.PREF_BACKUP -import one.mixin.android.Constants.Account.PREF_BATTERY_OPTIMIZE import one.mixin.android.Constants.Account.PREF_CHECK_STORAGE import one.mixin.android.Constants.Account.PREF_DEVICE_SDK import one.mixin.android.Constants.Account.PREF_LOGIN_OR_SIGN_UP @@ -130,7 +127,6 @@ import one.mixin.android.tip.wc.WCEvent import one.mixin.android.tip.wc.WalletConnect import one.mixin.android.tip.wc.WalletConnectV2 import one.mixin.android.ui.common.BaseFragment -import one.mixin.android.ui.common.BatteryOptimizationDialogActivity import one.mixin.android.ui.common.BlazeBaseActivity import one.mixin.android.ui.common.LoginVerifyBottomSheetDialogFragment import one.mixin.android.ui.common.NavigationController @@ -171,7 +167,6 @@ import one.mixin.android.util.BiometricUtil import one.mixin.android.util.ErrorHandler import one.mixin.android.util.ErrorHandler.Companion.SERVER import one.mixin.android.util.GsonHelper -import one.mixin.android.util.RomUtil import one.mixin.android.util.RootUtil import one.mixin.android.util.analytics.AnalyticsTracker import one.mixin.android.util.reportException @@ -471,7 +466,6 @@ class MainActivity : BlazeBaseActivity(), WalletMissingBtcAddressFragment.Callba refreshStickerAlbum() refreshExternalSchemes() cleanCache() - checkBatteryOptimization() if (!defaultSharedPreferences.getBoolean(PREF_SYNC_CIRCLE, false)) { jobManager.addJobInBackground(RefreshCircleJob()) @@ -613,28 +607,6 @@ class MainActivity : BlazeBaseActivity(), WalletMissingBtcAddressFragment.Callba return currentVersion > MINI_VERSION && CURRENT_VERSION != currentVersion } - @SuppressLint("BatteryLife") - private fun checkBatteryOptimization() { - val batteryOptimize = defaultSharedPreferences.getLong(PREF_BATTERY_OPTIMIZE, 0) - val cur = System.currentTimeMillis() - if (cur - batteryOptimize > INTERVAL_24_HOURS) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && !RomUtil.isEmui) { - getSystemService()?.let { am -> - if (am.isBackgroundRestricted) { - BatteryOptimizationDialogActivity.show(this) - } - } - } else { - getSystemService()?.let { pm -> - if (!pm.isIgnoringBatteryOptimizations(packageName)) { - BatteryOptimizationDialogActivity.show(this) - } - } - } - defaultSharedPreferences.putLong(PREF_BATTERY_OPTIMIZE, cur) - } - } - private fun delayShowModifyMobile() = lifecycleScope.launch { delay(2000) diff --git a/app/src/main/java/one/mixin/android/ui/home/reminder/ReminderBottomSheetDialogFragment.kt b/app/src/main/java/one/mixin/android/ui/home/reminder/ReminderBottomSheetDialogFragment.kt index 719589526c..057d4a50dc 100644 --- a/app/src/main/java/one/mixin/android/ui/home/reminder/ReminderBottomSheetDialogFragment.kt +++ b/app/src/main/java/one/mixin/android/ui/home/reminder/ReminderBottomSheetDialogFragment.kt @@ -3,13 +3,17 @@ package one.mixin.android.ui.home.reminder import android.annotation.SuppressLint import android.app.Dialog import android.content.Context +import android.os.Build import android.view.Gravity import android.view.View import android.view.ViewGroup +import androidx.annotation.StringRes import androidx.compose.runtime.Composable +import androidx.compose.ui.res.stringResource import androidx.core.app.NotificationManagerCompat import dagger.hilt.android.AndroidEntryPoint import one.mixin.android.BuildConfig +import one.mixin.android.Constants.Account.PREF_BATTERY_OPTIMIZE import one.mixin.android.Constants.INTERVAL_24_HOURS import one.mixin.android.Constants.INTERVAL_48_HOURS import one.mixin.android.Constants.INTERVAL_7_DAYS @@ -19,7 +23,9 @@ import one.mixin.android.compose.theme.languageBasedImage import one.mixin.android.extension.booleanFromAttribute import one.mixin.android.extension.defaultSharedPreferences import one.mixin.android.extension.getSafeAreaInsetsTop +import one.mixin.android.extension.isBatteryOptimizationRestricted import one.mixin.android.extension.isNightMode +import one.mixin.android.extension.openBatteryOptimizationSetting import one.mixin.android.extension.openNotificationSetting import one.mixin.android.extension.putLong import one.mixin.android.extension.screenHeight @@ -28,6 +34,7 @@ import one.mixin.android.session.Session import one.mixin.android.ui.common.MixinComposeBottomSheetDialogFragment import one.mixin.android.ui.home.MainActivity import one.mixin.android.ui.setting.SettingActivity +import one.mixin.android.util.RomUtil import one.mixin.android.util.SystemUIManager @AndroidEntryPoint @@ -74,6 +81,13 @@ class ReminderBottomSheetDialogFragment : MixinComposeBottomSheetDialogFragment( return PopupType.NotificationPermissionReminder } + val lastBatteryOptimizationReminderTime = sharedPreferences.getLong(PREF_BATTERY_OPTIMIZE, 0) + if (System.currentTimeMillis() - lastBatteryOptimizationReminderTime > INTERVAL_24_HOURS && + context.isBatteryOptimizationRestricted() + ) { + return PopupType.BatteryOptimizationReminder + } + val lastEmergencyContactReminderTime = sharedPreferences.getLong(PREF_EMERGENCY_CONTACT, 0) if (System.currentTimeMillis() - lastEmergencyContactReminderTime > INTERVAL_7_DAYS && totalUsd >= 100 && Session.hasPhone() && @@ -100,6 +114,15 @@ class ReminderBottomSheetDialogFragment : MixinComposeBottomSheetDialogFragment( } return 0 } + + @StringRes + private fun getBatteryOptimizationContentResId(): Int { + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + R.string.setting_battery_optimize_title_one_ui_above_s + } else { + R.string.setting_battery_optimize_title_one_ui_below_s + } + } } private val popupType by lazy { @@ -108,6 +131,7 @@ class ReminderBottomSheetDialogFragment : MixinComposeBottomSheetDialogFragment( PopupType.NewVersionReminder::class.java.simpleName -> PopupType.NewVersionReminder PopupType.BackupMnemonicReminder::class.java.simpleName -> PopupType.BackupMnemonicReminder PopupType.NotificationPermissionReminder::class.java.simpleName -> PopupType.NotificationPermissionReminder + PopupType.BatteryOptimizationReminder::class.java.simpleName -> PopupType.BatteryOptimizationReminder PopupType.RestoreContactReminder::class.java.simpleName -> PopupType.RestoreContactReminder else -> throw IllegalArgumentException("Unknown PopupType") } @@ -148,7 +172,7 @@ class ReminderBottomSheetDialogFragment : MixinComposeBottomSheetDialogFragment( MixinAppTheme { when (popupType) { is PopupType.NewVersionReminder -> { - ReminderPage(R.drawable.bg_reminber_version, R.string.New_Update_Available, R.string.New_Update_Available_desc, R.string.Update_Now, action = { + ReminderPage(R.drawable.bg_reminber_version, R.string.New_Update_Available, stringResource(R.string.New_Update_Available_desc), R.string.Update_Now, action = { Session.getAccount()?.system?.messenger?.let { it -> (requireActivity() as? MainActivity)?.showUpdate(it.releaseUrl) } dismissAllowingStateLoss() }, dismiss = { @@ -161,7 +185,7 @@ class ReminderBottomSheetDialogFragment : MixinComposeBottomSheetDialogFragment( } is PopupType.BackupMnemonicReminder -> { - ReminderPage(R.drawable.bg_reminber_mnemonic, R.string.Backup_Mnemonic_Phrase, R.string.Backup_Mnemonic_Phrase_desc, R.string.Backup_Now, action = { + ReminderPage(R.drawable.bg_reminber_mnemonic, R.string.Backup_Mnemonic_Phrase, stringResource(R.string.Backup_Mnemonic_Phrase_desc), R.string.Backup_Now, action = { SettingActivity.showMnemonicPhrase(requireContext()) dismissAllowingStateLoss() }, dismiss = { @@ -178,7 +202,7 @@ class ReminderBottomSheetDialogFragment : MixinComposeBottomSheetDialogFragment( languageBasedImage( R.drawable.bg_reminder_notifaction, R.drawable.bg_reminder_notifaction_cn - ), R.string.Turn_On_Notifications, R.string.notification_content, R.string.Enable_Notifications, action = { + ), R.string.Turn_On_Notifications, stringResource(R.string.notification_content), R.string.Enable_Notifications, action = { requireContext().openNotificationSetting() dismissAllowingStateLoss() }, dismiss = { @@ -190,8 +214,32 @@ class ReminderBottomSheetDialogFragment : MixinComposeBottomSheetDialogFragment( }) } + is PopupType.BatteryOptimizationReminder -> { + ReminderPage( + R.drawable.bg_reminder_battery_optimization, + R.string.Battery_Optimization, + batteryOptimizationContent(), + R.string.Go_settings, + action = { + requireContext().defaultSharedPreferences.putLong( + PREF_BATTERY_OPTIMIZE, + System.currentTimeMillis(), + ) + requireContext().openBatteryOptimizationSetting() + dismissAllowingStateLoss() + }, + dismiss = { + requireContext().defaultSharedPreferences.putLong( + PREF_BATTERY_OPTIMIZE, + System.currentTimeMillis(), + ) + dismissAllowingStateLoss() + }, + ) + } + is PopupType.RestoreContactReminder -> { - ReminderPage(R.drawable.bg_reminber_recovery_contact, R.string.Emergency_Contact, R.string.setting_emergency_content, R.string.Continue, action = { + ReminderPage(R.drawable.bg_reminber_recovery_contact, R.string.Emergency_Contact, stringResource(R.string.setting_emergency_content), R.string.Continue, action = { SettingActivity.showEmergencyContact(requireContext()) dismissAllowingStateLoss() }, dismiss = { @@ -214,10 +262,18 @@ class ReminderBottomSheetDialogFragment : MixinComposeBottomSheetDialogFragment( override fun showError(error: String) { } + private fun batteryOptimizationContent(): String { + return getString(getBatteryOptimizationContentResId()) + .replace("", "") + .replace("", "") + .replace("**", "") + } + sealed class PopupType { object NewVersionReminder : PopupType() object BackupMnemonicReminder : PopupType() object NotificationPermissionReminder : PopupType() + object BatteryOptimizationReminder : PopupType() object RestoreContactReminder : PopupType() } } diff --git a/app/src/main/java/one/mixin/android/ui/home/reminder/ReminderPage.kt b/app/src/main/java/one/mixin/android/ui/home/reminder/ReminderPage.kt index b8baa4dd12..4b5a32e16e 100644 --- a/app/src/main/java/one/mixin/android/ui/home/reminder/ReminderPage.kt +++ b/app/src/main/java/one/mixin/android/ui/home/reminder/ReminderPage.kt @@ -29,11 +29,17 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import one.mixin.android.R - import one.mixin.android.compose.theme.MixinAppTheme @Composable -fun ReminderPage(@DrawableRes contentImage: Int, @StringRes title: Int, @StringRes content: Int, @StringRes actionStr: Int, action: () -> Unit, dismiss: () -> Unit) { +fun ReminderPage( + @DrawableRes contentImage: Int, + @StringRes title: Int, + content: String, + @StringRes actionStr: Int, + action: () -> Unit, + dismiss: () -> Unit, +) { Column( horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier .clip(RoundedCornerShape(topEnd = 12.dp, topStart = 12.dp)) @@ -73,7 +79,7 @@ fun ReminderPage(@DrawableRes contentImage: Int, @StringRes title: Int, @StringR ) Spacer(modifier = Modifier.height(10.dp)) Text( - text = stringResource(content), + text = content, color = MixinAppTheme.colors.textAssist, modifier = Modifier.fillMaxWidth(), textAlign = androidx.compose.ui.text.style.TextAlign.Center @@ -116,4 +122,4 @@ fun ReminderPage(@DrawableRes contentImage: Int, @StringRes title: Int, @StringR Spacer(modifier = Modifier.height(20.dp)) } } -} \ No newline at end of file +} diff --git a/app/src/main/java/one/mixin/android/ui/home/reminder/VerifyMobileReminderBottomSheetDialogFragment.kt b/app/src/main/java/one/mixin/android/ui/home/reminder/VerifyMobileReminderBottomSheetDialogFragment.kt index 730678b45a..c5fd496502 100644 --- a/app/src/main/java/one/mixin/android/ui/home/reminder/VerifyMobileReminderBottomSheetDialogFragment.kt +++ b/app/src/main/java/one/mixin/android/ui/home/reminder/VerifyMobileReminderBottomSheetDialogFragment.kt @@ -7,6 +7,7 @@ import android.view.Gravity import android.view.View import android.view.ViewGroup import androidx.compose.runtime.Composable +import androidx.compose.ui.res.stringResource import dagger.hilt.android.AndroidEntryPoint import one.mixin.android.Constants import one.mixin.android.R @@ -165,7 +166,7 @@ class VerifyMobileReminderBottomSheetDialogFragment : MixinComposeBottomSheetDia ReminderPage( R.drawable.bg_reminder_verify_mobile, R.string.Verify_Mobile_Number, - subtitleResId, + stringResource(subtitleResId), R.string.Verify_Now, action = { dismissAllowingStateLoss() diff --git a/app/src/main/res/drawable-xxhdpi/bg_reminder_battery_optimization.png b/app/src/main/res/drawable-xxhdpi/bg_reminder_battery_optimization.png new file mode 100644 index 0000000000..511aecc65f Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/bg_reminder_battery_optimization.png differ diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 2020654b0f..fdf0d6cad8 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -839,6 +839,7 @@ Se ha establecido el PIN con éxito Aprobado: %1$s, último acceso: %2$s ID de Mixin, nombre + Optimización de batería Esto mejorará la confiabilidad de las notificaciones entrantes y las llamadas de Mixin. Esto mejorará la confiabilidad de las notificaciones entrantes y las llamadas de Mixin. Selecciona **Optimizado** o **Sin restricciones** en Configuración > Batería. Esto mejorará la confiabilidad de las notificaciones entrantes y las llamadas de Mixin. Pulsa Configuración -> Batería y activa **Permitir actividad en segundo plano**. diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 5cef39beeb..889ab7229c 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -787,6 +787,7 @@ PINコードの設定が完了しました。 許可: %1$s, 最終アクセス: %2$s Mixin ID, 名前 + バッテリー最適化 これにより、通知の受信や Mixinの呼び出しに対する確実性が向上します これにより、通知の受信やMixinの呼び出しに対する確実性が向上します。「設定」→「バッテリー」をタップしてください。そして**「最適化」** もしくは **「制限なし」**を選択してください。 これにより、通知の受信やMixinの呼び出しに対する確実性が向上します。「設定」→「バッテリー」をタップしてください。そして**「バックグラウンドでの活動を許可」**をオンにしてください。 diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 82de20581a..ddecec7345 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -808,6 +808,7 @@ ПИН-код успешно установлен Одобрено: %1$s, последнее обращение: %2$s Mixin ID, имя + Оптимизация батареи Это повысит надежность входящих уведомлений и вызовов Mixin. Это повысит надежность входящих уведомлений и вызовов Mixin. Выберите **Оптимизированный** или **Неограниченный** в меню «Настройки» > «Аккумулятор». Это повысит надежность входящих уведомлений и вызовов Mixin. Нажмите «Настройки» -> «Аккумулятор» и включите **Разрешить фоновую активность**. diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 3468bc3f7f..18623b6a85 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -979,6 +979,7 @@ PIN 设置成功 授权时间:%1$s, 上次访问:%2$s Mixin ID, 昵称 + 电池优化 这将提高 Mixin 通知和呼叫的可靠性。 这将提高 Mixin 通知和呼叫的可靠性. 请在设置 > 电池中选择 **已优化** 或者 **不受限制**。 这将提高 Mixin 通知和呼叫的可靠性。点击设置 -> 电池,开启**允许后台活动**。 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index b029541fbf..fecb678b09 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -794,6 +794,7 @@ PIN 設定成功 授權時間:%1$s, 上次訪問:%2$s Mixin ID, 暱稱 + 電池最佳化 這將提高 Mixin 通知和呼叫的可靠性。 這將提高 Mixin 通知和呼叫的可靠性. 請在設定 > 電池中選擇 **已最佳化** 或者 **不受限制**。 這將提高 Mixin 通知和呼叫的可靠性。點選設定 -> 電池,開啟**允許後臺活動**。 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9006810076..33be5547e0 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1010,6 +1010,7 @@ Set PIN successfully Approved: %1$s, Last Accessed: %2$s Mixin ID, Name + Battery Optimization This will improve reliability for incoming notifications and Mixin calls This will improve reliability for incoming notifications and Mixin calls. Please select **Optimised** or **Unrestricted** in Settings > Battery. This will improve reliability for incoming notifications and Mixin calls. Tap Settings -> Battery and turn **Allow background activity** on.