我需要在周围区域扫描蓝牙设备6至12秒。 在此之后,我需要停止发现新设备。
以下代码应该:开始扫描蓝牙设备
打印出find的任何内容
6秒后,取消所有发现和重复过程
问题是蓝牙发现永远不会被取消。 在此代码运行一两分钟之后, onReceive将在同一秒内被调用数十次……
public void startTrackingButton(View view) { Log.d("MAIN", "Track button pressed, isTracking: " + !isTracking); if (isTracking) { isTracking = false; } else { isTracking = true; Thread keepScanning = new Thread(new Runnable() { @Override public void run() { while (isTracking) { if (mBluetoothAdapter.isDiscovering()) { Log.d("MAIN", "Cancelling discovery!"); Log.d("MAIN", String.valueOf(mBluetoothAdapter.cancelDiscovery() + ":" + mBluetoothAdapter.getState())); mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); } startTracking(); try { Thread.sleep(6000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }); keepScanning.start(); } } private void startTracking() { Log.d("MAIN", "Starting Discovery..."); mBluetoothAdapter.startDiscovery(); // Create a BroadcastReceiver for ACTION_FOUND BroadcastReceiver mReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { Log.d("MAIN", "Device Found..."); String action = intent.getAction(); // When discovery finds a device if (BluetoothDevice.ACTION_FOUND.equals(action)) { // Get the BluetoothDevice object from the Intent BluetoothDevice device = intent .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); // Add the name and address to an array adapter to show in a // ListView Log.d("MAIN:", device.getName() + "\n" + device.getAddress()); } } }; // Register the BroadcastReceiver IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); registerReceiver(mReceiver, filter); // Don't forget to unregister // during onDestroy }
这是我的logcat输出:
//onReceive gets called many times in the same second??? 05-01 22:09:56.949: D/MAIN(3757): Cancelling discovery! 05-01 22:09:56.969: D/MAIN(3757): false:12 ///THIS SHOULD BE TRUE 05-01 22:09:56.969: D/MAIN(3757): Starting Discovery... 05-01 22:10:03.009: D/MAIN(3757): Starting Discovery... 05-01 22:10:03.579: D/MAIN(3757): Device Found... 05-01 22:10:03.579: D/MAIN:(3757): TOMSELLECK 05-01 22:10:03.579: D/MAIN:(3757): 06:07:08:09:A1:A1 05-01 22:10:03.579: D/MAIN(3757): Device Found... 05-01 22:10:03.579: D/MAIN:(3757): TOMSELLECK 05-01 22:10:03.579: D/MAIN:(3757): 06:07:08:09:A1:A1 05-01 22:10:03.589: D/MAIN(3757): Device Found... 05-01 22:10:03.589: D/MAIN:(3757): TOMSELLECK 05-01 22:10:03.589: D/MAIN:(3757): 06:07:08:09:A1:A1 05-01 22:10:03.589: D/MAIN(3757): Device Found... 05-01 22:10:03.589: D/MAIN:(3757): TOMSELLECK 05-01 22:10:03.589: D/MAIN:(3757): 06:07:08:09:A1:A1 05-01 22:10:03.589: D/MAIN(3757): Device Found... 05-01 22:10:03.589: D/MAIN:(3757): TOMSELLECK 05-01 22:10:03.589: D/MAIN:(3757): 06:07:08:09:A1:A1
有谁知道如何正确取消所有当前和未决的蓝牙发现?
谢谢你的帮助!
PS我需要重复这个过程的原因是从附近的设备获得新的信号强度值。
每次调用startTracking() ,都会创建并注册另一个BroadcastReceiver 。 因此,在您调用startTracking()十次之后,您有十个接收器等待设备。 find设备后,所有这些接收器都会收到通知,这就解释了为什么会有这么多日志条目。
关于cancelDiscovery返回false,Android的蓝牙代码可能是它最多的错误部分。 看看我find了什么 。 永远不要假设任何与Android上的蓝牙相关的内容都能在不同版本和设备上正常运行 出于调试目的,您可以为BluetoothAdapter.ACTION_DISCOVERY_FINISHED添加侦听器。 也许isDiscovering()在取消后会返回false,但我可以想象取消请求和isDiscovering()返回false之间有一个短暂的延迟。
您的个人BUG建议遇到此错误的客户也喜欢:
某些设备会忽略EXTRA_DISCOVERABLE_DURATION ,并且只能启用120秒的可发现性。 这应该由2.3.6修复,但我看到它发生在2.3.6的三星Galaxy Ace上,所以也许三星打破它或者它毕竟没有修复。 但是我的4.x设备上不会发生这种情况。
如果您实际创建连接,某些Android版本甚至会在不安全的连接上导致配对对话框 。 试图在4.2上连接到未知服务也会这样做 。
有时候,蓝牙只是破坏,直到重新启动才能连接(可能与应用程序崩溃或在测试期间被杀死时没有干净地关闭连接有关,我的直觉是它用完了某种文件描述符风格)资源)。
服务发现可能不可靠 。
另请注意:由于您使用Thread.sleep ,因此线程可能暂停超过6秒的实时,因为当CPUhibernate时, Thread.sleep测量的时间会停止。 根据设备在扫描时的行为方式,这可能会超过6秒。 如果你想使用基于实时的计时,你将不得不使用一个AlarmManager,不幸的是这是一个痛苦的屁股 – 你可能想要为它编写一个薄的包装器。
我不建议取消发现。 这是Android中的错误。 在我所拥有的Nexus 4上,取消有时会导致蓝牙被禁用,直到重启,并且在一些最坏的情况下,直到出厂重置。 我建议让发现完成,然后在结束后立即重新启动。
发现并不需要很长时间,尽管它根据发现时看到的设备数量而有所不同。 这是一个包含8个设备的扫描:
05-07 16:47:53.655: I/MANAGER:BluetoothManager(22019): Bluetooth Discovery Starting... 05-07 16:48:13.687: I/MANAGER:BluetoothManager(22019): Bluetooth Discovery Finished...
请注意,如果您一直运行发现,您将非常快地耗尽电池。