feat: battery optimization warning

This commit is contained in:
Canny 2022-11-29 22:49:23 +03:00
parent 2d5d59d53d
commit d25b67ceef
No known key found for this signature in database
GPG Key ID: 395CCB0AA979F27B
2 changed files with 70 additions and 79 deletions

View File

@ -1,6 +1,13 @@
package app.revanced.manager.ui.screen package app.revanced.manager.ui.screen
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build import android.os.Build
import android.os.PowerManager
import android.provider.Settings
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
@ -11,8 +18,10 @@ import androidx.compose.material3.*
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import app.revanced.manager.R import app.revanced.manager.R
import app.revanced.manager.domain.manager.PreferencesManager import app.revanced.manager.domain.manager.PreferencesManager
import app.revanced.manager.ui.component.GroupHeader import app.revanced.manager.ui.component.GroupHeader
@ -22,6 +31,7 @@ import app.revanced.manager.ui.viewmodel.SettingsViewModel
import org.koin.androidx.compose.get import org.koin.androidx.compose.get
import org.koin.androidx.compose.getViewModel import org.koin.androidx.compose.getViewModel
@SuppressLint("BatteryLife")
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun SettingsScreen( fun SettingsScreen(
@ -30,60 +40,84 @@ fun SettingsScreen(
onClickLicenses: () -> Unit, onClickLicenses: () -> Unit,
) { ) {
val prefs = vm.prefs val prefs = vm.prefs
val context = LocalContext.current
val pm = context.getSystemService(Context.POWER_SERVICE) as PowerManager
var showBatteryButton by remember { mutableStateOf(!pm.isIgnoringBatteryOptimizations(context.packageName)) }
Column( Column(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
.padding(horizontal = 18.dp) .padding(top = 48.dp, start = 18.dp, end = 18.dp)
.verticalScroll(state = rememberScrollState()), .verticalScroll(state = rememberScrollState()),
verticalArrangement = Arrangement.spacedBy(12.dp) verticalArrangement = Arrangement.spacedBy(12.dp)
) { ) {
if (vm.showThemePicker) { if (vm.showThemePicker) {
ThemePicker( ThemePicker(
onDismissRequest = vm::dismissThemePicker, onDismissRequest = vm::dismissThemePicker, onConfirm = vm::setTheme
onConfirm = vm::setTheme
) )
} }
AnimatedVisibility(visible = showBatteryButton) {
Card(
onClick = {
context.startActivity(Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS).apply {
data = Uri.parse("package:${context.packageName}")
})
showBatteryButton = !pm.isIgnoringBatteryOptimizations(context.packageName)
}, shape = MaterialTheme.shapes.extraLarge
) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 12.dp, vertical = 16.dp),
) {
Icon(
Icons.Default.BatteryChargingFull,
"Battery Optimization",
Modifier
.padding(start = 8.dp, end = 16.dp)
.size(24.dp),
)
Column(verticalArrangement = Arrangement.spacedBy(2.dp)) {
Text(
text = "Battery Optimization",
style = MaterialTheme.typography.titleLarge.copy(fontSize = 20.sp),
)
Text(
text = "Manager needs battery optimization to be disabled for working inbackground correctly",
style = MaterialTheme.typography.bodyMedium,
)
}
}
}
}
GroupHeader(stringResource(R.string.appearance)) GroupHeader(stringResource(R.string.appearance))
ListItem( ListItem(modifier = Modifier.clickable { vm.showThemePicker() },
modifier = Modifier.clickable { vm.showThemePicker() },
headlineText = { Text(stringResource(R.string.theme)) }, headlineText = { Text(stringResource(R.string.theme)) },
leadingContent = { Icon(Icons.Default.Style, contentDescription = null) }, leadingContent = { Icon(Icons.Default.Style, contentDescription = null) },
trailingContent = { trailingContent = {
FilledTonalButton(onClick = { vm.showThemePicker() }) { FilledTonalButton(onClick = { vm.showThemePicker() }) {
Text(text = prefs.theme.displayName) Text(text = prefs.theme.displayName)
} }
} })
)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
ListItem( ListItem(modifier = Modifier.clickable { prefs.dynamicColor = !prefs.dynamicColor },
modifier = Modifier.clickable { prefs.dynamicColor = !prefs.dynamicColor },
headlineText = { Text(stringResource(R.string.dynamic_color)) }, headlineText = { Text(stringResource(R.string.dynamic_color)) },
leadingContent = { Icon(Icons.Default.Palette, contentDescription = null) }, leadingContent = { Icon(Icons.Default.Palette, contentDescription = null) },
trailingContent = { trailingContent = {
Switch( Switch(checked = prefs.dynamicColor,
checked = prefs.dynamicColor, onCheckedChange = { prefs.dynamicColor = it })
onCheckedChange = { prefs.dynamicColor = it } })
)
} }
) ListItem(modifier = Modifier.clickable { prefs.sentry = !prefs.sentry },
}
ListItem(
modifier = Modifier.clickable { prefs.sentry = !prefs.sentry },
headlineText = { Text(stringResource(R.string.sentry)) }, headlineText = { Text(stringResource(R.string.sentry)) },
leadingContent = { leadingContent = {
Icon( Icon(
Icons.Default.IntegrationInstructions, Icons.Default.IntegrationInstructions, contentDescription = null
contentDescription = null
) )
}, },
trailingContent = { trailingContent = {
Switch( Switch(checked = prefs.sentry, onCheckedChange = { prefs.sentry = it })
checked = prefs.sentry, })
onCheckedChange = { prefs.sentry = it }
)
}
)
Divider() Divider()
SocialItem(R.string.github, R.drawable.ic_github, vm::openGitHub) SocialItem(R.string.github, R.drawable.ic_github, vm::openGitHub)
SocialItem(R.string.opensource_licenses, Icons.Default.LibraryBooks, onClickLicenses) SocialItem(R.string.opensource_licenses, Icons.Default.LibraryBooks, onClickLicenses)
@ -93,14 +127,11 @@ fun SettingsScreen(
@Composable @Composable
fun ThemePicker( fun ThemePicker(
onDismissRequest: () -> Unit, onDismissRequest: () -> Unit, onConfirm: (Theme) -> Unit, prefs: PreferencesManager = get()
onConfirm: (Theme) -> Unit,
prefs: PreferencesManager = get()
) { ) {
var selectedTheme by remember { mutableStateOf(prefs.theme) } var selectedTheme by remember { mutableStateOf(prefs.theme) }
AlertDialog( AlertDialog(onDismissRequest = onDismissRequest,
onDismissRequest = onDismissRequest,
title = { Text(stringResource(R.string.theme)) }, title = { Text(stringResource(R.string.theme)) },
text = { text = {
Column { Column {
@ -110,29 +141,23 @@ fun ThemePicker(
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
Text( Text(
theme.displayName, theme.displayName, style = MaterialTheme.typography.labelLarge
style = MaterialTheme.typography.labelLarge
) )
Spacer(Modifier.weight(1f, true)) Spacer(Modifier.weight(1f, true))
RadioButton( RadioButton(selected = theme == selectedTheme,
selected = theme == selectedTheme, onClick = { selectedTheme = theme })
onClick = { selectedTheme = theme }
)
} }
} }
} }
}, },
confirmButton = { confirmButton = {
Button( Button(onClick = {
onClick = {
onConfirm(selectedTheme) onConfirm(selectedTheme)
onDismissRequest() onDismissRequest()
} }) {
) {
Text(stringResource(R.string.apply)) Text(stringResource(R.string.apply))
} }
} })
)
} }

View File

@ -1,15 +1,9 @@
package app.revanced.manager.util package app.revanced.manager.util
import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager.NameNotFoundException import android.content.pm.PackageManager.NameNotFoundException
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.Build
import android.os.PowerManager
import android.provider.Settings
import androidx.activity.ComponentActivity
import androidx.core.net.toUri import androidx.core.net.toUri
@ -26,31 +20,3 @@ fun Context.loadIcon(string: String): Drawable? {
null null
} }
} }
fun Context.requestAllFilesAccess() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
startActivity(Intent(
Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION,
Uri.fromParts("package", applicationContext.packageName, null)
).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK
addCategory("android.intent.category.DEFAULT")
})
}
}
@SuppressLint("BatteryLife")
fun Context.requestIgnoreBatteryOptimizations() {
startActivity(Intent(
Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS,
Uri.fromParts("package", packageName, null)
).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK
addCategory("android.intent.category.DEFAULT")
})
}
fun Context.isIgnoringOptimizations(): Boolean {
val pm = getSystemService(ComponentActivity.POWER_SERVICE) as PowerManager
return pm.isIgnoringBatteryOptimizations(packageName)
}