mirror of
https://github.com/home-assistant/android
synced 2024-10-02 22:34:46 +00:00
Add permissions requests to wear OS sensors and add network sensors (#2956)
* Add permissions requests to wear OS sensors * Add intents for network sensors on wear * Separate background/foreground location permission requests * Prompt for background permissions after foreground was successful * Only set sensor to enabled if all permissions are grantted * Review comments * Process more review comments * Remove unnecessary variable update
This commit is contained in:
parent
4ded46af4d
commit
7c792c4d4b
|
@ -4,6 +4,8 @@
|
|||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
|
||||
|
||||
<uses-feature android:name="android.hardware.type.watch" />
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package io.homeassistant.companion.android
|
|||
import android.app.Application
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.net.wifi.WifiManager
|
||||
import dagger.hilt.android.HiltAndroidApp
|
||||
import io.homeassistant.companion.android.complications.ComplicationReceiver
|
||||
import io.homeassistant.companion.android.sensors.SensorReceiver
|
||||
|
@ -26,6 +27,15 @@ open class HomeAssistantApplication : Application() {
|
|||
}
|
||||
)
|
||||
|
||||
// This will trigger an update any time the wifi state has changed
|
||||
registerReceiver(
|
||||
sensorReceiver,
|
||||
IntentFilter().apply {
|
||||
addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION)
|
||||
addAction(WifiManager.WIFI_STATE_CHANGED_ACTION)
|
||||
}
|
||||
)
|
||||
|
||||
// Update complications when the screen is on
|
||||
val complicationReceiver = ComplicationReceiver()
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ import io.homeassistant.companion.android.data.SimplifiedEntity
|
|||
import io.homeassistant.companion.android.database.sensor.SensorDao
|
||||
import io.homeassistant.companion.android.database.wear.FavoritesDao
|
||||
import io.homeassistant.companion.android.database.wear.getAllFlow
|
||||
import io.homeassistant.companion.android.sensors.SensorWorker
|
||||
import io.homeassistant.companion.android.util.RegistriesDataHandler
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
@ -278,6 +279,7 @@ class MainViewModel @Inject constructor(
|
|||
isEnabled: Boolean
|
||||
) {
|
||||
sensorDao.setSensorsEnabled(listOf(basicSensor.id), isEnabled)
|
||||
SensorWorker.start(getApplication())
|
||||
}
|
||||
|
||||
fun getAreaForEntity(entityId: String): AreaRegistryResponse? =
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
package io.homeassistant.companion.android.home.views
|
||||
|
||||
import android.Manifest
|
||||
import android.os.Build
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
|
@ -21,13 +25,48 @@ fun SensorUi(
|
|||
basicSensor: SensorManager.BasicSensor,
|
||||
onSensorClicked: (String, Boolean) -> Unit,
|
||||
) {
|
||||
val perm = manager.checkPermission(LocalContext.current, basicSensor.id)
|
||||
val checked = sensor?.enabled == true
|
||||
|
||||
val backgroundRequest =
|
||||
rememberLauncherForActivityResult(ActivityResultContracts.RequestPermission()) {
|
||||
onSensorClicked(basicSensor.id, it)
|
||||
}
|
||||
|
||||
val permissionLaunch = rememberLauncherForActivityResult(
|
||||
ActivityResultContracts.RequestMultiplePermissions()
|
||||
) { isGranted ->
|
||||
var allGranted = true
|
||||
isGranted.forEach {
|
||||
if (
|
||||
manager.requiredPermissions(basicSensor.id).contains(Manifest.permission.ACCESS_FINE_LOCATION) &&
|
||||
manager.requiredPermissions(basicSensor.id).contains(Manifest.permission.ACCESS_BACKGROUND_LOCATION) &&
|
||||
it.key == Manifest.permission.ACCESS_FINE_LOCATION && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R
|
||||
) {
|
||||
backgroundRequest.launch(Manifest.permission.ACCESS_BACKGROUND_LOCATION)
|
||||
return@forEach
|
||||
}
|
||||
if (!it.value)
|
||||
allGranted = false
|
||||
}
|
||||
onSensorClicked(basicSensor.id, allGranted)
|
||||
}
|
||||
|
||||
val perm = manager.checkPermission(LocalContext.current, basicSensor.id)
|
||||
ToggleChip(
|
||||
checked = (sensor == null && manager.enabledByDefault) ||
|
||||
(sensor?.enabled == true && perm),
|
||||
onCheckedChange = { enabled ->
|
||||
onSensorClicked(basicSensor.id, enabled)
|
||||
val permissions = manager.requiredPermissions(basicSensor.id)
|
||||
if (perm || !enabled)
|
||||
onSensorClicked(basicSensor.id, enabled)
|
||||
else
|
||||
permissionLaunch.launch(
|
||||
if (permissions.size == 1 && permissions[0] == Manifest.permission.ACCESS_BACKGROUND_LOCATION)
|
||||
permissions
|
||||
else
|
||||
permissions.toSet().minus(Manifest.permission.ACCESS_BACKGROUND_LOCATION)
|
||||
.toTypedArray()
|
||||
)
|
||||
},
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
|
|
|
@ -44,20 +44,19 @@ fun SensorsView(
|
|||
ListHeader(id = commonR.string.sensors)
|
||||
}
|
||||
items(sensorManagers.size, { sensorManagers[it].name }) { index ->
|
||||
sensorManagers.forEach { manager ->
|
||||
Row {
|
||||
Chip(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
colors = ChipDefaults.secondaryChipColors(),
|
||||
label = {
|
||||
Text(
|
||||
text = stringResource(manager.name)
|
||||
)
|
||||
},
|
||||
onClick = { onClickSensorManager(manager) }
|
||||
)
|
||||
}
|
||||
val manager = sensorManagers[index]
|
||||
Row {
|
||||
Chip(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
colors = ChipDefaults.secondaryChipColors(),
|
||||
label = {
|
||||
Text(
|
||||
text = stringResource(manager.name)
|
||||
)
|
||||
},
|
||||
onClick = { onClickSensorManager(manager) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,9 +3,11 @@ package io.homeassistant.companion.android.sensors
|
|||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.wifi.WifiManager
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import io.homeassistant.companion.android.BuildConfig
|
||||
import io.homeassistant.companion.android.common.sensors.BatterySensorManager
|
||||
import io.homeassistant.companion.android.common.sensors.NetworkSensorManager
|
||||
import io.homeassistant.companion.android.common.sensors.SensorManager
|
||||
import io.homeassistant.companion.android.common.sensors.SensorReceiverBase
|
||||
|
||||
|
@ -24,7 +26,8 @@ class SensorReceiver : SensorReceiverBase() {
|
|||
companion object {
|
||||
const val TAG = "SensorReceiver"
|
||||
val MANAGERS = listOf(
|
||||
BatterySensorManager()
|
||||
BatterySensorManager(),
|
||||
NetworkSensorManager()
|
||||
)
|
||||
|
||||
const val ACTION_REQUEST_SENSORS_UPDATE =
|
||||
|
@ -33,7 +36,9 @@ class SensorReceiver : SensorReceiverBase() {
|
|||
|
||||
// Suppress Lint because we only register for the receiver if the android version matches the intent
|
||||
@SuppressLint("InlinedApi")
|
||||
override val skippableActions = mapOf<String, String>()
|
||||
override val skippableActions = mapOf(
|
||||
WifiManager.WIFI_STATE_CHANGED_ACTION to NetworkSensorManager.wifiState.id
|
||||
)
|
||||
|
||||
override fun getSensorSettingsIntent(context: Context, id: String): Intent? = null
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue