2015-02-12 31 views
8

Tôi đang làm việc trên một dự án để định cấu hình đèn hiệu. Một khoảng thời gian nhất định sau khi được bật nguồn, đèn hiệu trở nên không thể định cấu hình cho đến khi nó được xoay vòng nguồn. Để hiển thị danh sách các cảnh báo có thể định cấu hình, tôi đang xem xét các đặc điểm nhất định (tên thiết bị Bluetooth, dữ liệu nhà sản xuất nhất định trong gói quảng cáo). Tôi cũng cần phải biết nếu nó là "kết nối", tôi. e. nếu Kiểu PDU trong gói quảng cáo BLE cho thiết bị cho biết rằng nó có thể kết nối được. Tôi đã tìm kiếm các lớp học Android Bluetooth cao và thấp, cả trong Android 4.X và 5.X và đã không thể tìm thấy bất cứ điều gì mà sẽ cho tôi biết thông tin này.Phát hiện xem thiết bị BLE có thể kết nối được trên Android

Tôi nhận thấy rằng một cách để xác định khả năng kết nối đèn hiệu là kết nối với nó, e. g .: device.connectGatt(...). Tuy nhiên, tôi đã nhìn thấy nó mất hơn hai phút đôi khi trước khi gọi lại đến onConnectionStateChange quay lại với STATE_DISCONNECTED. Ngoài ra, có thể có nhiều cảnh báo trong môi trường này và kết nối với từng cảnh báo riêng lẻ mà có thể có thể định cấu hình sẽ không hiệu quả.

Tương đương iOS của thuộc tính này có thể được tìm thấy trong từ advertisementData từ điển theo khóa CBAdvertisementDataIsConnectable trong phương thức gọi lại CBCentralManagerDelegatecentralManager:didDiscoverPeripheral:advertisementData:RSSI.

Vì vậy, câu hỏi đặt ra là: có cách nào trên Android để xác định xem thiết bị BLE có "kết nối" từ dữ liệu quảng cáo hoặc kết quả quét hay không ...?

Trả lời

7

UPDATE: AS của API đã quyết toán trong Android SDK O, lớp ScanResult (thêm vào như là của Android 5.0) bây giờ có phương pháp isConnectable(). Chỉ phát hiện quảng cáo có thể kết nối trên Android 8.0+. Xem tại đây để biết thêm thông tin: https://developer.android.com/reference/android/bluetooth/le/ScanResult.html#isConnectable()

Trước Android 8.0, thật không may là không thể.

Một quảng cáo khả năng kết nối được xác định bởi các byte PDU header 0. Bạn có thể thấy điều này trong ví dụ cấu trúc dưới đây:

d6 be 89 8e # Access address for advertising data (this is always the same fixed value) 
40 # Advertising Channel PDU Header byte 0. Contains: (type = 0), (tx add = 1), (rx add = 0) 
24 # Advertising Channel PDU Header byte 1. Contains: (length = total bytes of the advertising payload + 6 bytes for the BLE mac address.) 
05 a2 17 6e 3d 71 # Bluetooth Mac 

Vấn đề là trên các thiết bị trước khi Anroid 8.0, các API quét Android cung cấp cho bạn không truy cập vào các tiêu đề này. Bạn nhận được đúng ba lĩnh vực gọi lại từ 4.x Android:

onLeScan(BluetoothDevice device, rssi, byte[] scan data) 

Việc quét mảng dữ liệu byte bắt đầu sau các byte tiêu đề nêu trên. Và từ những gì tôi có thể thấy định nghĩa BluetoothDevice, không có trường hoặc phương thức nào cho bạn biết đó có phải là quảng cáo có thể kết nối hay không - lớp này chỉ là vùng chứa cho địa chỉ mac bluetooth với các phương pháp để thực hiện các chức năng trên ngăn xếp bluetooth. Và không có phương pháp nào trong IBluetooth.aidl là giao diện riêng cho ngăn xếp bluetooth (và những gì gọi là BluetoothDevice cuộc gọi để nhận thông tin của nó) có thể nhận được cờ này.

Dường như thông tin này không được chuyển lên lớp Java từ ngăn BlueDroid trước Android 8.0.

+0

Cho rằng khẳng định của bạn phù hợp với những phát hiện của riêng tôi, tôi nghĩ câu trả lời ở đây là không có câu trả lời. :-( – mharper

+1

Tôi rất tiếc vì đã đúng lúc này – davidgyoung

+0

Điều này hiện có thể là của Android O – davidgyoung

4

Điều này có thể xảy ra vì Bảng điều khiển chính của NRF của Nordic thực hiện việc này.

Sau một số lần đào, tôi nghĩ tôi biết cách thực hiện điều này. Tôi không chắc chắn đó là cách đúng đắn để làm điều đó mặc dù.

Tôi đã thử sử dụng LE Advertiser và đặt thiết bị là có thể kết nối.Trong ứng dụng Nordic, một thiết bị được đặt là có thể kết nối tùy thuộc vào các byte được tìm thấy tại scanResult.getFlags().

tôi thấy rằng mã này làm việc cho các thiết bị của tôi:

int flags = scanResult.getScanRecord().getAdvertiseFlags(); 
if ((flags & 2) == 2) { 
    //connectable 
} 
+0

Thú vị. Đối tượng 'ScanRecord' đã được thêm vào Android 5.0.Bạn có biết bảng điều khiển chính của NRF chỉ thực hiện điều này trên Android 5+ thiết bị? Nếu nó hoạt động trên các thiết bị Android 4.x, nó phải có một cách khác – davidgyoung

+1

Tôi không thể tái tạo những kết quả này.Tôi đã thử nghiệm này trên một quét Nexus 9 cho một RadBeacon USB bằng cách sử dụng Android 5 BLE API. RadBeacon vào chế độ kết nối (xác minh điều này bằng cách sử dụng máy quét TI CC2540) và Android 'scanResult.getScanRecord(). getAdvertiseFlags()' trả về 6. Sau đó tôi đã thay đổi USB RadBeacon thành chế độ không kết nối (một lần nữa xác minh điều này với máy quét) và 'scanResult.getScanRecord(). getAdvertiseFlags()' vẫn trả về 6. Để chắc chắn điều này không chỉ là vấn đề bộ nhớ đệm, tôi bật/tắt bluetooth, sau đó cắm vào đèn hiệu, nó vẫn trả về 6. – davidgyoung

+0

Theo kinh nghiệm của tôi, có vẻ như có một số bất đồng liên quan đến cờ "có thể kết nối" và thông số kỹ thuật không hoàn toàn rõ ràng về nó (hoặc tôi chưa thể tìm được định nghĩa hoàn chỉnh). Tôi đã làm việc với các cảnh báo CSR, nếu bạn đặt cờ chế độ có thể phát hiện LE thành true, nó cũng hiển thị như có thể kết nối và với đèn hiệu Bluegiga, nơi cờ chế độ có thể phát hiện không có hiệu lực trên cờ kết nối. Nếu bạn thử ứng dụng Nordic, có thể bạn sẽ thấy rằng RadBeacon của bạn xuất hiện dưới dạng có thể kết nối. Và có, tôi tin rằng ứng dụng Bắc Âu hoạt động trên <5.0 vì vậy phải có một cách khác – user3934907

Các vấn đề liên quan