diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml
index 46452f8b..2bb62205 100644
--- a/.github/workflows/android.yml
+++ b/.github/workflows/android.yml
@@ -114,7 +114,7 @@ jobs:
timeout-minutes: 30
strategy:
matrix:
- api-level: [26, 33]
+ api-level: [26, 34]
steps:
- uses: actions/checkout@v4
diff --git a/app/build.gradle b/app/build.gradle
index a9fd187b..e894cc5d 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -37,7 +37,7 @@ android {
defaultConfig {
applicationId "com.geeksville.mesh"
minSdkVersion 21 // The oldest emulator image I have tried is 22 (though 21 probably works)
- targetSdk 33
+ targetSdk 34
versionCode 30315 // format is Mmmss (where M is 1+the numeric major number
versionName "2.3.15"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 0c56ed2b..6aa088e6 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -47,6 +47,7 @@
+
@@ -101,11 +102,13 @@
android:value="false" />
+
= callbackF
}
}
val filter = IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED)
- context.registerReceiver(receiver, filter)
+ context.registerReceiverCompat(receiver, filter)
createBond()
awaitClose { context.unregisterReceiver(receiver) }
diff --git a/app/src/main/java/com/geeksville/mesh/repository/bluetooth/BluetoothRepository.kt b/app/src/main/java/com/geeksville/mesh/repository/bluetooth/BluetoothRepository.kt
index 0a18df10..ec4781ed 100644
--- a/app/src/main/java/com/geeksville/mesh/repository/bluetooth/BluetoothRepository.kt
+++ b/app/src/main/java/com/geeksville/mesh/repository/bluetooth/BluetoothRepository.kt
@@ -14,6 +14,7 @@ import androidx.lifecycle.coroutineScope
import com.geeksville.mesh.android.Logging
import com.geeksville.mesh.CoroutineDispatchers
import com.geeksville.mesh.android.hasBluetoothPermission
+import com.geeksville.mesh.util.registerReceiverCompat
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
@@ -46,7 +47,7 @@ class BluetoothRepository @Inject constructor(
processLifecycle.coroutineScope.launch(dispatchers.default) {
updateBluetoothState()
bluetoothBroadcastReceiverLazy.get().let { receiver ->
- application.registerReceiver(receiver, receiver.intentFilter)
+ application.registerReceiverCompat(receiver, receiver.intentFilter)
}
}
}
diff --git a/app/src/main/java/com/geeksville/mesh/repository/usb/UsbManager.kt b/app/src/main/java/com/geeksville/mesh/repository/usb/UsbManager.kt
index 8bdf50b4..35008225 100644
--- a/app/src/main/java/com/geeksville/mesh/repository/usb/UsbManager.kt
+++ b/app/src/main/java/com/geeksville/mesh/repository/usb/UsbManager.kt
@@ -8,6 +8,7 @@ import android.content.IntentFilter
import android.hardware.usb.UsbDevice
import android.hardware.usb.UsbManager
import com.geeksville.mesh.util.PendingIntentCompat
+import com.geeksville.mesh.util.registerReceiverCompat
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
@@ -32,7 +33,7 @@ internal fun UsbManager.requestPermission(
PendingIntentCompat.FLAG_MUTABLE
)
val filter = IntentFilter(ACTION_USB_PERMISSION)
- context.registerReceiver(receiver, filter)
+ context.registerReceiverCompat(receiver, filter)
requestPermission(device, permissionIntent)
awaitClose { context.unregisterReceiver(receiver) }
diff --git a/app/src/main/java/com/geeksville/mesh/repository/usb/UsbRepository.kt b/app/src/main/java/com/geeksville/mesh/repository/usb/UsbRepository.kt
index d9301cd4..9040b6f4 100644
--- a/app/src/main/java/com/geeksville/mesh/repository/usb/UsbRepository.kt
+++ b/app/src/main/java/com/geeksville/mesh/repository/usb/UsbRepository.kt
@@ -7,6 +7,7 @@ import androidx.lifecycle.Lifecycle
import androidx.lifecycle.coroutineScope
import com.geeksville.mesh.android.Logging
import com.geeksville.mesh.CoroutineDispatchers
+import com.geeksville.mesh.util.registerReceiverCompat
import com.hoho.android.usbserial.driver.UsbSerialDriver
import com.hoho.android.usbserial.driver.UsbSerialProber
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -62,7 +63,7 @@ class UsbRepository @Inject constructor(
processLifecycle.coroutineScope.launch(dispatchers.default) {
refreshStateInternal()
usbBroadcastReceiverLazy.get().let { receiver ->
- application.registerReceiver(receiver, receiver.intentFilter)
+ application.registerReceiverCompat(receiver, receiver.intentFilter)
}
}
}
diff --git a/app/src/main/java/com/geeksville/mesh/util/CompatExtensions.kt b/app/src/main/java/com/geeksville/mesh/util/CompatExtensions.kt
index c0584849..4ab39e67 100644
--- a/app/src/main/java/com/geeksville/mesh/util/CompatExtensions.kt
+++ b/app/src/main/java/com/geeksville/mesh/util/CompatExtensions.kt
@@ -5,11 +5,15 @@ import android.bluetooth.BluetoothDevice
import android.bluetooth.le.ScanResult
import android.companion.AssociationInfo
import android.companion.CompanionDeviceManager
+import android.content.BroadcastReceiver
+import android.content.Context
import android.content.Intent
+import android.content.IntentFilter
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.os.Parcel
import android.os.Parcelable
+import androidx.core.content.ContextCompat
import androidx.core.content.IntentCompat
import androidx.core.os.ParcelCompat
@@ -40,6 +44,14 @@ fun PackageManager.getPackageInfoCompat(packageName: String, flags: Int = 0): Pa
@Suppress("DEPRECATION") getPackageInfo(packageName, flags)
}
+fun Context.registerReceiverCompat(
+ receiver: BroadcastReceiver,
+ filter: IntentFilter,
+ flag: Int = ContextCompat.RECEIVER_NOT_EXPORTED,
+) {
+ ContextCompat.registerReceiver(this, receiver, filter, flag)
+}
+
fun Intent.getAssociationResult(): String? = when {
android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU ->
getParcelableExtraCompat(CompanionDeviceManager.EXTRA_ASSOCIATION)