初始化 Android(服务器)和 PC 上的 bluecove(客户端)之间的蓝牙连接

发布于 2024-12-05 05:10:39 字数 6951 浏览 0 评论 0原文

我知道还有其他相关主题,但就我而言,我希望 Android 设备将蓝牙连接初始化为服务器。我按照文档,以这种方式编写了服务器:

private class AcceptThread implements Runnable {
    private final BluetoothServerSocket mmServerSocket;

    public AcceptThread() {

        BluetoothServerSocket tmp = null;
        try {
            tmp = mBluetooth.listenUsingRfcommWithServiceRecord(
                    "myService", mUuid);
        } catch (IOException e) { }
        mmServerSocket = tmp;
    }

    public void run() {
        BluetoothSocket socket = null;
        // Keep listening until exception occurs or a socket is returned
        while (true) {
            try {
                System.out.println("SERVER SOCKET LISTENING");
                socket = mmServerSocket.accept();
            } catch (IOException e) {
                break;
            }
            // If a connection was accepted
            if (socket != null) {
                System.out.println("SIGNAL RECEIVED");
                // Do work to manage the connection (in a separate thread)
                Toast.makeText(getApplicationContext(), "SIGNAL RECEIVED", Toast.LENGTH_LONG).show();
                try {
                    mmServerSocket.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                break;
            }
        }
    }

    /** Will cancel the listening socket, and cause the thread to finish */
    public void cancel() {
        try {
            mmServerSocket.close();
        } catch (IOException e) { }
    }
}

另一方面,我有 bluecove API 来发现远程设备和服务。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Vector;

import javax.bluetooth.DeviceClass;
import javax.bluetooth.DiscoveryAgent;
import javax.bluetooth.DiscoveryListener;
import javax.bluetooth.LocalDevice;
import javax.bluetooth.RemoteDevice;
import javax.bluetooth.ServiceRecord;
import javax.bluetooth.UUID;
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;

/**
* A simple SPP client that connects with an SPP server
*/
public class SampleSPPClient implements DiscoveryListener{

    //object used for waiting
    private static Object lock=new Object();

    //vector containing the devices discovered
    private static Vector vecDevices=new Vector();

    private static String connectionURL=null;

    public static void main(String[] args) throws IOException {

        SampleSPPClient client=new SampleSPPClient();

        //display local device address and name
        LocalDevice localDevice = LocalDevice.getLocalDevice();
        System.out.println("Address: "+localDevice.getBluetoothAddress());
        System.out.println("Name: "+localDevice.getFriendlyName());

        //find devices
        DiscoveryAgent agent = localDevice.getDiscoveryAgent();

        System.out.println("Starting device inquiry...");
        agent.startInquiry(DiscoveryAgent.GIAC, client);

        try {
            synchronized(lock){
                lock.wait();
            }
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }


        System.out.println("Device Inquiry Completed. ");

        //print all devices in vecDevices
        int deviceCount=vecDevices.size();

        if(deviceCount <= 0){
            System.out.println("No Devices Found .");
            System.exit(0);
        }
        else{
            //print bluetooth device addresses and names in the format [ No. address (name) ]
            System.out.println("Bluetooth Devices: ");
            for (int i = 0; i <deviceCount; i++) {
                RemoteDevice remoteDevice=(RemoteDevice)vecDevices.elementAt(i);
                System.out.println((i+1)+". "+remoteDevice.getBluetoothAddress()+" ("+remoteDevice.getFriendlyName(true)+")");
            }
        }

        System.out.print("Choose Device index: ");
        BufferedReader bReader=new BufferedReader(new InputStreamReader(System.in));

        String chosenIndex=bReader.readLine();
        int index=Integer.parseInt(chosenIndex.trim());

        //check for spp service
        RemoteDevice remoteDevice=(RemoteDevice)vecDevices.elementAt(index-1);
        UUID[] uuidSet = new UUID[1];
        uuidSet[0]=new UUID("4e3aea40e2a511e095720800200c9a66", false);

        System.out.println("\nSearching for service...");
        agent.searchServices(null,uuidSet,remoteDevice,client);

        try {
            synchronized(lock){
                lock.wait();
            }
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }

        if(connectionURL==null){
            System.out.println("Device does not support Simple SPP Service.");
            System.exit(0);
        }

        //connect to the server and send a line of text
        StreamConnection streamConnection=(StreamConnection)Connector.open(connectionURL);

        //send string
        OutputStream outStream=streamConnection.openOutputStream();
        PrintWriter pWriter=new PrintWriter(new OutputStreamWriter(outStream));
        pWriter.write("Test String from SPP Client\r\n");
        pWriter.flush();


        //read response
        InputStream inStream=streamConnection.openInputStream();
        BufferedReader bReader2=new BufferedReader(new InputStreamReader(inStream));
        String lineRead=bReader2.readLine();
        System.out.println(lineRead);


    }//main

    //methods of DiscoveryListener
    public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {
        //add the device to the vector
        if(!vecDevices.contains(btDevice)){
            vecDevices.addElement(btDevice);
        }
    }

    //implement this method since services are not being discovered
    public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {
        System.out.println(servRecord[0].getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false));
        if(servRecord!=null && servRecord.length>0){
            connectionURL=servRecord[0].getConnectionURL(ServiceRecord.AUTHENTICATE_ENCRYPT,false);
        }
        synchronized(lock){
            lock.notify();
        }
    }

    //implement this method since services are not being discovered
    public void serviceSearchCompleted(int transID, int respCode) {
        synchronized(lock){
            lock.notify();
        }
    }


    public void inquiryCompleted(int discType) {
        synchronized(lock){
            lock.notify();
        }

    }//end method



}

客户端找到了设备和服务,但从 ServiceRecord 检索 url 来建立连接时失败。它检索一个通道错误的 Url,并抛出异常: javax.bluetooth.BluetoothConnectionException: Failed to connect;

我该如何解决这个问题?

I know there are other topics about that but in my case I want the Android device to initialize the bluetooth connection as a server. I followed the Documentation and I wrote the server in this way:

private class AcceptThread implements Runnable {
    private final BluetoothServerSocket mmServerSocket;

    public AcceptThread() {

        BluetoothServerSocket tmp = null;
        try {
            tmp = mBluetooth.listenUsingRfcommWithServiceRecord(
                    "myService", mUuid);
        } catch (IOException e) { }
        mmServerSocket = tmp;
    }

    public void run() {
        BluetoothSocket socket = null;
        // Keep listening until exception occurs or a socket is returned
        while (true) {
            try {
                System.out.println("SERVER SOCKET LISTENING");
                socket = mmServerSocket.accept();
            } catch (IOException e) {
                break;
            }
            // If a connection was accepted
            if (socket != null) {
                System.out.println("SIGNAL RECEIVED");
                // Do work to manage the connection (in a separate thread)
                Toast.makeText(getApplicationContext(), "SIGNAL RECEIVED", Toast.LENGTH_LONG).show();
                try {
                    mmServerSocket.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                break;
            }
        }
    }

    /** Will cancel the listening socket, and cause the thread to finish */
    public void cancel() {
        try {
            mmServerSocket.close();
        } catch (IOException e) { }
    }
}

On the other side I have bluecove API that discover remote devices and services.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Vector;

import javax.bluetooth.DeviceClass;
import javax.bluetooth.DiscoveryAgent;
import javax.bluetooth.DiscoveryListener;
import javax.bluetooth.LocalDevice;
import javax.bluetooth.RemoteDevice;
import javax.bluetooth.ServiceRecord;
import javax.bluetooth.UUID;
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;

/**
* A simple SPP client that connects with an SPP server
*/
public class SampleSPPClient implements DiscoveryListener{

    //object used for waiting
    private static Object lock=new Object();

    //vector containing the devices discovered
    private static Vector vecDevices=new Vector();

    private static String connectionURL=null;

    public static void main(String[] args) throws IOException {

        SampleSPPClient client=new SampleSPPClient();

        //display local device address and name
        LocalDevice localDevice = LocalDevice.getLocalDevice();
        System.out.println("Address: "+localDevice.getBluetoothAddress());
        System.out.println("Name: "+localDevice.getFriendlyName());

        //find devices
        DiscoveryAgent agent = localDevice.getDiscoveryAgent();

        System.out.println("Starting device inquiry...");
        agent.startInquiry(DiscoveryAgent.GIAC, client);

        try {
            synchronized(lock){
                lock.wait();
            }
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }


        System.out.println("Device Inquiry Completed. ");

        //print all devices in vecDevices
        int deviceCount=vecDevices.size();

        if(deviceCount <= 0){
            System.out.println("No Devices Found .");
            System.exit(0);
        }
        else{
            //print bluetooth device addresses and names in the format [ No. address (name) ]
            System.out.println("Bluetooth Devices: ");
            for (int i = 0; i <deviceCount; i++) {
                RemoteDevice remoteDevice=(RemoteDevice)vecDevices.elementAt(i);
                System.out.println((i+1)+". "+remoteDevice.getBluetoothAddress()+" ("+remoteDevice.getFriendlyName(true)+")");
            }
        }

        System.out.print("Choose Device index: ");
        BufferedReader bReader=new BufferedReader(new InputStreamReader(System.in));

        String chosenIndex=bReader.readLine();
        int index=Integer.parseInt(chosenIndex.trim());

        //check for spp service
        RemoteDevice remoteDevice=(RemoteDevice)vecDevices.elementAt(index-1);
        UUID[] uuidSet = new UUID[1];
        uuidSet[0]=new UUID("4e3aea40e2a511e095720800200c9a66", false);

        System.out.println("\nSearching for service...");
        agent.searchServices(null,uuidSet,remoteDevice,client);

        try {
            synchronized(lock){
                lock.wait();
            }
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }

        if(connectionURL==null){
            System.out.println("Device does not support Simple SPP Service.");
            System.exit(0);
        }

        //connect to the server and send a line of text
        StreamConnection streamConnection=(StreamConnection)Connector.open(connectionURL);

        //send string
        OutputStream outStream=streamConnection.openOutputStream();
        PrintWriter pWriter=new PrintWriter(new OutputStreamWriter(outStream));
        pWriter.write("Test String from SPP Client\r\n");
        pWriter.flush();


        //read response
        InputStream inStream=streamConnection.openInputStream();
        BufferedReader bReader2=new BufferedReader(new InputStreamReader(inStream));
        String lineRead=bReader2.readLine();
        System.out.println(lineRead);


    }//main

    //methods of DiscoveryListener
    public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {
        //add the device to the vector
        if(!vecDevices.contains(btDevice)){
            vecDevices.addElement(btDevice);
        }
    }

    //implement this method since services are not being discovered
    public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {
        System.out.println(servRecord[0].getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false));
        if(servRecord!=null && servRecord.length>0){
            connectionURL=servRecord[0].getConnectionURL(ServiceRecord.AUTHENTICATE_ENCRYPT,false);
        }
        synchronized(lock){
            lock.notify();
        }
    }

    //implement this method since services are not being discovered
    public void serviceSearchCompleted(int transID, int respCode) {
        synchronized(lock){
            lock.notify();
        }
    }


    public void inquiryCompleted(int discType) {
        synchronized(lock){
            lock.notify();
        }

    }//end method



}

The client found the device and the service but when retrieve the url from the ServiceRecord to establish the connection it fails. It retrieve an Url in which the channel is wrong and it throws an exception: javax.bluetooth.BluetoothConnectionException: Failed to connect;

How can I solve the problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

-残月青衣踏尘吟 2024-12-12 05:10:39

我在使用时设法找到了一些电话ServiceRecords:

    UUID[] uuidSet = new UUID[1];
    uuidSet[0]=new UUID(0x0100);
    int[] attrIds = { 0x0100 };

    System.out.println("\nSearching for service...");
    agent.searchServices(attrIds, uuidSet, remoteDevice, client);

并且在serviceSearch之后您将调用lock.notify()两次,在servicesDiscovered函数中将其删除。

您还应该浏览服务记录并查找您感兴趣的服务记录。URL 将显示 btgoep:// 或 btspp://

当通过 for 循环搜索时,使用此代码列出服务名称

 for(int i = 0; i < servRecord.length; i++)
 {
    String url = servRecord[i].getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);
    DataElement serviceName = srs[i].getAttributeValue(0x0100);
    if (serviceName != null) {
       System.out.println("service " + serviceName.getValue() + " found " + url);
    } else {
       System.out.println("service found " + url);
    }

我遇到了确切的问题,似乎 android api 没有向 SDP 注册 ServiceRecord,因此 Bluecove api 可以找到它。
无论我使用什么 UUID,它都只会找到我的手机默认注册的 UUID,即音频网关和电话簿 OBEX 推送等。

编辑 - -
我遇到了同样的问题,但意识到我实际上还没有调用listenUsingInsecureRFCOMMSocket。然后就没有注册服务记录。
但在那之后它工作得很好。

I managed to find some phone ServiceRecords when using:

    UUID[] uuidSet = new UUID[1];
    uuidSet[0]=new UUID(0x0100);
    int[] attrIds = { 0x0100 };

    System.out.println("\nSearching for service...");
    agent.searchServices(attrIds, uuidSet, remoteDevice, client);

And you will be calling lock.notify() twice after a serviceSearch, remove it in the servicesDiscovered function.

You should also go through the service records and look for the one you are interested in. The URL will state btgoep:// or btspp://

When searching through the for loop use this code to list the service name

 for(int i = 0; i < servRecord.length; i++)
 {
    String url = servRecord[i].getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);
    DataElement serviceName = srs[i].getAttributeValue(0x0100);
    if (serviceName != null) {
       System.out.println("service " + serviceName.getValue() + " found " + url);
    } else {
       System.out.println("service found " + url);
    }

I have the exact problem, it seems like the android api doesn't register the ServiceRecord with the SDP so the Bluecove api can find it.
No matter what UUID I use it will only find the ones my phone register as default, i e Audio gateways and Phonebook OBEX push and such.

EDIT ---
I had the same problem, but realized I had not actually called listenUsingInsecureRFCOMMSocket yet. And then it did not register the service record.
But after that it worked just fine.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文