f16efce66e83767caab44fa01de27fe805f81667
Yes, the scanner was duplicating. refreshCategoryOptions(), updateRadar() and pairedAdapter.notifyDataSetChanged() ran from acceptSignal on every advertisement AND from pruneTask once a second - the same three calls either way. Worse, the whole persist path ran per advertisement, and ScanCallback is delivered on the main looper: a hex dump of the advertisement, lookupCompany(), get(), lookupOui(), then telemetry(), setDetectedCategory(), recordObservation() and setVendor(). Eight database operations on the UI thread per beacon, at SCAN_MODE_LOW_LATENCY, times every transmitter in range. The radar sweep re-posts itself every 33ms and was competing for that thread, which is why it dragged. A device already on the radar now only gets its RSSI and last-seen stamp refreshed until PERSIST_INTERVAL_MS (3s) is up. A device's first sighting still takes the full path and refreshes at once. The radar view also allocated per frame at 30fps: a six-stop RadialGradient plus two arrays, and a fresh ArrayList and Comparator for the target sort. Both reused now. setTargets no longer invalidates while scanning, since onDraw already re-posts itself. Left setLayerType(SOFTWARE) alone - setShadowLayer only works on text under hardware acceleration, so removing it would drop the ring glow. Separately, history points now say why they exist. location_history had no event column, so schema 16 adds one; connected() and disconnected() stamp it and a plain position refresh leaves it null. The popup shows a linked or broken-link line for the two states and stays quiet for older rows that predate the column. History points also render as the device's own marker at half size rather than a plain circle, sharing one divIcon per device so a long trail does not build a DOM node per point. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Description
BlueToothLogger Android APP for tracking your BLE devices.
5.7 MiB