From 241d724a0f87864e61fa556bad38cb9c7ebd711b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joris=20Pelgr=C3=B6m?= Date: Fri, 6 Sep 2024 05:09:13 +0200 Subject: [PATCH] Add (NOT_)EXPORTED to registerReceiver for Android 14 target (#4559) - For dynamically registered receivers, add whether or not they are exported to prevent a crash due to a behavior change when we start targeting Android 14: https://developer.android.com/about/versions/14/behavior-changes-14#runtime-receivers-exported. Exported or not depends on the list of system intents (not on list = exported to be safe): https://developer.android.com/about/versions/12/reference/broadcast-intents-31. --- .../android/HomeAssistantApplication.kt | 117 ++++++++++++------ .../companion/android/nfc/NfcSetupActivity.kt | 7 +- .../android/sensors/QuestSensorManager.kt | 7 +- .../android/widgets/BaseWidgetProvider.kt | 7 +- .../widgets/template/TemplateWidget.kt | 6 +- .../common/sensors/BatterySensorManager.kt | 5 +- .../common/sensors/SensorReceiverBase.kt | 3 +- .../android/HomeAssistantApplication.kt | 69 +++++++---- 8 files changed, 147 insertions(+), 74 deletions(-) diff --git a/app/src/main/java/io/homeassistant/companion/android/HomeAssistantApplication.kt b/app/src/main/java/io/homeassistant/companion/android/HomeAssistantApplication.kt index 1de9a2a8ec9..3e2ed65ea19 100644 --- a/app/src/main/java/io/homeassistant/companion/android/HomeAssistantApplication.kt +++ b/app/src/main/java/io/homeassistant/companion/android/HomeAssistantApplication.kt @@ -11,6 +11,7 @@ import android.nfc.NfcAdapter import android.os.Build import android.os.PowerManager import android.telephony.TelephonyManager +import androidx.core.content.ContextCompat import dagger.hilt.android.HiltAndroidApp import io.homeassistant.companion.android.common.data.keychain.KeyChainRepository import io.homeassistant.companion.android.common.data.prefs.PrefsRepository @@ -63,7 +64,8 @@ open class HomeAssistantApplication : Application() { languagesManager.applyCurrentLang() // This will make sure we start/stop when we actually need too. - registerReceiver( + ContextCompat.registerReceiver( + this, WebsocketBroadcastReceiver(), IntentFilter().apply { addAction(Intent.ACTION_SCREEN_OFF) @@ -71,7 +73,8 @@ open class HomeAssistantApplication : Application() { addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED) addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION) addAction(WifiManager.WIFI_STATE_CHANGED_ACTION) - } + }, + ContextCompat.RECEIVER_EXPORTED ) ioScope.launch { @@ -82,120 +85,148 @@ open class HomeAssistantApplication : Application() { // This will cause the sensor to be updated every time the OS broadcasts that a cable was plugged/unplugged. // This should be nearly instantaneous allowing automations to fire immediately when a phone is plugged // in or unplugged. Updates will also be triggered when the system reports low battery and when it recovers. - registerReceiver( + ContextCompat.registerReceiver( + this, sensorReceiver, IntentFilter().apply { addAction(Intent.ACTION_BATTERY_LOW) addAction(Intent.ACTION_BATTERY_OKAY) addAction(Intent.ACTION_POWER_CONNECTED) addAction(Intent.ACTION_POWER_DISCONNECTED) - } + }, + ContextCompat.RECEIVER_NOT_EXPORTED ) // This will cause interactive and power save to update upon a state change - registerReceiver( + ContextCompat.registerReceiver( + this, sensorReceiver, IntentFilter().apply { addAction(Intent.ACTION_SCREEN_OFF) addAction(Intent.ACTION_SCREEN_ON) addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED) - } + }, + ContextCompat.RECEIVER_NOT_EXPORTED ) // Update Quest only sensors when the device is a Quest if (Build.MODEL == "Quest") { - registerReceiver( + ContextCompat.registerReceiver( + this, sensorReceiver, IntentFilter().apply { addAction("com.oculus.intent.action.MOUNT_STATE_CHANGED") - } + }, + ContextCompat.RECEIVER_EXPORTED ) } // Update doze mode immediately on supported devices if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - registerReceiver( + ContextCompat.registerReceiver( + this, sensorReceiver, IntentFilter().apply { addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED) - } + }, + ContextCompat.RECEIVER_NOT_EXPORTED ) } // This will trigger an update any time the wifi state has changed - registerReceiver( + ContextCompat.registerReceiver( + this, sensorReceiver, IntentFilter().apply { addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION) addAction(WifiManager.WIFI_STATE_CHANGED_ACTION) addAction("android.net.wifi.WIFI_AP_STATE_CHANGED") - } + }, + ContextCompat.RECEIVER_EXPORTED ) // This will cause the phone state sensor to be updated every time the OS broadcasts that a call triggered. - registerReceiver( + ContextCompat.registerReceiver( + this, sensorReceiver, IntentFilter().apply { addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED) - } + }, + ContextCompat.RECEIVER_NOT_EXPORTED ) // Listen for bluetooth state changes - registerReceiver( + ContextCompat.registerReceiver( + this, sensorReceiver, - IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED) + IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED), + ContextCompat.RECEIVER_NOT_EXPORTED ) // Listen for NFC state changes - registerReceiver( + ContextCompat.registerReceiver( + this, sensorReceiver, - IntentFilter(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED) + IntentFilter(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED), + ContextCompat.RECEIVER_NOT_EXPORTED ) // Listen to changes to the audio input/output on the device - registerReceiver( + ContextCompat.registerReceiver( + this, sensorReceiver, IntentFilter().apply { addAction(AudioManager.ACTION_AUDIO_BECOMING_NOISY) addAction(AudioManager.ACTION_HEADSET_PLUG) addAction(AudioManager.RINGER_MODE_CHANGED_ACTION) addAction(AudioSensorManager.VOLUME_CHANGED_ACTION) - } + }, + ContextCompat.RECEIVER_EXPORTED ) // Listen for microphone mute changes if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { - registerReceiver( + ContextCompat.registerReceiver( + this, sensorReceiver, - IntentFilter(AudioManager.ACTION_MICROPHONE_MUTE_CHANGED) + IntentFilter(AudioManager.ACTION_MICROPHONE_MUTE_CHANGED), + ContextCompat.RECEIVER_NOT_EXPORTED ) } // Listen for speakerphone state changes if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { - registerReceiver( + ContextCompat.registerReceiver( + this, sensorReceiver, - IntentFilter(AudioManager.ACTION_SPEAKERPHONE_STATE_CHANGED) + IntentFilter(AudioManager.ACTION_SPEAKERPHONE_STATE_CHANGED), + ContextCompat.RECEIVER_NOT_EXPORTED ) } // Add receiver for DND changes on devices that support it if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - registerReceiver( + ContextCompat.registerReceiver( + this, sensorReceiver, - IntentFilter(NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED) + IntentFilter(NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED), + ContextCompat.RECEIVER_NOT_EXPORTED ) } - registerReceiver( + ContextCompat.registerReceiver( + this, sensorReceiver, - IntentFilter("androidx.car.app.connection.action.CAR_CONNECTION_UPDATED") + IntentFilter("androidx.car.app.connection.action.CAR_CONNECTION_UPDATED"), + ContextCompat.RECEIVER_EXPORTED ) // Add a receiver for the shutdown event to attempt to send 1 final sensor update - registerReceiver( + ContextCompat.registerReceiver( + this, sensorReceiver, - IntentFilter(Intent.ACTION_SHUTDOWN) + IntentFilter(Intent.ACTION_SHUTDOWN), + ContextCompat.RECEIVER_NOT_EXPORTED ) // Register for all saved user intents @@ -204,7 +235,8 @@ open class HomeAssistantApplication : Application() { for (setting in allSettings) { if (setting.value != "" && setting.value != "SensorWorker") { val settingSplit = setting.value.split(',') - registerReceiver( + ContextCompat.registerReceiver( + this, sensorReceiver, IntentFilter().apply { addAction(settingSplit[0]) @@ -212,28 +244,33 @@ open class HomeAssistantApplication : Application() { val categories = settingSplit.minus(settingSplit[0]) categories.forEach { addCategory(it) } } - } + }, + ContextCompat.RECEIVER_EXPORTED ) } } // Register for changes to the managed profile availability if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - registerReceiver( + ContextCompat.registerReceiver( + this, sensorReceiver, IntentFilter().apply { addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE) addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE) - } + }, + ContextCompat.RECEIVER_NOT_EXPORTED ) } // Register for faster sensor updates if enabled val settingDao = AppDatabase.getInstance(applicationContext).settingsDao().get(0) if (settingDao != null && (settingDao.sensorUpdateFrequency == SensorUpdateFrequencySetting.FAST_WHILE_CHARGING || settingDao.sensorUpdateFrequency == SensorUpdateFrequencySetting.FAST_ALWAYS)) { - registerReceiver( + ContextCompat.registerReceiver( + this, sensorReceiver, - IntentFilter(Intent.ACTION_TIME_TICK) + IntentFilter(Intent.ACTION_TIME_TICK), + ContextCompat.RECEIVER_NOT_EXPORTED ) } @@ -247,9 +284,9 @@ open class HomeAssistantApplication : Application() { screenIntentFilter.addAction(Intent.ACTION_SCREEN_ON) screenIntentFilter.addAction(Intent.ACTION_SCREEN_OFF) - registerReceiver(buttonWidget, screenIntentFilter) - registerReceiver(entityWidget, screenIntentFilter) - registerReceiver(mediaPlayerWidget, screenIntentFilter) - registerReceiver(templateWidget, screenIntentFilter) + ContextCompat.registerReceiver(this, buttonWidget, screenIntentFilter, ContextCompat.RECEIVER_NOT_EXPORTED) + ContextCompat.registerReceiver(this, entityWidget, screenIntentFilter, ContextCompat.RECEIVER_NOT_EXPORTED) + ContextCompat.registerReceiver(this, mediaPlayerWidget, screenIntentFilter, ContextCompat.RECEIVER_NOT_EXPORTED) + ContextCompat.registerReceiver(this, templateWidget, screenIntentFilter, ContextCompat.RECEIVER_NOT_EXPORTED) } } diff --git a/app/src/main/java/io/homeassistant/companion/android/nfc/NfcSetupActivity.kt b/app/src/main/java/io/homeassistant/companion/android/nfc/NfcSetupActivity.kt index 9bacc1dd7f9..ce78ca1592c 100644 --- a/app/src/main/java/io/homeassistant/companion/android/nfc/NfcSetupActivity.kt +++ b/app/src/main/java/io/homeassistant/companion/android/nfc/NfcSetupActivity.kt @@ -10,6 +10,7 @@ import android.util.Log import android.widget.Toast import androidx.activity.compose.setContent import androidx.activity.viewModels +import androidx.core.content.ContextCompat import androidx.lifecycle.lifecycleScope import dagger.hilt.android.AndroidEntryPoint import io.homeassistant.companion.android.BaseActivity @@ -82,9 +83,11 @@ class NfcSetupActivity : BaseActivity() { mNfcAdapter?.let { NFCUtil.enableNFCInForeground(it, this, javaClass) } - registerReceiver( + ContextCompat.registerReceiver( + this, nfcStateChangedReceiver, - IntentFilter(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED) + IntentFilter(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED), + ContextCompat.RECEIVER_NOT_EXPORTED ) } diff --git a/app/src/main/java/io/homeassistant/companion/android/sensors/QuestSensorManager.kt b/app/src/main/java/io/homeassistant/companion/android/sensors/QuestSensorManager.kt index 831a457763a..c0e0c788d35 100644 --- a/app/src/main/java/io/homeassistant/companion/android/sensors/QuestSensorManager.kt +++ b/app/src/main/java/io/homeassistant/companion/android/sensors/QuestSensorManager.kt @@ -4,6 +4,7 @@ import android.content.Context import android.content.Intent import android.content.IntentFilter import android.os.Build +import androidx.core.content.ContextCompat import io.homeassistant.companion.android.common.R as commonR import io.homeassistant.companion.android.common.sensors.SensorManager @@ -45,9 +46,11 @@ class QuestSensorManager : SensorManager { override fun requestSensorUpdate( context: Context ) { - val intent = context.registerReceiver( + val intent = ContextCompat.registerReceiver( + context, null, - IntentFilter("com.oculus.intent.action.MOUNT_STATE_CHANGED") + IntentFilter("com.oculus.intent.action.MOUNT_STATE_CHANGED"), + ContextCompat.RECEIVER_EXPORTED ) if (intent != null) { updateHeadsetMount(context, intent) diff --git a/app/src/main/java/io/homeassistant/companion/android/widgets/BaseWidgetProvider.kt b/app/src/main/java/io/homeassistant/companion/android/widgets/BaseWidgetProvider.kt index 4cfa31b3e5d..275ec96eda9 100644 --- a/app/src/main/java/io/homeassistant/companion/android/widgets/BaseWidgetProvider.kt +++ b/app/src/main/java/io/homeassistant/companion/android/widgets/BaseWidgetProvider.kt @@ -9,6 +9,7 @@ import android.content.IntentFilter import android.os.Bundle import android.util.Log import android.widget.RemoteViews +import androidx.core.content.ContextCompat import io.homeassistant.companion.android.common.data.integration.Entity import io.homeassistant.companion.android.common.data.servers.ServerManager import javax.inject.Inject @@ -95,9 +96,11 @@ abstract class BaseWidgetProvider : AppWidgetProvider() { val allWidgets = getAllWidgetIdsWithEntities(context) val widgetsWithDifferentEntities = allWidgets.filter { it.value.second != widgetEntities[it.key] } if (widgetsWithDifferentEntities.isNotEmpty()) { - context.applicationContext.registerReceiver( + ContextCompat.registerReceiver( + context.applicationContext, this@BaseWidgetProvider, - IntentFilter(Intent.ACTION_SCREEN_OFF) + IntentFilter(Intent.ACTION_SCREEN_OFF), + ContextCompat.RECEIVER_NOT_EXPORTED ) widgetsWithDifferentEntities.forEach { (id, pair) -> diff --git a/app/src/main/java/io/homeassistant/companion/android/widgets/template/TemplateWidget.kt b/app/src/main/java/io/homeassistant/companion/android/widgets/template/TemplateWidget.kt index c0f3e8593a9..528a74023c4 100644 --- a/app/src/main/java/io/homeassistant/companion/android/widgets/template/TemplateWidget.kt +++ b/app/src/main/java/io/homeassistant/companion/android/widgets/template/TemplateWidget.kt @@ -131,9 +131,11 @@ class TemplateWidget : AppWidgetProvider() { val widgetsWithDifferentTemplate = allWidgets.filter { it.template != widgetTemplates[it.id] } if (widgetsWithDifferentTemplate.isNotEmpty()) { if (thisSetScope) { - context.applicationContext.registerReceiver( + ContextCompat.registerReceiver( + context.applicationContext, this@TemplateWidget, - IntentFilter(Intent.ACTION_SCREEN_OFF) + IntentFilter(Intent.ACTION_SCREEN_OFF), + ContextCompat.RECEIVER_NOT_EXPORTED ) } diff --git a/common/src/main/java/io/homeassistant/companion/android/common/sensors/BatterySensorManager.kt b/common/src/main/java/io/homeassistant/companion/android/common/sensors/BatterySensorManager.kt index cfe2e040416..552db1ca71d 100644 --- a/common/src/main/java/io/homeassistant/companion/android/common/sensors/BatterySensorManager.kt +++ b/common/src/main/java/io/homeassistant/companion/android/common/sensors/BatterySensorManager.kt @@ -6,6 +6,7 @@ import android.content.IntentFilter import android.os.BatteryManager import android.os.Build import androidx.annotation.RequiresApi +import androidx.core.content.ContextCompat import io.homeassistant.companion.android.common.R as commonR import io.homeassistant.companion.android.common.util.STATE_UNAVAILABLE import io.homeassistant.companion.android.common.util.STATE_UNKNOWN @@ -143,7 +144,7 @@ class BatterySensorManager : SensorManager { } override fun hasSensor(context: Context): Boolean { - val intent = context.registerReceiver(null, IntentFilter(Intent.ACTION_BATTERY_CHANGED)) + val intent = ContextCompat.registerReceiver(context, null, IntentFilter(Intent.ACTION_BATTERY_CHANGED), ContextCompat.RECEIVER_NOT_EXPORTED) return intent?.getBooleanExtra(BatteryManager.EXTRA_PRESENT, false) == true } @@ -154,7 +155,7 @@ class BatterySensorManager : SensorManager { override fun requestSensorUpdate( context: Context ) { - val intent = context.registerReceiver(null, IntentFilter(Intent.ACTION_BATTERY_CHANGED)) + val intent = ContextCompat.registerReceiver(context, null, IntentFilter(Intent.ACTION_BATTERY_CHANGED), ContextCompat.RECEIVER_NOT_EXPORTED) if (intent != null) { updateBatteryLevel(context, intent) updateBatteryState(context, intent) diff --git a/common/src/main/java/io/homeassistant/companion/android/common/sensors/SensorReceiverBase.kt b/common/src/main/java/io/homeassistant/companion/android/common/sensors/SensorReceiverBase.kt index 3aeec8be617..a2ca482be3f 100644 --- a/common/src/main/java/io/homeassistant/companion/android/common/sensors/SensorReceiverBase.kt +++ b/common/src/main/java/io/homeassistant/companion/android/common/sensors/SensorReceiverBase.kt @@ -11,6 +11,7 @@ import android.content.res.Configuration import android.os.Build import android.util.Log import androidx.core.app.NotificationCompat +import androidx.core.content.ContextCompat import androidx.core.content.getSystemService import io.homeassistant.companion.android.common.R import io.homeassistant.companion.android.common.data.integration.IntegrationException @@ -51,7 +52,7 @@ abstract class SensorReceiverBase : BroadcastReceiver() { SensorUpdateFrequencySetting.FAST_ALWAYS -> true SensorUpdateFrequencySetting.FAST_WHILE_CHARGING -> { val batteryStatusIntent = - context.registerReceiver(null, IntentFilter(Intent.ACTION_BATTERY_CHANGED)) + ContextCompat.registerReceiver(context, null, IntentFilter(Intent.ACTION_BATTERY_CHANGED), ContextCompat.RECEIVER_NOT_EXPORTED) return batteryStatusIntent?.let { BatterySensorManager.getIsCharging(it) } ?: false } else -> false diff --git a/wear/src/main/java/io/homeassistant/companion/android/HomeAssistantApplication.kt b/wear/src/main/java/io/homeassistant/companion/android/HomeAssistantApplication.kt index d0664157c58..89bc5702a93 100644 --- a/wear/src/main/java/io/homeassistant/companion/android/HomeAssistantApplication.kt +++ b/wear/src/main/java/io/homeassistant/companion/android/HomeAssistantApplication.kt @@ -10,6 +10,7 @@ import android.net.wifi.WifiManager import android.nfc.NfcAdapter import android.os.Build import android.os.PowerManager +import androidx.core.content.ContextCompat import dagger.hilt.android.HiltAndroidApp import io.homeassistant.companion.android.common.data.keychain.KeyChainRepository import io.homeassistant.companion.android.common.data.keychain.KeyStoreRepositoryImpl @@ -42,94 +43,116 @@ open class HomeAssistantApplication : Application() { // This will cause the sensor to be updated every time the OS broadcasts that a cable was plugged/unplugged. // This should be nearly instantaneous allowing automations to fire immediately when a phone is plugged // in or unplugged. Updates will also be triggered when the system reports low battery and when it recovers. - registerReceiver( + ContextCompat.registerReceiver( + this, sensorReceiver, IntentFilter().apply { addAction(Intent.ACTION_BATTERY_LOW) addAction(Intent.ACTION_BATTERY_OKAY) addAction(Intent.ACTION_POWER_CONNECTED) addAction(Intent.ACTION_POWER_DISCONNECTED) - } + }, + ContextCompat.RECEIVER_NOT_EXPORTED ) // This will trigger an update any time the wifi state has changed - registerReceiver( + ContextCompat.registerReceiver( + this, sensorReceiver, IntentFilter().apply { addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION) addAction(WifiManager.WIFI_STATE_CHANGED_ACTION) - } + }, + ContextCompat.RECEIVER_EXPORTED ) // This will trigger for DND changes, including bedtime and theater mode - registerReceiver( + ContextCompat.registerReceiver( + this, sensorReceiver, - IntentFilter(NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED) + IntentFilter(NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED), + ContextCompat.RECEIVER_NOT_EXPORTED ) // Listen to changes to the audio input/output on the device - registerReceiver( + ContextCompat.registerReceiver( + this, sensorReceiver, IntentFilter().apply { addAction(AudioManager.ACTION_AUDIO_BECOMING_NOISY) addAction(AudioManager.ACTION_HEADSET_PLUG) addAction(AudioManager.RINGER_MODE_CHANGED_ACTION) addAction(AudioSensorManager.VOLUME_CHANGED_ACTION) - } + }, + ContextCompat.RECEIVER_EXPORTED ) // Listen for microphone mute changes if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { - registerReceiver( + ContextCompat.registerReceiver( + this, sensorReceiver, - IntentFilter(AudioManager.ACTION_MICROPHONE_MUTE_CHANGED) + IntentFilter(AudioManager.ACTION_MICROPHONE_MUTE_CHANGED), + ContextCompat.RECEIVER_NOT_EXPORTED ) } // Listen for speakerphone state changes if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { - registerReceiver( + ContextCompat.registerReceiver( + this, sensorReceiver, - IntentFilter(AudioManager.ACTION_SPEAKERPHONE_STATE_CHANGED) + IntentFilter(AudioManager.ACTION_SPEAKERPHONE_STATE_CHANGED), + ContextCompat.RECEIVER_NOT_EXPORTED ) } // This will cause interactive and power save to update upon a state change - registerReceiver( + ContextCompat.registerReceiver( + this, sensorReceiver, IntentFilter().apply { addAction(Intent.ACTION_SCREEN_OFF) addAction(Intent.ACTION_SCREEN_ON) addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED) - } + }, + ContextCompat.RECEIVER_NOT_EXPORTED ) - registerReceiver( + ContextCompat.registerReceiver( + this, sensorReceiver, IntentFilter().apply { addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED) - } + }, + ContextCompat.RECEIVER_NOT_EXPORTED ) // Listen to changes to Wet Mode State - registerReceiver( + ContextCompat.registerReceiver( + this, sensorReceiver, IntentFilter().apply { addAction("com.google.android.clockwork.actions.WET_MODE_STARTED") addAction("com.google.android.clockwork.actions.WET_MODE_ENDED") - } + }, + ContextCompat.RECEIVER_EXPORTED ) // Listen for bluetooth state changes - registerReceiver( + ContextCompat.registerReceiver( + this, sensorReceiver, - IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED) + IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED), + ContextCompat.RECEIVER_NOT_EXPORTED ) // Listen for NFC state changes - registerReceiver( + ContextCompat.registerReceiver( + this, sensorReceiver, - IntentFilter(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED) + IntentFilter(NfcAdapter.ACTION_ADAPTER_STATE_CHANGED), + ContextCompat.RECEIVER_NOT_EXPORTED ) // Update complications when the screen is on @@ -138,6 +161,6 @@ open class HomeAssistantApplication : Application() { val screenIntentFilter = IntentFilter() screenIntentFilter.addAction(Intent.ACTION_SCREEN_ON) - registerReceiver(complicationReceiver, screenIntentFilter) + ContextCompat.registerReceiver(this, complicationReceiver, screenIntentFilter, ContextCompat.RECEIVER_NOT_EXPORTED) } }