mirror of
https://github.com/home-assistant/android
synced 2024-09-06 17:23:32 +00:00
Added a sensor to detect if the hotspot is enabled. (#4012)
* Added a sensor to detect if the hotspot is enabled. * Validate if we aren't running a watch before showing hotspot sensor. * Fixed code style issues with the linter. * Fix instant update for hotspot-sensor. * Update hotspot icon to access-point instead of wifi.
This commit is contained in:
parent
af9f131799
commit
f5886dce1a
|
@ -125,6 +125,7 @@ open class HomeAssistantApplication : Application() {
|
||||||
IntentFilter().apply {
|
IntentFilter().apply {
|
||||||
addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION)
|
addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION)
|
||||||
addAction(WifiManager.WIFI_STATE_CHANGED_ACTION)
|
addAction(WifiManager.WIFI_STATE_CHANGED_ACTION)
|
||||||
|
addAction("android.net.wifi.WIFI_AP_STATE_CHANGED")
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -105,6 +105,7 @@ class SensorReceiver : SensorReceiverBase() {
|
||||||
"android.bluetooth.device.action.ACL_CONNECTED" to BluetoothSensorManager.bluetoothConnection.id,
|
"android.bluetooth.device.action.ACL_CONNECTED" to BluetoothSensorManager.bluetoothConnection.id,
|
||||||
"android.bluetooth.device.action.ACL_DISCONNECTED" to BluetoothSensorManager.bluetoothConnection.id,
|
"android.bluetooth.device.action.ACL_DISCONNECTED" to BluetoothSensorManager.bluetoothConnection.id,
|
||||||
"com.oculus.intent.action.MOUNT_STATE_CHANGED" to QuestSensorManager.headsetMounted.id,
|
"com.oculus.intent.action.MOUNT_STATE_CHANGED" to QuestSensorManager.headsetMounted.id,
|
||||||
|
"android.net.wifi.WIFI_AP_STATE_CHANGED" to NetworkSensorManager.hotspotState.id,
|
||||||
BluetoothAdapter.ACTION_STATE_CHANGED to BluetoothSensorManager.bluetoothState.id,
|
BluetoothAdapter.ACTION_STATE_CHANGED to BluetoothSensorManager.bluetoothState.id,
|
||||||
Intent.ACTION_SCREEN_OFF to PowerSensorManager.interactiveDevice.id,
|
Intent.ACTION_SCREEN_OFF to PowerSensorManager.interactiveDevice.id,
|
||||||
Intent.ACTION_SCREEN_ON to PowerSensorManager.interactiveDevice.id,
|
Intent.ACTION_SCREEN_ON to PowerSensorManager.interactiveDevice.id,
|
||||||
|
|
|
@ -3,6 +3,7 @@ package io.homeassistant.companion.android.common.sensors
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.pm.PackageManager
|
||||||
import android.net.ConnectivityManager
|
import android.net.ConnectivityManager
|
||||||
import android.net.NetworkCapabilities
|
import android.net.NetworkCapabilities
|
||||||
import android.net.wifi.WifiInfo
|
import android.net.wifi.WifiInfo
|
||||||
|
@ -24,11 +25,21 @@ import okhttp3.Response
|
||||||
import okio.IOException
|
import okio.IOException
|
||||||
import org.json.JSONException
|
import org.json.JSONException
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
|
import java.lang.reflect.Method
|
||||||
import io.homeassistant.companion.android.common.R as commonR
|
import io.homeassistant.companion.android.common.R as commonR
|
||||||
|
|
||||||
class NetworkSensorManager : SensorManager {
|
class NetworkSensorManager : SensorManager {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "NetworkSM"
|
private const val TAG = "NetworkSM"
|
||||||
|
val hotspotState = SensorManager.BasicSensor(
|
||||||
|
"hotspot_state",
|
||||||
|
"binary_sensor",
|
||||||
|
commonR.string.basic_sensor_name_hotspot_state,
|
||||||
|
commonR.string.sensor_description_hotspot,
|
||||||
|
"mdi:access-point",
|
||||||
|
entityCategory = SensorManager.ENTITY_CATEGORY_DIAGNOSTIC,
|
||||||
|
updateType = SensorManager.BasicSensor.UpdateType.INTENT
|
||||||
|
)
|
||||||
val wifiConnection = SensorManager.BasicSensor(
|
val wifiConnection = SensorManager.BasicSensor(
|
||||||
"wifi_connection",
|
"wifi_connection",
|
||||||
"sensor",
|
"sensor",
|
||||||
|
@ -137,7 +148,12 @@ class NetworkSensorManager : SensorManager {
|
||||||
wifiSignalStrength
|
wifiSignalStrength
|
||||||
)
|
)
|
||||||
val list = if (hasWifi(context)) {
|
val list = if (hasWifi(context)) {
|
||||||
wifiSensors.plus(publicIp)
|
val withPublicIp = wifiSensors.plus(publicIp)
|
||||||
|
if (hasHotspot(context)) {
|
||||||
|
withPublicIp.plus(hotspotState)
|
||||||
|
} else {
|
||||||
|
withPublicIp
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
listOf(publicIp)
|
listOf(publicIp)
|
||||||
}
|
}
|
||||||
|
@ -150,7 +166,7 @@ class NetworkSensorManager : SensorManager {
|
||||||
|
|
||||||
override fun requiredPermissions(sensorId: String): Array<String> {
|
override fun requiredPermissions(sensorId: String): Array<String> {
|
||||||
return when {
|
return when {
|
||||||
sensorId == publicIp.id || sensorId == networkType.id -> {
|
sensorId == hotspotState.id || sensorId == publicIp.id || sensorId == networkType.id -> {
|
||||||
arrayOf()
|
arrayOf()
|
||||||
}
|
}
|
||||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q -> {
|
Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q -> {
|
||||||
|
@ -168,6 +184,7 @@ class NetworkSensorManager : SensorManager {
|
||||||
override fun requestSensorUpdate(
|
override fun requestSensorUpdate(
|
||||||
context: Context
|
context: Context
|
||||||
) {
|
) {
|
||||||
|
updateHotspotEnabledSensor(context)
|
||||||
updateWifiConnectionSensor(context)
|
updateWifiConnectionSensor(context)
|
||||||
updateBSSIDSensor(context)
|
updateBSSIDSensor(context)
|
||||||
updateWifiIPSensor(context)
|
updateWifiIPSensor(context)
|
||||||
|
@ -184,6 +201,39 @@ class NetworkSensorManager : SensorManager {
|
||||||
private fun hasWifi(context: Context): Boolean =
|
private fun hasWifi(context: Context): Boolean =
|
||||||
context.applicationContext.getSystemService<WifiManager>() != null
|
context.applicationContext.getSystemService<WifiManager>() != null
|
||||||
|
|
||||||
|
@SuppressLint("PrivateApi")
|
||||||
|
private fun hasHotspot(context: Context): Boolean {
|
||||||
|
// Watch doesn't have hotspot.
|
||||||
|
if (context.packageManager.hasSystemFeature(PackageManager.FEATURE_WATCH)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
val wifiManager: WifiManager = context.applicationContext.getSystemService()!!
|
||||||
|
return try {
|
||||||
|
wifiManager.javaClass.getDeclaredMethod("isWifiApEnabled")
|
||||||
|
true
|
||||||
|
} catch (e: NoSuchMethodException) {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private fun updateHotspotEnabledSensor(context: Context) {
|
||||||
|
if (!isEnabled(context, hotspotState)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val wifiManager: WifiManager = context.getSystemService()!!
|
||||||
|
|
||||||
|
@SuppressLint("PrivateApi")
|
||||||
|
val method: Method = wifiManager.javaClass.getDeclaredMethod("isWifiApEnabled")
|
||||||
|
method.isAccessible = true
|
||||||
|
val enabled = method.invoke(wifiManager) as Boolean
|
||||||
|
val icon = if (enabled) "mdi:access-point" else "mdi:access-point-off"
|
||||||
|
onSensorUpdated(
|
||||||
|
context,
|
||||||
|
hotspotState,
|
||||||
|
enabled,
|
||||||
|
icon,
|
||||||
|
mapOf()
|
||||||
|
)
|
||||||
|
}
|
||||||
private fun updateWifiConnectionSensor(context: Context) {
|
private fun updateWifiConnectionSensor(context: Context) {
|
||||||
if (!isEnabled(context, wifiConnection) || !hasWifi(context)) {
|
if (!isEnabled(context, wifiConnection) || !hasWifi(context)) {
|
||||||
return
|
return
|
||||||
|
|
|
@ -113,6 +113,7 @@
|
||||||
<string name="basic_sensor_name_wifi_signal">WiFi signal strength</string>
|
<string name="basic_sensor_name_wifi_signal">WiFi signal strength</string>
|
||||||
<string name="basic_sensor_name_wifi_state">WiFi state</string>
|
<string name="basic_sensor_name_wifi_state">WiFi state</string>
|
||||||
<string name="basic_sensor_name_wifi">WiFi connection</string>
|
<string name="basic_sensor_name_wifi">WiFi connection</string>
|
||||||
|
<string name="basic_sensor_name_hotspot_state">Hotspot state</string>
|
||||||
<string name="binary_sensor">Binary sensor</string>
|
<string name="binary_sensor">Binary sensor</string>
|
||||||
<string name="biometric_message">Unlock using your biometric or screen lock credential</string>
|
<string name="biometric_message">Unlock using your biometric or screen lock credential</string>
|
||||||
<string name="biometric_set_title">Confirm to continue</string>
|
<string name="biometric_set_title">Confirm to continue</string>
|
||||||
|
@ -590,6 +591,7 @@
|
||||||
<string name="sensor_description_headphone">Whether headphones are plugged into the device</string>
|
<string name="sensor_description_headphone">Whether headphones are plugged into the device</string>
|
||||||
<string name="sensor_description_headset_mounted">Whether the headset is currently in use</string>
|
<string name="sensor_description_headset_mounted">Whether the headset is currently in use</string>
|
||||||
<string name="sensor_description_high_accuracy_mode">Whether high accuracy mode is active on the device</string>
|
<string name="sensor_description_high_accuracy_mode">Whether high accuracy mode is active on the device</string>
|
||||||
|
<string name="sensor_description_hotspot">Whether the WIFI hotspot is enabled</string>
|
||||||
<string name="sensor_description_interactive">Whether the device is in an interactive state</string>
|
<string name="sensor_description_interactive">Whether the device is in an interactive state</string>
|
||||||
<string name="sensor_description_internal_storage">Information about the total and available storage space internally</string>
|
<string name="sensor_description_internal_storage">Information about the total and available storage space internally</string>
|
||||||
<string name="sensor_description_keyguard_locked">Whether the keyguard is currently locked</string>
|
<string name="sensor_description_keyguard_locked">Whether the keyguard is currently locked</string>
|
||||||
|
|
Loading…
Reference in a new issue