Fix Settings UI reactivity, resolve compiler warnings, update .gitignore
- Make screen capture permission and battery optimization states reactive - Add lifecycle observer to refresh battery status on resume - Add lifecycle-runtime-compose dependency for non-deprecated LocalLifecycleOwner - Replace deprecated LocalLifecycleOwner import - Remove unused REQUEST_CODE constant - Use KTX createBitmap() and bitmap[x,y] extensions - Add misc.xml and junie.xml to .gitignore
This commit is contained in:
2
android/.gitignore
vendored
2
android/.gitignore
vendored
@@ -7,6 +7,8 @@
|
||||
/.idea/workspace.xml
|
||||
/.idea/navEditor.xml
|
||||
/.idea/assetWizardSettings.xml
|
||||
/.idea/misc.xml
|
||||
/.idea/junie.xml
|
||||
.DS_Store
|
||||
/build
|
||||
/captures
|
||||
|
||||
10
android/.idea/misc.xml
generated
10
android/.idea/misc.xml
generated
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="temurin-21" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
<option name="id" value="Android" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -64,6 +64,7 @@ dependencies {
|
||||
|
||||
// Lifecycle service
|
||||
implementation(libs.lifecycle.service)
|
||||
implementation(libs.lifecycle.runtime.compose)
|
||||
|
||||
// Navigation
|
||||
implementation(libs.navigation.compose)
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
package com.thisux.droidclaw.capture
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.PixelFormat
|
||||
import androidx.core.graphics.createBitmap
|
||||
import androidx.core.graphics.get
|
||||
import android.hardware.display.DisplayManager
|
||||
import android.hardware.display.VirtualDisplay
|
||||
import android.media.ImageReader
|
||||
@@ -19,16 +22,19 @@ class ScreenCaptureManager(private val context: Context) {
|
||||
|
||||
companion object {
|
||||
private const val TAG = "ScreenCapture"
|
||||
const val REQUEST_CODE = 1001
|
||||
val isAvailable = MutableStateFlow(false)
|
||||
|
||||
// Stores MediaProjection consent for use by ConnectionService
|
||||
var consentResultCode: Int? = null
|
||||
var consentData: Intent? = null
|
||||
|
||||
// Expose consent as state so UI can react immediately
|
||||
val hasConsentState = MutableStateFlow(false)
|
||||
|
||||
fun storeConsent(resultCode: Int, data: Intent?) {
|
||||
consentResultCode = resultCode
|
||||
consentData = data
|
||||
hasConsentState.value = (resultCode == Activity.RESULT_OK && data != null)
|
||||
}
|
||||
|
||||
fun hasConsent(): Boolean = consentResultCode != null && consentData != null
|
||||
@@ -86,7 +92,7 @@ class ScreenCaptureManager(private val context: Context) {
|
||||
val rowStride = planes[0].rowStride
|
||||
val rowPadding = rowStride - pixelStride * image.width
|
||||
|
||||
val bitmap = Bitmap.createBitmap(
|
||||
val bitmap = createBitmap(
|
||||
image.width + rowPadding / pixelStride,
|
||||
image.height,
|
||||
Bitmap.Config.ARGB_8888
|
||||
@@ -119,7 +125,7 @@ class ScreenCaptureManager(private val context: Context) {
|
||||
bitmap.width - 1 to bitmap.height - 1,
|
||||
bitmap.width / 2 to bitmap.height / 2
|
||||
)
|
||||
return points.all { (x, y) -> bitmap.getPixel(x, y) == android.graphics.Color.BLACK }
|
||||
return points.all { (x, y) -> bitmap[x, y] == android.graphics.Color.BLACK }
|
||||
}
|
||||
|
||||
fun release() {
|
||||
|
||||
@@ -26,6 +26,7 @@ import androidx.compose.material3.OutlinedButton
|
||||
import androidx.compose.material3.OutlinedTextField
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
@@ -36,8 +37,11 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.lifecycle.compose.LocalLifecycleOwner
|
||||
import androidx.compose.ui.text.input.PasswordVisualTransformation
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleEventObserver
|
||||
import com.thisux.droidclaw.DroidClawApp
|
||||
import com.thisux.droidclaw.accessibility.DroidClawAccessibilityService
|
||||
import com.thisux.droidclaw.capture.ScreenCaptureManager
|
||||
@@ -58,8 +62,21 @@ fun SettingsScreen() {
|
||||
|
||||
val isAccessibilityEnabled by DroidClawAccessibilityService.isRunning.collectAsState()
|
||||
val isCaptureAvailable by ScreenCaptureManager.isAvailable.collectAsState()
|
||||
val hasCaptureConsent = isCaptureAvailable || ScreenCaptureManager.hasConsent()
|
||||
val isBatteryExempt = remember { BatteryOptimization.isIgnoringBatteryOptimizations(context) }
|
||||
val hasConsent by ScreenCaptureManager.hasConsentState.collectAsState()
|
||||
val hasCaptureConsent = isCaptureAvailable || hasConsent
|
||||
|
||||
var isBatteryExempt by remember { mutableStateOf(BatteryOptimization.isIgnoringBatteryOptimizations(context)) }
|
||||
|
||||
val lifecycleOwner = LocalLifecycleOwner.current
|
||||
DisposableEffect(lifecycleOwner) {
|
||||
val observer = LifecycleEventObserver { _, event ->
|
||||
if (event == Lifecycle.Event.ON_RESUME) {
|
||||
isBatteryExempt = BatteryOptimization.isIgnoringBatteryOptimizations(context)
|
||||
}
|
||||
}
|
||||
lifecycleOwner.lifecycle.addObserver(observer)
|
||||
onDispose { lifecycleOwner.lifecycle.removeObserver(observer) }
|
||||
}
|
||||
|
||||
val projectionLauncher = rememberLauncherForActivityResult(
|
||||
ActivityResultContracts.StartActivityForResult()
|
||||
|
||||
@@ -39,6 +39,7 @@ kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-
|
||||
kotlinx-coroutines-android = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-android", version.ref = "kotlinxCoroutines" }
|
||||
datastore-preferences = { group = "androidx.datastore", name = "datastore-preferences", version.ref = "datastore" }
|
||||
lifecycle-service = { group = "androidx.lifecycle", name = "lifecycle-service", version.ref = "lifecycleService" }
|
||||
lifecycle-runtime-compose = { group = "androidx.lifecycle", name = "lifecycle-runtime-compose", version.ref = "lifecycleService" }
|
||||
navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigationCompose" }
|
||||
compose-icons-extended = { group = "androidx.compose.material", name = "material-icons-extended", version.ref = "composeIconsExtended" }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user