簡體   English   中英

藍牙:服務發現失敗

[英]Bluetooth : Service discovery failed

我嘗試在我的Android應用程序(運行4.1.2的三星手機:客戶端)和我的筆記本電腦(Win7,64位:服務器)之間建立藍牙連接。 服務發現失敗時始終失敗

我閱讀了關於這個( 這里那里 )的各種主題,但它沒有解決我的問題。

我有兩個問題:

  • 什么意思是眾所周知的UUID“00001101-0000-1000-8000-00805F9B34FB” 應該使用何時/何時使用?
  • 任何建議調查/解決我的問題將不勝感激。

備注:

  • 我試圖建立一個安全和不安全的連接(同時失敗)
  • 我可以通過設置>藍牙將我的筆記本電腦和設備配對
  • 正如評論中所建議的那樣:我嘗試使用隨機生成的UUID(但兩側都是相同的)而不是眾所周知的 UUID,但我仍然有完全相同的行為。

我有這些權限

<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

編輯

我沒有在客戶端編碼UUID,而是嘗試了以下方法(但仍然得到相同的錯誤):

UUID uuid = bluetoothDevice.getUuids()[bluetoothDevice.getUuids().length-1].getUuid();

echo-server的UUID始終是數組中的最后一個。

結束編輯

以下是客戶端上的相關日志:

08-22 12:30:28.627: ERROR/BluetoothService.cpp(12008): stopDiscoveryNative: D-Bus error in StopDiscovery: org.bluez.Error.Failed (Invalid discovery session)
08-22 12:30:28.647: INFO/BluetoothSocket.cpp(18030): Setting Master socket option
08-22 12:30:28.647: VERBOSE/BluetoothSocket.cpp(18030): ...fd 43 created (RFCOMM, lm = 7)
08-22 12:30:28.687: DEBUG/BluetoothPolicyService(12008): getAllowBluetoothDataTransfer - showMsg: true
08-22 12:30:28.687: DEBUG/BluetoothPolicyService(12008): MDM: isProfileEnabled = true
08-22 12:30:28.697: DEBUG/BluetoothUtils(18030): isSocketAllowedBySecurityPolicy start : device null
08-22 12:30:28.727: ERROR/BluetoothEventLoop.cpp(12008): onCreateDeviceResult: D-Bus error: org.bluez.Error.AlreadyExists (Already Exists)
08-22 12:30:28.727: VERBOSE/BluetoothService.cpp(12008): discoverServicesNative
08-22 12:30:28.727: VERBOSE/BluetoothService.cpp(12008): ... Object Path = /org/bluez/12635/hci0/dev_00_09_DD_50_88_54
08-22 12:30:28.727: VERBOSE/BluetoothService.cpp(12008): ... Pattern = , strlen = 0
08-22 12:30:29.138: VERBOSE/BluetoothEventLoop.cpp(12008): event_filter: Received signal org.bluez.Device:PropertyChanged from /org/bluez/12635/hci0/dev_00_09_DD_50_88_54
08-22 12:30:29.138: DEBUG/BluetoothEventLoop(12008): Device property changed
08-22 12:30:32.141: DEBUG/BluetoothA2DPStateReceiver(15827): BluetoothA2DPStateReceiver constructor call()
08-22 12:30:32.141: DEBUG/BluetoothA2DPStateReceiver(15827): onReceive(): action = android.bluetooth.device.action.ACL_CONNECTED
08-22 12:30:32.141: DEBUG/BluetoothA2DPStateReceiver(15827): ACTION_ACL_CONNECTED
08-22 12:30:32.141: DEBUG/BluetoothA2DPSinkInfo(15827): checkBlackListCarkit() : isBlackListCarkit false
08-22 12:30:32.161: DEBUG/BluetoothNotiBroadcastReceiver(15910): onReceive
08-22 12:30:40.749: ERROR/Bluetooth(18030): Cannot connect
    java.io.IOException: Service discovery failed
    at android.bluetooth.BluetoothSocket$SdpHelper.doSdp(BluetoothSocket.java:475)
    at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:241)
    at com.company.BlueToothTestActivity.open(BlueToothTestActivity.java:48)
    at com.company.BlueToothTestActivity$1.run(BlueToothTestActivity.java:29)
08-22 12:30:40.749: WARN/Bluetooth(18030): Unable to open connection !

這是重現錯誤的代碼(它的簡化版本,它編譯並重現錯誤 - 至少在我的硬件上 - )

客戶

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;

import java.io.IOException;
import java.util.UUID;

public class BlueToothTestActivity extends Activity {

private String macAddress = "00:09:DD:50:88:54";  //hardcoded laptop macAddress
private BluetoothAdapter mBluetoothAdapter;
private BluetoothDevice bluetoothDevice;
private BluetoothSocket socket;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);   
    Thread bluetoothClientThread = new Thread(){
        @Override
        public void run() {
            if(open()){
                Log.i("Bluetooth","Connection is open !");
            }else{
                Log.w("Bluetooth","Unable to open connection !");
            }
        }
    };
    bluetoothClientThread.start();
    initUI();
}

public boolean open() {
    mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    bluetoothDevice = mBluetoothAdapter.getRemoteDevice(macAddress);
    String BT_UUID = "00001101-0000-1000-8000-00805F9B34FB";
    try {
        mBluetoothAdapter.cancelDiscovery();
        //socket = bluetoothDevice.createInsecureRfcommSocketToServiceRecord(UUID.fromString(BT_UUID));
        socket = bluetoothDevice.createRfcommSocketToServiceRecord(UUID.fromString(BT_UUID));
        socket.connect(); //Block 12 sec here, then throw the exception.
        return true;
    } catch (IOException e) {
        try {
            socket.close();
        } catch (IOException closeException) { }
        Log.e("Bluetooth", "Cannot connect", e);
        return false;
    }
}

private void initUI(){
    LinearLayout linearLayout = new LinearLayout(this);
    Button finish = new Button(this);
    finish.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if(socket!=null){
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            BlueToothTestActivity.this.finish();
        }
    });
    finish.setText("Exit");
    linearLayout.addView(finish);
    setContentView(linearLayout);
}
}

服務器是一個簡單的echo服務器 (基於Bluecove庫,我從這里獲取代碼: http//www.miniware.net/mobile/articles/viewarticle.php?id = 22

服務器

import java.io.*;
import javax.bluetooth.*;
import javax.microedition.io.*;

// sample code from : http://www.miniware.net/mobile/articles/viewarticle.php?id=22   (Nikos Fotiou)
public class EchoServer {
    public final UUID uuid = new UUID("0000110100001000800000805F9B34FB",false);
    public final String name = "EchoServer";                       //the name of the service
    public final String url  =  "btspp://localhost:" + uuid + ";name=" + name  + ";authenticate=false;encrypt=false;";
    LocalDevice local = null;
    StreamConnectionNotifier server = null;
    StreamConnection conn = null;

    public EchoServer() {
    try {
        System.out.println("Setting device to be discoverable...");
        local = LocalDevice.getLocalDevice();
        local.setDiscoverable(DiscoveryAgent.GIAC);
        System.out.println("Start service:"+url);
        server = (StreamConnectionNotifier)Connector.open(url);
        System.out.println("Waiting for incoming connection...");
        conn = server.acceptAndOpen();  // stop and wait here
        System.out.println("Client Connected..."); //never reach this line
        DataInputStream din   = new DataInputStream(conn.openInputStream());
        while(true){
            String cmd = "";
            char c;
            while (((c = din.readChar()) > 0) && (c!='\n') ){
                cmd = cmd + c;
            }
            System.out.println("Received " + cmd);
        }
    } catch (Exception  e) {
        System.err.println("Exception Occured: " + e.toString());
        e.printStackTrace();
    }
}

public static void main (String args[]){
    EchoServer echoserver = new EchoServer();
}

}

服務器pom.xml

<dependencies>
    <dependency>
        <groupId>net.sf.bluecove</groupId>
        <artifactId>bluecove</artifactId>
        <version>2.1.1-SNAPSHOT</version>
    </dependency>
</dependencies>

<repositories>
    <repository>
        <id>pyx4me-web-snapshot</id>
        <url>http://www.pyx4me.com/maven2-snapshot</url>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
        <releases>
            <enabled>false</enabled>
        </releases>
    </repository>
</repositories>

您嘗試使用的UUID是串行端口配置文件UUID。 它可以在代碼中聲明

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

我嘗試使用Windows 8筆記本電腦和Nexus S編寫代碼。首先,我必須配對Nexus的設備。 然后我啟動了服務器並使用藍牙SPP應用程序來測試連接。 它完美無缺。 然后我開始你的代碼,它也工作,它也工作。

當服務器端未啟動時,我可以重現“ 服務發現失敗 ”異常。 此外,在使用createRfcommSocket方法掃描所有30個通道后,手機上的藍牙堆棧已損壞,我不得不重新啟動設備。

總之,要確保您能夠溝通:

  1. 在筆記本電腦上確保藍牙處於可發現狀態
  2. (可選)關閉UAC並使用管理員帳戶以確保您不會遇到任何安全漏洞(我沒有必要這樣做,但在第二次啟動時,必須打開防火牆以啟用調試以啟用調試)
  3. 重啟手機
  4. 從電話配對
  5. 使用SPP UUID,而不是自定義的
  6. 通過添加System.out.println(local.getBluetoothAddress());確保使用正確的mac地址System.out.println(local.getBluetoothAddress()); acceptAndOpen()調用之前的某個地方。
  7. 從Play商店測試與第三方應用程序的連接。 我在命令行模式下使用了這個 只需要測試連接。
  8. 更新MAC地址並運行應用程序
  9. 它應該工作。

這是我從運行中得到的輸出:

Start service:btspp://localhost:0000110100001000800000805f9b34fb;name=EchoServer;authenticate=false;encrypt=false;
MAC 402CF454215C
Waiting for incoming connection...
Client Connected...
Exception Occured: java.io.EOFException
BlueCove stack shutdown completed
java.io.EOFException
    at java.io.DataInputStream.readChar(Unknown Source)
    at examples.bluetooth_spp_server.EchoServer.<init>(EchoServer.java:30)
    at examples.bluetooth_spp_server.EchoServer.main(EchoServer.java:42)

為了完整起見,這是在各種條件下返回的錯誤

  • Windows藍牙已關閉: javax.bluetooth.BluetoothStateException: Bluetooth not detected
  • Android藍牙已關閉: java.io.IOException: Unable to start Service Discovery
  • Windows服務器未運行: java.io.IOException: Service discovery failed
  • 未配對: TimeoutException

理論上配對應該在啟動安全連接時自動發生,但實際上配對對話框可能不會出現在手機或Windows中的所有情況下。 如果發生故障,這是一個需要考慮的不確定因素。

a)UUID是串行端口UUID - 主要用於使用不講SDP協議的設備 - 例如小型嵌入式RFCOMM設備。

b)檢查手機上的藍牙是否已打開。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM