Your BLE device is powered on and nearby, but the Android app shows an empty device list. Before changing the connection code, determine whether scanning failed to start, the peripheral stopped advertising, or the application discarded a valid result. This guide walks through a practical troubleshooting process using permissions, advertising data, scan callbacks, and controlled comparisons.
Start by Identifying Where Discovery Fails
An empty device list does not tell you which part of BLE discovery failed.
The peripheral may not be advertising. Android may not have permission to scan. A scan may fail to start. Or the app may receive a valid advertisement and remove it before updating the interface.
Separate the problem into three questions:
- Did the app start a scan without an exception or failure callback?
- Did the app receive any scan results?
- Did the target appear in those results before application filtering?
Record evidence at each boundary. A loading spinner proves only that the interface entered a loading state.
Begin with a controlled test: keep the app visible and the screen on, place the peripheral nearby, and run one bounded scan. Avoid changing permissions, firmware, and filters simultaneously.
Confirm That the Peripheral Is Advertising
A powered device is not necessarily discoverable.
Check the firmware’s advertising behavior. Some products advertise only during setup, after a button press, or for a limited period after startup. Others stop advertising while connected to another central.
Disconnect other clients if appropriate, then put the device into its documented discovery mode. Do not assume that a status LED means advertising is active.
Use a BLE inspection app on the same phone to check whether advertisements are visible. Compare tests close together in time, with the same device state.
Interpret the Comparison
- Neither app sees the target: Investigate advertising state, device power, radio conditions, and phone configuration.
- The inspection app sees the target but your app does not: Compare permissions, scan settings, and filters.
- Your callback receives the target but the list remains empty: Investigate parsing, application filtering, and UI state updates.
These observations narrow the investigation; they do not establish a cause by themselves.
Keep a known-working BLE peripheral available as a control. If your app finds it but misses the target, focus on what differs in the target’s advertising data or behavior.
Check Android Version, Target SDK, and Permissions
Record both the phone’s Android version and the app’s target SDK. Permission requirements depend on that combination.
For a modern app targeting Android 12 or higher on Android 12 or higher:
- Declare and request BLUETOOTH_SCAN for discovery.
- Request BLUETOOTH_CONNECT for connection operations and protected Bluetooth APIs your workflow uses.
- Request BLUETOOTH_ADVERTISE only if the phone itself advertises.
- Check the actual runtime grant before invoking the relevant API.
On older Android versions, BLE scanning uses the legacy Bluetooth and location permission model. For Android 10 and 11, foreground discovery generally requires fine location permission; background discovery introduces additional location requirements.
Manifest declarations alone do not grant runtime access. For legacy configurations, also check the phone’s Location setting when diagnosing empty results.
The neverForLocation flag is appropriate only when the app genuinely does not derive physical location from scan results. Android warns that it can filter some BLE beacons. Check this when certain advertisements disappear, rather than removing the flag without reviewing the app’s permission model.
Use the Android Bluetooth permissions guide (https://developer.android.com/develop/connectivity/bluetooth/bt-permissions) to validate the supported configurations.
Verify Bluetooth State Before Starting a Scan
Check BLE support and Bluetooth availability before entering the scanning state.
Android provides BluetoothLeScanner through BluetoothAdapter. The scanner can be unavailable when Bluetooth is disabled.
A clear preflight sequence is:
- Check that the phone supports BLE.
- Obtain the Bluetooth adapter.
- Verify the permissions required for the operations you will call.
- Confirm Bluetooth is enabled.
- Obtain the scanner.
- Start the bounded scan.
If a prerequisite is missing, explain it in the interface. “Allow Nearby devices access” and “Turn on Bluetooth” are more useful than “No devices found.”
Catch and report permission-related exceptions. Do not convert every exception into an empty list.
Android’s Find BLE devices guide (https://developer.android.com/develop/connectivity/bluetooth/ble/find-ble-devices) recommends a scan time limit and stopping once the desired device is found.
Remove Filters During a Controlled Foreground Test
An incorrect filter can make a working scanner appear broken.
For diagnosis, run a short, unfiltered foreground scan with the screen on. Log received results before applying product-specific rules. Restore suitable filters after identifying the mismatch.
Check the configured service UUID, advertised name, manufacturer identifier, payload pattern, and masks.
A service UUID used for discovery must be present in the advertisement data being matched. A service exposed after GATT connection should not be assumed to appear in the advertisement.
Likewise, manufacturer-data matching must follow the actual advertised layout. A firmware revision that changes an offset can invalidate an application’s assumptions.
Fields within a ScanFilter are combined as matching requirements. Adding a name constraint to a UUID constraint can exclude a device whose advertisement omits its name. See the Android ScanFilter reference (https://developer.android.com/reference/android/bluetooth/le/ScanFilter).
Inspect Application Filters Too
Platform filters are only one layer. Check whether your own code rejects results because:
- The name is absent or does not match a prefix.
- The RSSI falls below a threshold.
- An advertisement has an unfamiliar payload version.
- A cached device identifier no longer matches.
- The device is considered a duplicate.
- The result belongs to an older scan session.
Log the rejection reason. Otherwise, “not received” and “received but discarded” remain indistinguishable.
Inspect Advertising Data Instead of Relying on a Name
An advertised name is useful for display, but it should not be the only evidence used to recognize your product.
Android’s ScanRecord exposes the local name, service UUIDs, service data, manufacturer data, and raw advertisement bytes. The local name may be null.
Inspect those fields together and verify them against firmware documentation. The Android ScanRecord reference (https://developer.android.com/reference/android/bluetooth/le/ScanRecord) describes the available data.
For diagnostic logging, capture only the fields needed to explain matching behavior. Redact identifiers when sharing logs.
Avoid treating an observed Bluetooth address as a permanent product identity unless the device’s identity design explicitly supports that assumption.
Document the discovery contract with the firmware team:
- Which field identifies the product family?
- Which field identifies an individual device, if applicable?
- What changes during setup or normal operation?
- How are payload versions distinguished?
- Can firmware updates alter the advertised name or data layout?
This turns discovery from a set of guesses into a testable interface.
Handle Scan Callbacks and Failure Codes
Implement failure handling as carefully as result handling.
ScanCallback provides onScanResult, onBatchScanResults, and onScanFailed. If batching is configured, inspect the batch callback rather than assuming every result arrives individually.
Useful failure categories include:
- Already started: Check duplicate scan requests.
- Application registration failed: Record the configuration and investigate scanner registration.
- Feature unsupported: Review the requested scan options.
- Internal error: Preserve diagnostic evidence before recovery.
- Out of hardware resources: Simplify the configuration and check concurrent scanning.
- Scanning too frequently: Stop rapid retries and apply a bounded recovery policy.
Not all constants are available on every Android API level. Preserve the numeric code alongside its interpreted name. See the Android ScanCallback reference (https://developer.android.com/reference/android/bluetooth/le/ScanCallback).
A failed scan start and a completed scan with zero results should produce different application states.
Also use the same callback instance when stopping the callback-based scan. Creating a new instance for cleanup can leave the original session unmanaged.
Control the Scan Lifecycle
Repeated scan starts can originate from several places: a screen callback, a retry timer, a permission result, or a second tap on the scan button.
Give scanning a single owner and model its state explicitly:
- Idle.
- Checking prerequisites.
- Scanning.
- Stopping.
- Completed.
- Failed.
Assign a session identifier so delayed work from an earlier scan cannot overwrite the current result list.
Record why each scan starts and stops. Pay particular attention to an old timeout that accidentally stops a newer session.
For a diagnostic foreground scan, use immediate reporting and a bounded window appropriate to the peripheral’s advertising behavior. A higher-duty scan can be useful for comparison, but it does not repair missing permissions or incorrect filters.
Do not respond to an empty result list with an endless start-stop loop.
Test Screen-Off and Background Behavior Separately
A successful foreground scan does not validate background discovery.
Android documents that unfiltered scans stop when the screen turns off and resume when it turns on. Use appropriate filters for workflows that require screen-off discovery. See the BluetoothLeScanner reference (https://developer.android.com/reference/android/bluetooth/le/BluetoothLeScanner).
Test these situations independently:
- App visible, screen on.
- App not visible, process still running.
- Screen off.
- Process terminated.
- Phone restarted.
A callback-based workflow depends on the app process remaining alive. Android describes PendingIntent-based scanning and companion-device options for suitable background use cases in its background BLE guide (https://developer.android.com/develop/connectivity/bluetooth/ble/background).
Choose the mechanism around the product requirement. A foreground service is not a universal fix for discovery failures.
Capture a Reproducible Diagnostic Record
A useful bug report should explain exactly what happened during one scan session.
Capture:
- Phone manufacturer, model, and Android version.
- App version and target SDK.
- Runtime permission grants.
- Bluetooth state and relevant legacy Location settings.
- Peripheral hardware and firmware versions.
- Peripheral advertising mode and existing connections.
- Scan filters, reporting delay, and callback type.
- Scan start time, stop time, and stop reason.
- Failure callback codes or exceptions.
- Number of results before and after application filtering.
- Redacted advertisement evidence for the target.
Change one variable at a time and compare against the previous session.
If restarting Bluetooth temporarily helps, preserve that observation. It does not yet explain whether the original cause was lifecycle management, resource exhaustion, or another condition.
Verify the Fix Across Real Devices
Confirm that the fix addresses the original failure without introducing a different discovery problem.
Test:
- Fresh installation and first permission request.
- Permission denial, later grant, and revocation.
- Bluetooth disabled at scan start.
- Peripheral advertising mode entered late.
- Advertisements with no local name.
- Supported firmware payload versions.
- Repeated user-initiated scans.
- Navigation away during scanning.
- Screen-off behavior if required.
- Background discovery if required.
Include more than one phone model and the Android versions the product supports.
Define success in terms of a measurable workflow: the target is recognized within the documented discovery window, duplicate sessions are controlled, and the interface reports missing prerequisites accurately.
Finding the device is one milestone. Connection, service discovery, and command exchange still need their own verification.
Frequently Asked Questions
Why Can a BLE Inspection App Find the Device but My App Cannot?
Compare permissions, filters, scan settings, and the handling of advertising data. The inspection app may display an advertisement that your application rejects.
Start with a controlled unfiltered foreground scan, then add product-specific matching rules one at a time.
Does Increasing Scan Duration Fix the Problem?
A longer window can help reveal infrequent advertisements. It will not fix an invalid filter, a denied permission, or a peripheral that is not advertising.
Measure the advertising behavior before choosing a discovery window.
Should I Filter by Device Name?
Use the name as one piece of evidence. Verify whether the firmware guarantees its presence and stability.
Where possible, define discovery around documented service or manufacturer data, then verify device identity during the connected workflow.
Should I Reset Bluetooth Whenever Scanning Returns Nothing?
Use that as a controlled diagnostic step rather than routine application behavior.
First inspect failure callbacks, scan ownership, filters, and peripheral state. Repeated resets can hide the evidence needed to identify the cause.
Build a Predictable Device Discovery Workflow
Reliable discovery requires agreement between firmware advertising behavior, Android permissions, scan configuration, and application matching rules.
YUNJI’s BLE App Development service (https://yunji-node.com/solutions/ble-app-development) covers discovery, device integration, connection state, and real-device verification.
For a troubleshooting review, prepare the affected phone configurations, firmware versions, advertising samples, and logs from a scan session that missed the target.



