Capability detection, degradation, and hardware testing
Android’s API level says which framework contract may exist. It does not prove a particular device has NFC, BLE advertising, a gyroscope, a back camera, Google Play services, a desired camera combination, or healthy hardware.
Capability layers
API available?
↓
hardware feature present?
↓
service/provider available and enabled?
↓
permission granted?
↓
specific operation/configuration supported?
↓
resource currently available?
Model the result so UI can explain the actual recovery:
sealed interface HardwareCapability {
data object Ready : HardwareCapability
data object Unsupported : HardwareCapability
data object PermissionRequired : HardwareCapability
data object Disabled : HardwareCapability
data class Busy(val retryable: Boolean) : HardwareCapability
data class Degraded(val limitations: Set<Limitation>) : HardwareCapability
}
Manifest filtering versus runtime choice
<uses-feature android:name="android.hardware.bluetooth_le" android:required="false" />
<uses-feature android:name="android.hardware.nfc" android:required="false" />
<uses-feature android:name="android.hardware.sensor.gyroscope" android:required="false" />
<uses-feature android:name="android.hardware.camera.any" android:required="false" />
Set required="true" only if the whole app is unusable without it. Otherwise keep installation broad and disable/replace the specific feature.
Graceful alternatives
- BLE device setup: manual code/QR onboarding, later retry, supported-device list.
- NFC tag: QR/barcode/manual identifier.
- absent gyroscope: lower-quality accelerometer experience or hide feature.
- camera unavailable: import from picker or manual entry.
- unsupported multi-use-case camera combination: reduce analysis resolution/unbind optional use case.
Do not display “permission denied” when hardware is absent or Bluetooth is simply off—users cannot fix the wrong diagnosis.
Test pyramid for hardware integrations
Pure protocol tests
Test byte encoders/parsers, fragmentation, state reducers, filters, coordinate transforms, NDEF/APDU parsers, timeouts, and retry policy with deterministic inputs.
Adapter tests with fakes
Wrap framework APIs behind narrow interfaces. Replay callbacks: success, error, stale callback, no callback, disconnect, duplicate event, permission loss.
Emulator/simulator where meaningful
Useful for camera virtual scenes and sensor injection, but does not reproduce vendor Bluetooth stacks, RF conditions, NFC antenna behavior, camera quality, or power accurately.
Real-device lab
Maintain a risk-based matrix across API levels, vendors, chipsets, RAM tiers, orientations, firmware/peripherals, and permission states. Automate long-run soak tests and capture sanitized diagnostics.
Observability without leaking data
Record operation/state/error codes, duration, device/app/firmware compatibility metadata, retry counts, and queue depth. Avoid raw scanned device names/addresses, NFC payloads, sensor histories, images, or secrets. Provide an explicit user-consented diagnostic export when support needs more.
Sources
Interview question
Why is an API-level check insufficient? Platform version, hardware presence, enabled state, permission, operation-specific support, and current resource availability are independent gates.