Android蓝牙客户端和服务器无法连接

时间:2014-02-18 21:45:14

标签: android bluetooth ubuntu-12.04 google-glass

我目前正在尝试创建一个将Google Glass(客户端)连接到我的计算机(python服务器)的应用程序。我想发送简单的字符串。我尝试了多种方法,但没有多少运气。我目前正在使用我发现的一些示例代码。运行两者后,我收到消息

  

“在onResume()中,写入期间发生异常:Socket Closed”

在Glass上,我的电脑(运行带蓝牙适配器的Ubuntu 12.04的HP Pavillion Dv6)完全冻结。有一次GUI本身崩溃,我正在控制台上的堆栈跟踪(可怕的黑屏)。

以下是客户端代码:

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

import com.myPackage.glassbluetooth.R;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;

public class ConnectTest extends Activity {
    TextView out;
    private static final int REQUEST_ENABLE_BT = 1;
    private BluetoothAdapter btAdapter = null;
    private BluetoothSocket btSocket = null;
    private OutputStream outStream = null;

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

    // Insert your server's MAC address
    private static String address = "00:1F:81:00:08:30";

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        out = (TextView) findViewById(R.id.out);

        out.append("\n...In onCreate()...");

        btAdapter = BluetoothAdapter.getDefaultAdapter();
        CheckBTState();
    }

    @Override
    public void onStart() {
        super.onStart();
        out.append("\n...In onStart()...");
    }

    @Override
    public void onResume() {
        super.onResume();

        out.append("\n...In onResume...\n...Attempting client connect...");

        // Set up a pointer to the remote node using it's address.
        BluetoothDevice device = btAdapter.getRemoteDevice(address);

        // Two things are needed to make a connection:
        //   A MAC address, which we got above.
        //   A Service ID or UUID.  In this case we are using the
        //     UUID for SPP.
        try {
            btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
        } catch (IOException e) {
            AlertBox("Fatal Error", "In onResume() and socket create failed: " + e.getMessage() + ".");
        }

        // Discovery is resource intensive.  Make sure it isn't going on
        // when you attempt to connect and pass your message.
        btAdapter.cancelDiscovery();

        // Establish the connection.  This will block until it connects.
        Log.d("CONNECTTEST", "Try to open socket");

        try {
            btSocket.connect();
            Log.d("CONNECTTEST", "btSocket.connect executed");
            out.append("\n...Connection established and data link opened...");
        } catch (IOException e) {
            try {
                btSocket.close();
            } catch (IOException e2) {
                AlertBox("Fatal Error", "In onResume() and unable to close socket during connection failure" + e2.getMessage() + ".");
            }
        }

        // Create a data stream so we can talk to server.
        out.append("\n...Sending message to server...");

        try {
            outStream = btSocket.getOutputStream();
        } catch (IOException e) {
            AlertBox("Fatal Error", "In onResume() and output stream creation failed:" + e.getMessage() + ".");
        }

        String message = "Hello from Android.\n";
        byte[] msgBuffer = message.getBytes();
        try {
            outStream.write(msgBuffer);
        } catch (IOException e) {
            String msg = "In onResume() and an exception occurred during write: " + e.getMessage();
            if (address.equals("00:00:00:00:00:00")) 
                msg = msg + ".\n\nUpdate your server address from 00:00:00:00:00:00 to the correct address on line 37 in the java code";
            msg = msg +  ".\n\nCheck that the SPP UUID: " + MY_UUID.toString() + " exists on server.\n\n";

            AlertBox("Fatal Error", msg);       
        }
    }

    @Override
    public void onPause() {
        super.onPause();

        out.append("\n...In onPause()...");

        if (outStream != null) {
            try {
                outStream.flush();
            } catch (IOException e) {
                AlertBox("Fatal Error", "In onPause() and failed to flush output stream: " + e.getMessage() + ".");
            }
        }

        try     {
            btSocket.close();
        } catch (IOException e2) {
            AlertBox("Fatal Error", "In onPause() and failed to close socket." + e2.getMessage() + ".");
        }
    }

    @Override
    public void onStop() {
        super.onStop();
        out.append("\n...In onStop()...");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        out.append("\n...In onDestroy()...");
    }

    private void CheckBTState() {
        // Check for Bluetooth support and then check to make sure it is turned on

        // Emulator doesn't support Bluetooth and will return null
        if(btAdapter==null) { 
            AlertBox("Fatal Error", "Bluetooth Not supported. Aborting.");
        } else {
            if (btAdapter.isEnabled()) {
                out.append("\n...Bluetooth is enabled...");
            } else {
                //Prompt user to turn on Bluetooth
                Intent enableBtIntent = new Intent(btAdapter.ACTION_REQUEST_ENABLE);
                startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
            }
        }
    }

    public void AlertBox( String title, String message ){
        new AlertDialog.Builder(this)
        .setTitle( title )
        .setMessage( message + " Press OK to exit." )
        .setPositiveButton("OK", new OnClickListener() {
            public void onClick(DialogInterface arg0, int arg1) {
                finish();
            }
        }).show();
    }
}

这是服务器代码:

from bluetooth import *

server_sock=BluetoothSocket( RFCOMM )
server_sock.bind(("",PORT_ANY))
server_sock.listen(1)

port = server_sock.getsockname()[1]

uuid = "1aefbf9b-ea60-47de-b5a0-ed0e3a36d9a5"
testUuid = "00001101-0000-1000-8000-00805F9B34FB"

advertise_service( server_sock, "GlassServer",
                   service_id = testUuid,
                   service_classes = [ uuid, SERIAL_PORT_CLASS ],
                   profiles = [ SERIAL_PORT_PROFILE ], 
#                   protocols = [ OBEX_UUID ] 
                    )

print("Waiting for connection on RFCOMM channel %d" % port)

client_sock, client_info = server_sock.accept()
print("Accepted connection from ", client_info)

try:
    while True:
        data = client_sock.recv(1024)
        if len(data) == 0: break
        print("received [%s]" % data)
except IOError:
    pass

print("disconnected")

client_sock.close()
server_sock.close()
print("all done")

这是hcitool的输出:

$ hcitool scan
Scanning ...
    F4:B7:E2:F9:74:63   GLASS-YUKON
$ hcitool dev
Devices:
    hci0    00:1F:81:00:08:30

有没有人知道最新情况?此外,如果您知道可能有效的任何相关示例程序,我将有兴趣尝试它们!提前谢谢!

凹凸,任何人都可以帮忙吗?

在尝试使用内置蓝牙功能的计算机后,我能够更深入地研究这个问题。代码尝试创建RFComm套接字时会出现此问题。使用我现在的代码,我得到一个异常服务发现失败。在使用此处的建议后,我摆脱了这个错误:Service discovery failed exception using Bluetooth on Android

但现在我得到一个例外情况,说“主机已经关闭”。我发现没有任何修复工作。有什么想法吗?

1 个答案:

答案 0 :(得分:0)

我可以回答我问题的一部分:

内核恐慌不是因为我的代码而是因为我的蓝牙适配器的驱动程序软件错误。我在一台本机具有蓝牙功能的计算机上尝试了这些代码,并且我得到的结果与内核恐慌相同。