如果不重新启动蓝牙无线电,则无法重新连接到蓝牙服务器

时间:2018-02-22 18:57:49

标签: java android bluecove

我有一个Android客户端设备,它将尝试连接到支持蓝牙的服务器并向其传输数据。到目前为止,除了一个故障之外它一直很好用:每当我想在连接终止后重新连接到服务器时,服务器都不会检测到客户端发送了连接请求。如果我关闭并打开蓝牙无线电,然后尝试重新连接,一切正常。我做错了什么?

这是主要的课程

package org.team2180.scoutingServer;
import java.io.IOException;

import javax.bluetooth.*;
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;
import javax.microedition.io.StreamConnectionNotifier;

import org.json.JSONObject;

import javax.bluetooth.UUID;
public class Server {

    public static final UUID serviceUUID = new UUID("94f39d297d6d437d973bfba39e49d4ee", false);
    public static String connectionString = "btspp://localhost:" + serviceUUID.toString() +";name=ProblemServer";
    static LocalDevice locDev;
    public static final JSONObject DATA = new JSONObject();
    public static void main(String[] args) {
        try {

            locDev = LocalDevice.getLocalDevice();
            System.out.println("Local Device: '" + locDev.getFriendlyName()+"' @ "+locDev.getBluetoothAddress());
            StreamConnectionNotifier streamConnNot = startServer();
            startListening(streamConnNot);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static StreamConnectionNotifier startServer() throws Exception {
        if(serverStarted){return null;}
        boolean isNowDiscoverable = locDev.setDiscoverable(DiscoveryAgent.GIAC);
        System.out.println("Local Device Discoverable: "+Boolean.toString(isNowDiscoverable));
        System.out.println("Local Device URI: "+connectionString);

        StreamConnectionNotifier streamConnNot = (StreamConnectionNotifier) Connector.open(connectionString);
        System.out.println("Server: Created, waiting for clients . . . ");
        return streamConnNot;
    }

    public static void startListening(StreamConnectionNotifier streamConnNot) throws IOException {
        while(true) {
            StreamConnection connection = streamConnNot.acceptAndOpen();
            Thread connectedThread = new Thread(new ConnectionHandler(connection, TEAM_DATA));
            System.out.println("Sever: found a client, placed on thread:" + connectedThread.getId());
            connectedThread.start();
        }
    }
}

我使用自己的线程处理每个连接,基于此类,交换初始字节以确定如何处理连接(将数据发送到设备的数据库,从设备的数据库中获取数据)

package org.team2180.scoutingServer;

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.Iterator;

import javax.microedition.io.StreamConnection;
import javax.bluetooth.RemoteDevice;
import org.json.*;

public class ConnectionHandler implements Runnable {
    final StreamConnection connection;
    final JSONObject TEAM_DATA;
    RemoteDevice remDev;
    String deviceIndex;
    public ConnectionHandler(StreamConnection connection,JSONObject TEAM_DATA) {
        this.connection = connection;
        this.TEAM_DATA = TEAM_DATA;
        try {
            this.remDev = RemoteDevice.getRemoteDevice(connection);
            this.deviceIndex = remDev.getFriendlyName(true)+'@'+remDev.getBluetoothAddress();
        } catch (IOException e) {
            this.remDev = null;
            this.deviceIndex = null;
        }
    }

    @Override
    public void run() {
        try {
            OutputStream out = connection.openOutputStream();
            InputStream in = connection.openInputStream();
            PrintWriter pWriter = new PrintWriter(new OutputStreamWriter(out));
            BufferedReader bReader = new BufferedReader(new InputStreamReader(in)); 

            int handshake = in.read();
            if(handshake==1) {
                System.out.println(deviceIndex+" will now inform you of TOP SECRET_INFO");
                updateDatabase(remDev, pWriter, bReader);
                System.out.println(deviceIndex+" >\n"+ TEAM_DATA.getJSONObject(deviceIndex).getInt("entryCount"));
      }
        } catch (Exception e) {
            System.out.println(deviceIndex+"'s thread is terminating BADLY!");
            try {connection.close();} catch (IOException e1) {e1.printStackTrace();}
            return;
        }
        System.out.println(deviceIndex+"'s thread is terminating!");
        return;
    }

    public void updateDatabase(RemoteDevice remDev, PrintWriter ex, BufferedReader in) throws IOException, JSONException {
        //OK!
        ex.write(1);
        ex.flush();
        char[] charData = new char[8192];

        in.read(charData);
        String data = new String(charData);

        connection.close();
    //Continue doing other things with data
    .
    .
    .

这是连接到服务器的Android客户端代码。它不是一个线程,并且阻止,但是,这是故意的,以便用户在离开连接半径之前等待

sendButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String text = gatherData();
                try{
                    bS = getSockToServer();
                    bS.connect();
                    OutputStream bsO = bS.getOutputStream();
                    InputStream bsI = bS.getInputStream();
                    bsO.write(1);//Code upload
                    bsO.flush();

                    Log.d("sendButton.onClick","sent condition code 1");

                    int handRespond = (int)bsI.read();

                    Log.d("recieved",handRespond+"");

                    if(handRespond == 1){
                        bsO.write(text.getBytes("UTF-8"));
                        bsO.flush();
                    }

                }catch(Exception e){
                    Log.e("sendButton.onClick",e.toString());
                    try{
                        bS.close();
                    }catch(IOException ioE){
                        Log.e("sendButton.onClick{SNC}",e.toString());
                    }
                }
            }
        });

我的最终目标是同时处理多个设备(因此使用线程),而不是每次设备需要重新连接时都必须重置无线电。

我的代码非常粗糙;我只使用了bluecove(和蓝牙一般)两个星期。任何建议/技巧都表示赞赏!

1 个答案:

答案 0 :(得分:0)

我无法重温我之前没有看到过。

我需要关闭套接字客户端。

糟糕。