2010-08-03 24 views
47

Tôi hiện đang làm việc trên ứng dụng Android kết nối với một công cụ qua Bluetooth và cần phải viết lệnh chuỗi và nhận phản hồi chuỗi. Hiện tại tôi có kết nối/đọc/ghi làm việc cho TCP/IP qua Wi-Fi và hiện đang cố gắng triển khai Bluetooth. Nhưng tôi đang chạy vào một số rào chắn. Tôi đã tìm kiếm trên web để tìm các ví dụ về điều tương tự và không có bất kỳ may mắn nào. Tôi đã sử dụng ví dụ về tài nguyên dành cho nhà phát triển Android: Trò chuyện qua Bluetooth làm điểm tham chiếu chính của tôi.Lỗi phát hiện dịch vụ không thành công khi sử dụng Bluetooth trên Android

Mã hiện tại của tôi có vẻ hoạt động .. Sau đó, nó sẽ phát hiện ra dịch vụ Khám phá không thành công ở điểm kết nối. Tôi đang sử dụng lớp DeviceListActivity để khám phá và chọn thiết bị tôi muốn kết nối. Nó trả về anActivityResult và sau đó lớp Bluetooth của tôi đợi nó xử lý và sau đó kết nối với nó. Mã bên dưới gần giống với Ứng dụng trò chuyện Bluetooth.

public void onActivityResult(int requestCode, int resultCode, Intent data) { 
    if(!m_BluetoothAdapter.isEnabled()) 
    { 
     m_BluetoothAdapter.enable(); 
    } 
    switch (requestCode) { 
     case REQUEST_CONNECT_DEVICE: 
      // When DeviceListActivity returns with a device to connect 
      if (resultCode == Activity.RESULT_OK) { 
       // Get the device MAC address 
       String address = data.getExtras() 
            .getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS); 
       // Get the BLuetoothDevice object 
       BluetoothDevice device = m_BluetoothAdapter.getRemoteDevice(address); 
       // Attempt to connect to the device 
       connect(device); 
      } 
      break; 

     case REQUEST_ENABLE_BT: 
      // When the request to enable Bluetooth returns 
      if (resultCode == Activity.RESULT_OK) { 
       // Bluetooth is now enabled, so set up a chat session 
      } 
      else { 
       // User did not enable Bluetooth or an error occured 

       Toast.makeText(this, "Bluetooth not enabled", Toast.LENGTH_SHORT).show(); 
       finish(); 
      } 
    } 
} 

Đây là chức năng kết nối của tôi:

private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); 

private void connect(BluetoothDevice device) { 
    m_Device = device; 
    BluetoothSocket tmp = null; 

    // Get a BluetoothSocket for a connection with the 
    // given BluetoothDevice 
    try { 
     tmp = device.createRfcommSocketToServiceRecord(MY_UUID); 
    } 
    catch (IOException e) { 

    } 
    m_Socket = tmp; 

    m_BluetoothAdapter.cancelDiscovery(); 

    try { 
     // This is a blocking call and will only return on a 
     // successful connection or an exception 
     m_Socket.connect(); 
    } 
    catch (IOException e) { 
     try { 
      m_Socket.close(); 
     } 
     catch (IOException e2) { 
     } 
     return; 
    } 
} 

Hy vọng rằng, bất cứ điều gì tôi đang làm sai rất đơn giản, nhưng tôi sợ nó không bao giờ là dễ dàng. Đây là lần đầu tiên tôi thực hiện bất kỳ sự phát triển Bluetooth nào, và có lẽ tôi đang làm điều gì đó một cách mù quáng ... Nhưng tôi không chắc tại sao tôi lại phát hiện ra dịch vụ không thành công.

Bạn có thể ghép/tìm thiết bị mọi lúc thủ công trên điện thoại ... Nó yêu cầu mật mã, nhưng tôi không nghĩ đó là vấn đề tôi đang gặp phải.

Trả lời

92

Sau ba ngày, tôi nhận thấy rằng nhờ một số bài đăng rất hữu ích.

tôi đã phải thay thế:

tmp = device.createRfcommSocketToServiceRecord(MY_UUID); 

với:

Method m = device.getClass().getMethod("createRfcommSocket", new Class[] {int.class}); 
     tmp = (BluetoothSocket) m.invoke(device, 1); 

và Voila nó hoạt động!

+1

Chờ, tôi có một vài ứng dụng Bluetooth và tôi đã không tìm thấy một tình huống mà việc sử dụng sự phản chiếu (getclass.getmethod) là cần thiết. Bạn có thể cho tôi biết thêm một chút về phần cứng bạn đã thử không? Tôi rất muốn biết liệu sự phản chiếu có thực sự cần thiết trong những tình huống nhất định không. –

+0

Sau một số thử nghiệm. Tôi thấy rằng nó thực sự là điện thoại có vấn đề với nó. HTC Incredible không kết nối bằng cách sử dụng phương pháp đầu tiên, tuy nhiên Samsung Galaxy S và một chiếc khác, không thể nhớ cái nào, đã kết nối vào lần thử đầu tiên. – TxAg

+0

Tôi đã bị cản trở với ngoại lệ này và giải pháp này dường như đã khắc phục được sự cố của tôi. Bạn có hiểu những gì đang xảy ra ở đây và tại sao nó làm giảm bớt vấn đề của dịch vụ Discovery không? – GobiasKoffi

2

Đây là a suggested edit from an anonymous user cố gắng trả lời câu trả lời được chấp nhận.

Một khác biệt lớn giữa mã trước và sau là UUID bạn đang chuyển. Tôi tìm thấy câu trả lời của tôi ở đây: http://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#createRfcommSocketToServiceRecord(java.util.UUID)

tôi đã phải thay thế:

tmp = device.createRfcommSocketToServiceRecord(MY_UUID); 

với:

private static final UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); 
tmp = device.createRfcommSocketToServiceRecord(SPP_UUID); 

và thì đấy nó hoạt động! Mã gốc là dành cho ứng dụng Android ngang hàng. Nó không có ý nghĩa để sử dụng UUID ứng dụng khi kết nối với một thiết bị bluetooth nối tiếp đơn giản. Đó là lý do tại sao khám phá thất bại.

+0

Và bây giờ [một nhận xét người dùng ẩn danh] (http://stackoverflow.com/suggested-edits/335727): Bản chỉnh sửa được đề xuất đang sử dụng cùng một phương thức giống như mã không hoạt động. Mã làm việc sử dụng một phương thức không công khai khác không yêu cầu uuid. – Rup

+0

Có lỗi giống như trên khi cố viết ứng dụng android kết nối với máy quét Bluetooth. Giải pháp này làm việc cho tôi. – zarazan

+0

Điều này là vô nghĩa. – Monsignor

13

Tính đến API 15 bạn có thể sử dụng các phương pháp sau đây:

Hãy thử thay thế UUID của bạn với giá trị trả về của getUuids() phương pháp BluetoothDevice lớp. gì làm việc đối với tôi là một cái gì đó như thế này:

UUID uuid = bluetoothDevice.getUuids()[0].getUuid(); 
BluetoothSocket socket = bluetoothDevice.createRfcommSocketToServiceRecord(uuid); 

Lý do làm việc này là thiết bị khác nhau hỗ trợ UUIDs khác nhau và bằng cách nhận các UUIDs của thiết bị sử dụng getUuids bạn đang hỗ trợ tất cả các tính năng và thiết bị.

Một phương pháp mới thú vị khác (được hỗ trợ từ API 14) là: BluetoothHealth.getConnectionState. Chưa thử nhưng có vẻ đầy hứa hẹn ...

1

Vì vậy, như đã đề cập ở trên, điểm là bạn cần sử dụng UUID mà máy chủ đang chờ.

Nếu bạn đang kết nối với thiết bị bluetooth, chẳng hạn như tai nghe hoặc chuột, bạn cần kiểm tra thiết bị đang nghe thiết bị UUID nào. Bạn có thể thấy UUID như thế này.

UUID[] uuids = bluetoothDevice.getUuids(); 

Và nếu bạn muốn biết những UUID này có ý nghĩa gì, hãy xem this.

0

Đây là một câu hỏi thực sự cũ nhưng tôi thấy rằng việc sử dụng createInsecureRfcommSocketToServiceRecord() thay vì createRfcommSocketToServiceRecord() cùng với getUuids() đề cập trước đây làm các trick cho tôi

UUID uuid = bluetoothDevice.getUuids()[0].getUuid(); 
BluetoothSocket socket = bluetoothDevice.createInsecureRfcommSocketToServiceRecord(uuid); 
Các vấn đề liên quan