我实施了以下BluetoothService
,它来自官方
Android BluetoothChatService
示例:
public class BluetoothService extends Thread {
private static final String TAG = BluetoothService.class.getSimpleName();
private static final String NAME_SECURE = TAG + "Secure";
private static final String NAME_INSECURE = TAG + "Insecure";
private static final UUID MY_UUID_SECURE = UUID.fromString("a6fb84f6-20b3-477f-9160-bcd028bddc99");
private static final UUID MY_UUID_INSECURE = UUID.fromString("7dd8441a-1d4b-42f1-9996-a7d507548dfc");
public static final int STATE_NONE = 0;
public static final int STATE_LISTEN = 1;
public static final int STATE_CONNECTING = 2;
public static final int STATE_CONNECTED = 3;
private BluetoothAdapter bluetoothAdapter = null;
private Handler handler = null;
private AcceptThread secureAcceptThread = null;
private AcceptThread insecureAcceptThread = null;
private ConnectThread connectThread = null;
private ConnectedThread connectedThread = null;
private int bluetoothState = STATE_NONE;
public BluetoothService(Handler handler) {
this.bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
this.bluetoothState = STATE_NONE;
this.handler = handler;
}
public synchronized void startConnection() {
Log.d(TAG, "start");
if (this.connectThread != null) {
this.connectThread.cancel();
this.connectThread = null;
}
if (this.connectedThread != null) {
this.connectedThread.cancel();
this.connectedThread = null;
}
this.setBluetoothState(STATE_LISTEN);
if (this.secureAcceptThread == null) {
this.secureAcceptThread = new AcceptThread(true);
this.secureAcceptThread.start();
}
if (this.insecureAcceptThread == null) {
this.insecureAcceptThread = new AcceptThread(false);
this.insecureAcceptThread.start();
}
}
public synchronized void connect(BluetoothDevice device, boolean secure) {
if (this.bluetoothState == STATE_CONNECTING) {
if (this.connectThread != null) {
this.connectThread.cancel();
this.connectThread = null;
}
}
if (this.connectedThread != null) {
this.connectedThread.cancel();
this.connectedThread = null;
}
this.connectThread = new ConnectThread(device, secure);
this.connectThread.start();
this.setBluetoothState(STATE_CONNECTING);
}
public synchronized void connected(BluetoothSocket socket, BluetoothDevice device, final String socketType) {
if (this.connectThread != null) {
this.connectThread.cancel();
this.connectThread = null;
}
if (this.connectedThread != null) {
this.connectedThread.cancel();
this.connectedThread = null;
}
if (this.secureAcceptThread != null) {
this.secureAcceptThread.cancel();
this.secureAcceptThread = null;
}
if (this.insecureAcceptThread != null) {
this.insecureAcceptThread.cancel();
this.insecureAcceptThread = null;
}
this.connectedThread = new ConnectedThread(socket, socketType);
this.connectedThread.start();
Message msg = this.handler.obtainMessage(Globals.MESSAGE_DEVICE_NAME);
Bundle bundle = new Bundle();
bundle.putString(Globals.DEVICE_NAME, device.getName());
msg.setData(bundle);
this.handler.sendMessage(msg);
this.setBluetoothState(STATE_CONNECTED);
}
public synchronized void stopConnection() {
if (this.connectThread != null) {
this.connectThread.cancel();
this.connectThread = null;
}
if (this.connectedThread != null) {
this.connectedThread.cancel();
this.connectedThread = null;
}
if (this.secureAcceptThread != null) {
this.secureAcceptThread.cancel();
this.secureAcceptThread = null;
}
if (this.insecureAcceptThread != null) {
this.insecureAcceptThread.cancel();
this.insecureAcceptThread = null;
}
this.setBluetoothState(STATE_NONE);
}
public void write(byte[] out) {
ConnectedThread connectedThread = null;
synchronized (this) {
if (this.bluetoothState != STATE_CONNECTED) {
return;
}
connectedThread = this.connectedThread;
}
connectedThread.write(out);
}
private void connectionFailed() {
Message msg = this.handler.obtainMessage(Globals.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(Globals.TOAST, "Unable to connect device");
msg.setData(bundle);
this.handler.sendMessage(msg);
BluetoothService.this.start();
}
private void connectionLost() {
Message msg = this.handler.obtainMessage(Globals.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(Globals.TOAST, "Device connection was lost");
msg.setData(bundle);
this.handler.sendMessage(msg);
BluetoothService.this.start();
}
public synchronized int getBluetoothState() {
return this.bluetoothState;
}
private synchronized void setBluetoothState(int bluetoothState) {
this.bluetoothState = bluetoothState;
}
private class AcceptThread extends Thread {
private BluetoothServerSocket serverSocket = null;
private String socketType = null;
public AcceptThread(boolean secure) {
BluetoothServerSocket tempServerSocket = null;
this.socketType = secure ? "Secure" : "Insecure";
try {
if (secure) {
tempServerSocket = bluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME_SECURE, MY_UUID_SECURE);
} else {
tempServerSocket = bluetoothAdapter.listenUsingInsecureRfcommWithServiceRecord(NAME_INSECURE, MY_UUID_INSECURE);
}
} catch (IOException e) {
Log.e(TAG, "Socket Type: " + socketType + "listen() failed", e);
}
this.serverSocket = tempServerSocket;
}
public void run() {
this.setName("AcceptThread" + socketType);
BluetoothSocket socket = null;
while (bluetoothState != STATE_CONNECTED) {
try {
socket = this.serverSocket.accept();
} catch (IOException e) {
break;
}
if (socket != null) {
synchronized (BluetoothService.this) {
switch (bluetoothState) {
case STATE_LISTEN:
case STATE_CONNECTING:
connected(socket, socket.getRemoteDevice(), socketType);
break;
case STATE_NONE:
case STATE_CONNECTED:
try {
socket.close();
} catch (IOException e) {
Log.e(TAG, "Could not close unwanted socket", e);
}
break;
}
}
}
}
}
public void cancel() {
try {
this.serverSocket.close();
} catch (IOException e) {
Log.e(TAG, "Socket Type" + socketType + "close() of server failed", e);
}
}
}
private class ConnectThread extends Thread {
private BluetoothSocket bluetoothSocket = null;
private BluetoothDevice bluetoothDevice = null;
private String socketType = null;
public ConnectThread(BluetoothDevice bluetoothDevice, boolean secure) {
this.bluetoothDevice = bluetoothDevice;
this.socketType = secure ? "Secure" : "Insecure";
BluetoothSocket tempBluetoothSocket = null;
try {
if (secure) {
tempBluetoothSocket = this.bluetoothDevice.createRfcommSocketToServiceRecord(MY_UUID_SECURE);
} else {
tempBluetoothSocket = this.bluetoothDevice.createInsecureRfcommSocketToServiceRecord(MY_UUID_INSECURE);
}
} catch (IOException e) {
Log.e(TAG, "Socket Type: " + this.socketType + "create() failed", e);
}
this.bluetoothSocket = tempBluetoothSocket;
}
public void run() {
Log.i(TAG, "BEGIN mConnectThread");
this.setName("ConnectThread");
bluetoothAdapter.cancelDiscovery();
try {
this.bluetoothSocket.connect();
} catch (IOException e) {
Log.e(TAG, e.getMessage(), e);
connectionFailed();
try {
this.bluetoothSocket.close();
} catch (IOException e2) {
Log.e(TAG, "unable to close() socket during connection failure", e2);
}
return;
}
synchronized (BluetoothService.this) {
connectThread = null;
}
connected(this.bluetoothSocket, this.bluetoothDevice, this.socketType);
}
public void cancel() {
try {
this.bluetoothSocket.close();
} catch (IOException e) {
Log.e(TAG, "close() of connect socket failed", e);
}
}
}
private class ConnectedThread extends Thread {
private BluetoothSocket bluetoothSocket = null;
private InputStream inputStream = null;
private OutputStream outputStream = null;
public ConnectedThread(BluetoothSocket bluetoothSocket, String socketType) {
Log.d(TAG, "create ConnectedThread");
this.bluetoothSocket = bluetoothSocket;
InputStream tempInputStream = null;
OutputStream tempOutputStream = null;
try {
tempInputStream = this.bluetoothSocket.getInputStream();
tempOutputStream = this.bluetoothSocket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "temp sockets not created", e);
}
this.inputStream = tempInputStream;
this.outputStream = tempOutputStream;
}
public void run() {
byte[] buffer = new byte[1024];
int bytes = 0;
while (true) {
try {
bytes = this.inputStream.read(buffer);
handler.obtainMessage(Globals.MESSAGE_READ, bytes, -1, buffer).sendToTarget();
} catch (IOException e) {
Log.e(TAG, "disconnected", e);
connectionLost();
BluetoothService.this.start();
break;
}
}
}
public void write(byte[] buffer) {
try {
this.outputStream.write(buffer);
handler.obtainMessage(Globals.MESSAGE_WRITE, -1, -1, buffer).sendToTarget();
} catch (IOException e) {
Log.e(TAG, "Exception during write", e);
}
}
public void cancel() {
try {
this.bluetoothSocket.close();
} catch (IOException e) {
Log.e(TAG, "close() of connect socket failed", e);
}
}
}
}
当我现在想要使用以下代码连接到BluetoothDevice
时:
private void connectDevice(Intent data, boolean secure) {
String address = data.getExtras().getString(BluetoothFragment.EXTRA_DEVICE_ADDRESS);
BluetoothDevice device = this.bluetoothAdapter.getRemoteDevice(address);
this.bluetoothService.connect(device, secure);
}
我收到以下错误:
02-07 12:47:15.633: E/BluetoothService(17671): read failed, socket might closed or timeout, read ret: -1
02-07 12:47:15.633: E/BluetoothService(17671): java.io.IOException: read failed, socket might closed or timeout, read ret: -1
02-07 12:47:15.633: E/BluetoothService(17671): at android.bluetooth.BluetoothSocket.readAll(BluetoothSocket.java:512)
所以我所做的一切都与android提供的例子完全一样。
您可以在Android中下载BluetoothChat
的示例代码
工作室示例代码。
唯一令人好奇的是uuid。我不知道如何创建它们,如果使用特殊的uuid很重要。我刚刚使用了从Android Play商店下载的uuid生成器并执行了以下操作:
private static final UUID MY_UUID_SECURE = UUID.fromString("a6fb84f6-20b3-477f-9160-bcd028bddc99");
private static final UUID MY_UUID_INSECURE = UUID.fromString("7dd8441a-1d4b-42f1-9996-a7d507548dfc");
所以问题是:如何连接到BluetoothDevice
?
加成
我使用Nexus 7和Nexus 4以及最新的Android版本。 我下载了几个蓝牙连接应用程序和所有这些 应用程序无法在我的设备之间建立连接。所以 也许这不是代码的问题?它是Nexus还是Android 5.0.1错误?
答案 0 :(得分:0)
你能试试这段代码吗?
您可以通过调用
将字符串传递给BT设备BluetoothPrinterHelper.BT.send(context, data)
注意:代码假定您已连接并与BT设备配对,并且是配对列表中唯一的设备。您可以在 findDevice(BluetoothAdapter)方法中更改此行为。
此外,UUID可以通过调用UUID.randomUUID()。toString()在Java本身生成,但在这种情况下,UUID扮演不同的角色。这标识了目标BT设备正在运行的配置文件。您可以在此处查看更多相关信息BT-UUID
package com.example.bt;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.os.AsyncTask;
public enum class BluetoothPrinterHelper {
BT;
private BluetoothDevice device;
private static BluetoothSocket socket;
private BluetoothSocket tmp;
private BluetoothAdapter adapter;
private String deviceName;
public void send(Context ctx, String data) {
mTryConnect = new TryConnect();
mTryConnect.execute();
boolean isConnected = false;
try {
Log.d(TAG, "Establishing connection to device");
isConnected = mTryConnect.get();
} catch (InterruptedException e) {
Log.e(TAG, "Error connecting to device");
return;
} catch (ExecutionException e) {
Log.e(TAG, "Error connecting to device");
return;
}
if (isConnected) {
Log.d(TAG, "Connection to device successfully established");
mTrySend = new TrySend(data);
mTrySend.execute();
} else {
Toast.makeText(ctx, "No BT device connected", Toast.LENGTH_LONG).show();
}
}
private BluetoothDevice findDevice(BluetoothAdapter adapter) {
Log.d(TAG, "Finding BT devices");
Set<BluetoothDevice> pairedDevices = null;
try {
pairedDevices = adapter.getBondedDevices();
} catch (NullPointerException e) {
Log.e(TAG, "Error retrieving paired devices");
}
if (pairedDevices != null && pairedDevices.size() == 1) {
Log.d(TAG, "Found 1 paired device");
for (BluetoothDevice bluetoothDevice : pairedDevices) {
return bluetoothDevice;
}
} else {
Log.w(TAG, "Many/No paired BT devices found");
}
return null;
}
private class TryConnect extends AsyncTask<Void, Void, Boolean> {
public TryConnect() {
adapter = BluetoothAdapter.getDefaultAdapter();
}
@Override
protected Boolean doInBackground(Void... params) {
// Check bonded devices list
device = findDevice(adapter);
if (adapter.isDiscovering()) {
adapter.cancelDiscovery();
}
// Create a socket for the device connection
if (device != null) {
try {
deviceName = device.getName();
Log.d(TAG, "Creating socket");
tmp = device.createRfcommSocketToServiceRecord(DEVICE_UUID);
} catch (NoSuchMethodException e) {
Log.e(TAG, "Printing - NoSuchMethodException", e);
return false;
} catch (IllegalArgumentException e) {
Log.e(TAG, "Printing - IllegalArgumentException", e);
return false;
} catch (IllegalAccessException e) {
Log.e(TAG, "Printing - IllegalAccessException", e);
return false;
} catch (InvocationTargetException e) {
Log.e(TAG, "Printing - InvocationTargetException", e);
return false;
}
}
socket = tmp;
// Connect to the created socket and device
try {
Log.d(TAG, "Creating connection to: " + deviceName);
socket.connect();
} catch (IOException e) {
Log.e(TAG, "Unable to connect. Closing connection", e);
try {
socket.close();
} catch (IOException e1) {
Log.e(TAG, "Unable to close connection during connection failure", e1);
}
return false;
} catch (NullPointerException e) {
Log.e(TAG, "NPE during BT socket connection");
}
return true;
}
}
private class TrySend extends AsyncTask<Void, Void, Boolean> {
byte[] out;
public TrySend(String data) {
try {
out = data.getBytes("UTF-8");
} catch (UnsupportedEncodingException e1) {
Log.w(TAG, "UnsupportedEncodingException");
}
}
@Override
protected Boolean doInBackground(Void... params) {
try {
// Get the output stream and ready for write
try {
Log.d(TAG, "Creating output stream");
outStream = socket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "Socket not created", e);
return false;
} catch (NullPointerException e) {
Log.e(TAG, "NPE retreiving socket stream");
return false;
}
// Write data to the socket for printing
try {
Log.d(TAG, "Write to output stream");
// Write format
outStream.write(command);
// Write data to print
DataOutputStream dataOutputStream = new DataOutputStream(outStream);
dataOutputStream.write(out);
dataOutputStream.flush();
} catch (IOException e) {
Log.e(TAG, "Exception during BT write to device", e);
return false;
} catch (NullPointerException e) {
Log.e(TAG, "NPE during socket write");
} finally {
try {
outStream.close();
} catch (IOException e) {
Log.e(TAG, "Exception during closing outstream", e);
} catch (NullPointerException e) {
Log.e(TAG, "NPE during BT socket close");
}
}
// Close the socket and cleanup
try {
Log.d(TAG, "Closing socket");
socket.close();
} catch (IOException e) {
Log.e(TAG, "Socket closing exception", e);
return false;
} catch (NullPointerException e) {
Log.e(TAG, "NPE during BT socket close");
}
} finally {
adapter = null;
device = null;
socket = null;
outStream = null;
}
return true;
}
}
}
更新:您可以尝试以下代码:
Method m = device.getClass().getMethod("createInsecureRfcommSocket", new Class[] { int.class });
tmp = (BluetoothSocket) m.invoke(device, 1);
而不是
tmp = device.createRfcommSocketToServiceRecord(DEVICE_UUID);