fix: Android API compat, location permission, characteristic guards#6319
Conversation
associate(), myAssociations, and startObservingDevicePresence use API 33+ signatures. Use legacy APIs on older versions to prevent NoSuchMethodError crashes.
…elow Android 11 and below require ACCESS_FINE_LOCATION for BLE scan results. Request it alongside Bluetooth permissions, and check actual OS status on each scan attempt so returning from settings is handled correctly.
When location permission is missing on older Android, show a clear dialog directing the user to enable it in settings.
…NECT When CompanionDeviceService starts the ForegroundService after process death, BLUETOOTH_CONNECT permission may not be available. Catch the SecurityException and notify Dart with permission_denied error instead of crashing.
Log and return silently instead of throwing. The caller handles missing responses via timeout. Prevents Crashlytics fatal errors when battery timer fires after device disconnects.
Greptile SummaryThis PR fixes four Android BLE reliability issues: API 33+
Confidence Score: 4/5Safe to merge after fixing the missing Platform.isAndroid guard in askForBluetoothPermissions(). One P1 defect: DeviceInfoPlugin().androidInfo is called without a Platform.isAndroid guard in askForBluetoothPermissions(), which throws a PlatformException on non-Android platforms. The same pattern is correctly guarded in scanDevices(). The remaining finding is a P2 l10n violation. All other changes (SecurityException catch, API version guards, writeCharacteristic silent-return) are correct and well-structured. app/lib/providers/onboarding_provider.dart (missing Platform.isAndroid guard around androidInfo call) Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[scanDevices called] --> B{hasBluetoothPermission?}
B -- No --> C[askForBluetoothPermissions]
C --> D{Platform.isIOS?}
D -- Yes --> E[Request bluetooth permission]
D -- No --> F[Request bluetoothScan + bluetoothConnect]
F --> G{Platform.isAndroid AND sdkInt <= 30?}
G -- Yes --> H[Request locationWhenInUse]
G -- No --> I[Skip location]
H --> J[updateLocationPermission]
B -- Yes --> K{Platform.isAndroid?}
C --> K
K -- Yes --> L{sdkInt <= 30?}
K -- No --> M[Start BLE scan]
L -- Yes --> N{locationWhenInUse.isGranted?}
L -- No --> M
N -- Yes --> M
N -- No --> O[onShowLocationDialog → open Settings]
O --> P[return early]
M --> Q[subscribe + initiateConnection]
Reviews (1): Last reviewed commit: "bump ver 806" | Re-trigger Greptile |
- Wrap DeviceInfoPlugin().androidInfo in PlatformService.isAndroid check to prevent crash on non-Android platforms - Add enableLocationTitle and enableLocationDescription l10n keys - Replace hardcoded strings with context.l10n references
…asedHardware#6319) ## Summary - **CompanionDeviceManager API compat for Android < 13** — `associate()`, `myAssociations`, and `startObservingDevicePresence()` use API 33+ signatures. Use legacy APIs on older versions to prevent `NoSuchMethodError` crashes. - **Location permission for BLE scanning on Android 11 and below** — Android 11 and below require `ACCESS_FINE_LOCATION` for BLE scan results. Request it alongside Bluetooth permissions, check actual OS status on each scan attempt, and show a clear dialog directing the user to enable it in settings. - **SecurityException catch on connectGatt** — When CompanionDeviceService starts the ForegroundService after process death, `BLUETOOTH_CONNECT` permission may not be available. Catch `SecurityException` and notify Dart with `permission_denied` error instead of crashing. - **writeCharacteristic silently returns when characteristic is missing** — Previously threw an exception that bubbled up as a Crashlytics fatal error (e.g. battery timer fires after device disconnects). Now logs and returns, consistent with `readCharacteristic` behavior. ## Test plan - [x] Connect device on Android 12 — no `NoSuchMethodError` crash on CompanionDeviceManager - [x] Connect device on Android 11 — location permission prompted, devices discovered after granting - [x] Connect device on Android 13+ — still works - [ ] Revoke Bluetooth permission mid-session — no crash, error sent to Dart 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Summary
associate(),myAssociations, andstartObservingDevicePresence()use API 33+ signatures. Use legacy APIs on older versions to preventNoSuchMethodErrorcrashes.ACCESS_FINE_LOCATIONfor BLE scan results. Request it alongside Bluetooth permissions, check actual OS status on each scan attempt, and show a clear dialog directing the user to enable it in settings.BLUETOOTH_CONNECTpermission may not be available. CatchSecurityExceptionand notify Dart withpermission_deniederror instead of crashing.readCharacteristicbehavior.Test plan
NoSuchMethodErrorcrash on CompanionDeviceManager🤖 Generated with Claude Code