mirror of
https://github.com/rhunk/SnapEnhance.git
synced 2025-06-13 13:47:47 +02:00
feat(setup/permissions): display over other apps
This commit is contained in:
2
app/proguard-rules.pro
vendored
2
app/proguard-rules.pro
vendored
@ -6,5 +6,5 @@
|
||||
-keep class org.jf.dexlib2.** { *; }
|
||||
-keep class org.mozilla.javascript.** { *; }
|
||||
-keep class androidx.compose.material.icons.** { *; }
|
||||
-keep class androidx.navigation.compose.** { *; }
|
||||
-keep class androidx.navigation.** { *; }
|
||||
-keep class me.rhunk.snapenhance.** { *; }
|
||||
|
@ -17,7 +17,11 @@ import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.OutlinedCard
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.mutableStateMapOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
@ -25,6 +29,12 @@ import kotlinx.coroutines.launch
|
||||
import me.rhunk.snapenhance.ui.setup.screens.SetupScreen
|
||||
import me.rhunk.snapenhance.ui.util.ActivityLauncherHelper
|
||||
|
||||
data class PermissionData(
|
||||
val translationKey: String,
|
||||
val isPermissionGranted: () -> Boolean,
|
||||
val requestPermission: (PermissionData) -> Unit,
|
||||
)
|
||||
|
||||
class PermissionsScreen : SetupScreen() {
|
||||
private lateinit var activityLauncherHelper: ActivityLauncherHelper
|
||||
|
||||
@ -53,27 +63,73 @@ class PermissionsScreen : SetupScreen() {
|
||||
@SuppressLint("BatteryLife")
|
||||
@Composable
|
||||
override fun Content() {
|
||||
var notificationPermissionGranted by remember { mutableStateOf(true) }
|
||||
var isBatteryOptimisationIgnored by remember { mutableStateOf(false) }
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
|
||||
if (isBatteryOptimisationIgnored && notificationPermissionGranted) {
|
||||
allowNext(true)
|
||||
} else {
|
||||
allowNext(false)
|
||||
val grantedPermissions = remember {
|
||||
mutableStateMapOf<String, Boolean>()
|
||||
}
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
val permissions = remember {
|
||||
listOf(
|
||||
PermissionData(
|
||||
translationKey = "notification_access",
|
||||
isPermissionGranted = {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
notificationPermissionGranted =
|
||||
context.androidContext.checkSelfPermission(Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED
|
||||
} else {
|
||||
true
|
||||
}
|
||||
},
|
||||
requestPermission = { perm ->
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
activityLauncherHelper.requestPermission(Manifest.permission.POST_NOTIFICATIONS) { resultCode, _ ->
|
||||
coroutineScope.launch {
|
||||
grantedPermissions[perm.translationKey] = resultCode == ComponentActivity.RESULT_OK
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
),
|
||||
PermissionData(
|
||||
translationKey = "battery_optimization",
|
||||
isPermissionGranted = {
|
||||
val powerManager =
|
||||
context.androidContext.getSystemService(Context.POWER_SERVICE) as PowerManager
|
||||
isBatteryOptimisationIgnored =
|
||||
powerManager.isIgnoringBatteryOptimizations(context.androidContext.packageName)
|
||||
if (isBatteryOptimisationIgnored && notificationPermissionGranted) {
|
||||
goNext()
|
||||
},
|
||||
requestPermission = { perm ->
|
||||
activityLauncherHelper.launch(Intent().apply {
|
||||
action = Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
|
||||
data = Uri.parse("package:${context.androidContext.packageName}")
|
||||
}) { resultCode, _ ->
|
||||
coroutineScope.launch {
|
||||
grantedPermissions[perm.translationKey] = resultCode == 0
|
||||
}
|
||||
}
|
||||
}
|
||||
),
|
||||
PermissionData(
|
||||
translationKey = "display_over_other_apps",
|
||||
isPermissionGranted = {
|
||||
Settings.canDrawOverlays(context.androidContext)
|
||||
},
|
||||
requestPermission = { perm ->
|
||||
activityLauncherHelper.launch(Intent().apply {
|
||||
action = Settings.ACTION_MANAGE_OVERLAY_PERMISSION
|
||||
data = Uri.parse("package:${context.androidContext.packageName}")
|
||||
}) { resultCode, _ ->
|
||||
coroutineScope.launch {
|
||||
grantedPermissions[perm.translationKey] = resultCode == 0
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
allowNext(permissions.all { perm -> grantedPermissions[perm.translationKey] == true })
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
permissions.forEach { perm ->
|
||||
grantedPermissions[perm.translationKey] = perm.isPermissionGranted()
|
||||
}
|
||||
}
|
||||
|
||||
@ -88,53 +144,24 @@ class PermissionsScreen : SetupScreen() {
|
||||
modifier = Modifier
|
||||
.padding(all = 16.dp),
|
||||
) {
|
||||
permissions.forEach { perm ->
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
DialogText(
|
||||
text = context.translation["setup.permissions.notification_access"],
|
||||
text = context.translation["setup.permissions.${perm.translationKey}"],
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
if (notificationPermissionGranted) {
|
||||
if (grantedPermissions[perm.translationKey] == true) {
|
||||
GrantedIcon()
|
||||
} else {
|
||||
RequestButton {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
activityLauncherHelper.requestPermission(Manifest.permission.POST_NOTIFICATIONS) { resultCode, _ ->
|
||||
coroutineScope.launch {
|
||||
notificationPermissionGranted =
|
||||
resultCode == ComponentActivity.RESULT_OK
|
||||
perm.requestPermission(perm)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
DialogText(
|
||||
text = context.translation["setup.permissions.battery_optimization"],
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
if (isBatteryOptimisationIgnored) {
|
||||
GrantedIcon()
|
||||
} else {
|
||||
RequestButton {
|
||||
activityLauncherHelper.launch(Intent().apply {
|
||||
action = Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
|
||||
data = Uri.parse("package:${context.androidContext.packageName}")
|
||||
}) { resultCode, _ ->
|
||||
coroutineScope.launch {
|
||||
isBatteryOptimisationIgnored = resultCode == 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -16,6 +16,7 @@
|
||||
"dialog": "To continue you need to fit the following requirements:",
|
||||
"notification_access": "Notification Access",
|
||||
"battery_optimization": "Battery Optimization",
|
||||
"display_over_other_apps": "Display Over Other Apps",
|
||||
"request_button": "Request"
|
||||
}
|
||||
},
|
||||
|
Reference in New Issue
Block a user