@Trevor Page 我认为是在正确的道路上。这是我用来连接基本邮票微控制器的谷歌示例。
/*
* 版权所有 (C) 2009 Android 开源项目
*
* 根据 Apache 许可证 2.0 版(“许可证”)获得许可;
* 除非遵守许可,否则您不得使用此文件。
* 您可以在以下网址获取许可证的副本
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 除非适用法律要求或书面同意,否则软件
*根据许可分发是在“原样”基础上分发的,
* 不提供任何明示或暗示的保证或条件。
* 请参阅许可证以了解特定语言的管理权限和
* 许可证下的限制。
*/
包 com.your_package;
导入 java.io.IOException;
导入 java.io.InputStream;
导入 java.io.OutputStream;
导入 java.util.UUID;
导入 android.bluetooth.BluetoothAdapter;
导入 android.bluetooth.BluetoothDevice;
导入 android.bluetooth.BluetoothServerSocket;
导入 android.bluetooth.BluetoothSocket;
导入android.content.Context;
导入android.os.Bundle;
导入android.os.Handler;
导入android.os.Message;
导入android.util.Log;
/**
* 这个类完成了设置和管理蓝牙的所有工作
*与其他设备的连接。它有一个线程来监听
* 传入连接,用于连接设备的线程,以及
* 连接时执行数据传输的线程。
*/
公共类蓝牙服务
{
// 调试
私有静态最终字符串 TAG = "BluetoothService_BoeBot";
私有静态最终布尔值 D = true;
// 创建服务器套接字时 SDP 记录的名称
private static final String NAME_SECURE = "BluetoothSecure";
private static final String NAME_INSECURE = "BluetoothInsecure";
// 此应用程序的唯一 UUID
私有静态最终 UUID MY_UUID_SECURE =
UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
私有静态最终 UUID MY_UUID_INSECURE =
UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
// 成员字段
私有最终蓝牙适配器 mAdapter;
私有最终处理程序 mHandler;
私有AcceptThread mSecureAcceptThread;
私有AcceptThread mInsecureAcceptThread;
私有连接线程 mConnectThread;
私有连接线程 mConnectedThread;
私有int mState;
// 表示当前连接状态的常量
公共静态最终 int STATE_NONE = 0; // 我们什么都不做
公共静态最终 int STATE_LISTEN = 1; // 现在监听传入的连接
公共静态最终 int STATE_CONNECTING = 2; // 现在开始一个传出连接
公共静态最终 int STATE_CONNECTED = 3; // 现在连接到远程设备
/**
* 构造函数。准备一个新的 BluetoothChat 会话。
* @param context UI 活动上下文
* @param handler 将消息发送回 UI Activity 的 Handler
*/
公共蓝牙服务(上下文上下文,处理程序处理程序)
{
mAdapter = BluetoothAdapter.getDefaultAdapter();
mState = STATE_NONE;
mHandler = 处理程序;
}
/**
* 设置聊天连接的当前状态
* @param state 定义当前连接状态的整数
*/
私有同步无效 setState(int state)
{
如果 (D)
Log.d(TAG, "setState() " + mState + " -> " + state);
mState = 状态;
// 将新状态赋予 Handler,以便 UI Activity 可以更新
mHandler.obtainMessage(BoeBot.MESSAGE_STATE_CHANGE, state, -1).sendToTarget();
}
/**
* 返回当前连接状态。 */
公共同步 int getState()
{
返回 mState;
}
/**
* 启动聊天服务。具体启动AcceptThread开始一个
* 监听(服务器)模式下的会话。活动调用 onResume() */
公共同步无效开始()
{
如果 (D)
Log.d(TAG, "开始");
// 取消任何试图建立连接的线程
如果(mConnectThread!= null)
{
mConnectThread.cancel();
mConnectThread = null;
}
// 取消当前运行连接的任何线程
如果(mConnectedThread != null)
{
mConnectedThread.cancel();
mConnectedThread = null;
}
setState(STATE_LISTEN);
// 启动线程以侦听 BluetoothServerSocket
如果(mSecureAcceptThread == null)
{
mSecureAcceptThread = new AcceptThread(true);
mSecureAcceptThread.start();
}
如果(mInsecureAcceptThread == null)
{
mInsecureAcceptThread = new AcceptThread(false);
mInsecureAcceptThread.start();
}
}
/**
* 启动 ConnectThread 以启动与远程设备的连接。
* @param device 要连接的蓝牙设备
* @param secure 套接字安全类型 - Secure (true) , Insecure (false)
*/
公共同步无效连接(蓝牙设备设备,布尔安全)
{
如果 (D)
Log.d(TAG, "连接到:" + 设备);
// 取消任何试图建立连接的线程
如果(mState == STATE_CONNECTING)
{
如果(mConnectThread!= null)
{
mConnectThread.cancel();
mConnectThread = null;
}
}
// 取消当前运行连接的任何线程
如果(mConnectedThread != null)
{
mConnectedThread.cancel();
mConnectedThread = null;
}
尝试
{
// 启动线程以连接给定的设备
mConnectThread = new ConnectThread(设备,安全);
mConnectThread.start();
setState(STATE_CONNECTING);
}catch(异常 e)
{
}
}
/**
* 启动 ConnectedThread 以开始管理蓝牙连接
* @param socket 建立连接的蓝牙套接字
* @param device 已连接的蓝牙设备
*/
公共同步无效连接(蓝牙套接字套接字,蓝牙设备设备,最终字符串套接字类型)
{
如果 (D)
Log.d(TAG, "已连接, 套接字类型:" + socketType);
// 取消完成连接的线程
如果(mConnectThread!= null)
{
mConnectThread.cancel();
mConnectThread = null;
}
// 取消当前运行连接的任何线程
如果(mConnectedThread != null)
{
mConnectedThread.cancel();
mConnectedThread = null;
}
// 取消接受线程,因为我们只想连接一个设备
如果(mSecureAcceptThread != null)
{
mSecureAcceptThread.cancel();
mSecureAcceptThread = null;
}
如果(mInsecureAcceptThread != null)
{
mInsecureAcceptThread.cancel();
mInsecureAcceptThread = null;
}
// 启动线程来管理连接并执行传输
mConnectedThread = new ConnectedThread(socket, socketType);
mConnectedThread.start();
// 将连接设备的名称发送回 UI Activity
消息消息 = mHandler.obtainMessage(BoeBot.MESSAGE_DEVICE_NAME);
捆绑捆绑 = 新捆绑();
bundle.putString(BoeBot.DEVICE_NAME, device.getName());
msg.setData(捆绑);
mHandler.sendMessage(msg);
setState(STATE_CONNECTED);
}
/**
* 停止所有线程
*/
公共同步无效停止()
{
如果 (D)
Log.d(TAG, "停止");
如果(mConnectThread!= null)
{
mConnectThread.cancel();
mConnectThread = null;
}
如果(mConnectedThread != null)
{
mConnectedThread.cancel();
mConnectedThread = null;
}
如果(mSecureAcceptThread != null)
{
mSecureAcceptThread.cancel();
mSecureAcceptThread = null;
}
如果(mInsecureAcceptThread != null)
{
mInsecureAcceptThread.cancel();
mInsecureAcceptThread = null;
}
setState(STATE_NONE);
}
/**
* 以非同步方式写入ConnectedThread
* @param out 要写入的字节数
* @see ConnectedThread#write(byte[])
*/
公共无效写入(字节[]输出)
{
// 创建临时对象
连接线程 r;
//同步一个ConnectedThread的副本
同步(这个)
{
如果(mState!= STATE_CONNECTED)
返回;
r = mConnectedThread;
}
// 执行非同步写入
r.write(out);
}
/**
* 表示连接尝试失败并通知UI Activity。
*/
私人无效连接失败()
{
// 向Activity发送失败消息
消息消息 = mHandler.obtainMessage(BoeBot.MESSAGE_TOAST);
捆绑捆绑 = 新捆绑();
bundle.putString(BoeBot.TOAST, "无法连接设备");
msg.setData(捆绑);
mHandler.sendMessage(msg);
// 重新启动服务以重新启动监听模式
BluetoothService.this.start();
}
/**
* 表示连接丢失并通知UI Activity。
*/
私人无效连接丢失()
{
// 向Activity发送失败消息
消息消息 = mHandler.obtainMessage(BoeBot.MESSAGE_TOAST);
捆绑捆绑 = 新捆绑();
bundle.putString(BoeBot.TOAST, "设备连接丢失");
msg.setData(捆绑);
mHandler.sendMessage(msg);
// 重新启动服务以重新启动监听模式
BluetoothService.this.start();
}
/**
* 此线程在侦听传入连接时运行。它的行为
* 像服务器端客户端。它一直运行直到接受连接
*(或直到取消)。
*/
私有类 AcceptThread 扩展 Thread
{
// 本地服务器套接字
私有最终 BluetoothServerSocket mmServerSocket;
私有字符串 mSocketType;
公共AcceptThread(布尔安全)
{
BluetoothServerSocket tmp = null;
mSocketType = 安全? “安全”:“不安全”;
// 创建一个新的监听服务器套接字
尝试
{
如果(安全)
{
tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME_SECURE, MY_UUID_SECURE);
} 别的
{
tmp = mAdapter.listenUsingInsecureRfcommWithServiceRecord(
NAME_INSECURE,MY_UUID_INSECURE);
}
} 捕捉(IOException e)
{
Log.e(TAG, "套接字类型:" + mSocketType + "listen() 失败", e);
}
mmServerSocket = tmp;
}
@Override
公共无效运行()
{
如果 (D)
{
Log.d(TAG, "套接字类型:" + mSocketType + "BEGIN mAcceptThread" + this);
}
setName("AcceptThread" + mSocketType);
BluetoothSocket 套接字 = null;
// 如果我们没有连接,则监听服务器套接字
而(mState!= STATE_CONNECTED)
{
尝试
{
// 这是一个阻塞调用,只会返回一个
// 连接成功或异常
套接字 = mmServerSocket.accept();
} 捕捉(IOException e)
{
Log.e(TAG, "套接字类型:" + mSocketType + "accept() 失败", e);
休息;
}
// 如果连接被接受
如果(套接字!= null)
{
同步(BluetoothService.this)
{
开关(mState)
{
案例STATE_LISTEN:
案例状态连接:
// 情况正常。启动连接的线程。
已连接(套接字,socket.getRemoteDevice(),mSocketType);
休息;
案例状态_无:
案例STATE_CONNECTED:
// 未准备好或已连接。终止新套接字。
尝试
{
socket.close();
} 捕捉(IOException e)
{
Log.e(TAG, "无法关闭不需要的套接字", e);
}
休息;
}
}
}
}
如果 (D)
{
Log.i(TAG, "END mAcceptThread, socket Type: " + mSocketType);
}
}
公共无效取消()
{
如果 (D)
{
Log.d(TAG, "Socket Type" + mSocketType + "cancel" + this);
}
尝试
{
mmServerSocket.close();
} 捕捉(IOException e)
{
Log.e(TAG, "Socket Type" + mSocketType + "close() of server failed", e);
}
}
}
/**
* 该线程在尝试建立传出连接时运行
* 带设备。它直接穿过;连接要么
* 成功或失败。
*/
私有类 ConnectThread 扩展 Thread
{
私有最终蓝牙套接字 mmSocket;
私有最终蓝牙设备 mmDevice;
私有字符串 mSocketType;
公共 ConnectThread(蓝牙设备设备,布尔安全)
{
mmDevice = 设备;
蓝牙套接字 tmp = null;
mSocketType = 安全? “安全”:“不安全”;
// 获取一个 BluetoothSocket 用于与
// 给定蓝牙设备
尝试
{
如果(安全)
{
tmp = device.createRfcommSocketToServiceRecord(MY_UUID_SECURE);
} 别的
{
tmp = device.createInsecureRfcommSocketToServiceRecord(MY_UUID_INSECURE);
}
} 捕捉(IOException e)
{
Log.e(TAG, "套接字类型:" + mSocketType + "create() failed", e);
}
mmSocket = tmp;
}
@Override
公共无效运行()
{
Log.i(TAG, "BEGIN mConnectThread SocketType:" + mSocketType);
setName("ConnectThread" + mSocketType);
// 始终取消发现,因为它会减慢连接速度
mAdapter.cancelDiscovery();
// 与蓝牙套接字建立连接
尝试
{
// 这是一个阻塞调用,只会返回一个
// 连接成功或异常
mmSocket.connect();
} 捕捉(IOException e)
{
// 关闭套接字
尝试
{
mmSocket.close();
} 捕捉(IOException e2)
{
Log.e(TAG, "unable to close() " + mSocketType + " socket during connection failure", e2);
}
连接失败();
返回;
}
// 重置 ConnectThread 因为我们已经完成了
同步(BluetoothService.this)
{
mConnectThread = null;
}
尝试
{
// 启动连接的线程
已连接(mmSocket,mmDevice,mSocketType);
}catch(异常 e)
{
Log.e(TAG, "", e);
}
}
公共无效取消()
{
尝试
{
mmSocket.close();
} 捕捉(IOException e)
{
Log.e(TAG, "close() of connect " + mSocketType + "socket failed", e);
}
}
}
/**
* 此线程在与远程设备连接期间运行。
*它处理所有传入和传出的传输。
*/
私有类 ConnectedThread 扩展 Thread
{
私有最终蓝牙套接字 mmSocket;
私有最终 InputStream mmInStream;
私有最终输出流 mmOutStream;
公共连接线程(蓝牙套接字套接字,字符串套接字类型)
{
Log.d(TAG, "创建 ConnectedThread:" + socketType);
mmSocket = 插座;
输入流 tmpIn = null;
输出流 tmpOut = null;
// 获取 BluetoothSocket 输入和输出流
尝试
{
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} 捕捉(IOException e)
{
Log.e(TAG, "临时套接字未创建", e);
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
@Override
公共无效运行()
{
Log.i(TAG, "开始 mConnectedThread");
字节[]缓冲区=新字节[1024];
整数字节;
// 连接时继续监听 InputStream
而(真)
{
尝试
{
// 从 InputStream 中读取
字节= mmInStream.read(缓冲区);
// 将获取的字节发送到 UI Activity
mHandler.obtainMessage(BoeBot.MESSAGE_READ, bytes, -1, buffer).sendToTarget();
} 捕捉(IOException e)
{
Log.e(TAG, "断开连接", e);
连接丢失();
休息;
}
}
}
/**
* 写入连接的 OutStream。
* @param buffer 要写入的字节数
*/
公共无效写入(字节[]缓冲区)
{
尝试
{
mmOutStream.write(缓冲区);
// 将发送的消息分享回 UI Activity
mHandler.obtainMessage(BoeBot.MESSAGE_WRITE, -1, -1, 缓冲区).sendToTarget();
} 捕捉(IOException e)
{
Log.e(TAG, "写入异常", e);
}
}
公共无效取消()
{
尝试
{
mmSocket.close();
} 捕捉(IOException e)
{
Log.e(TAG, "close() of connect socket failed", e);
}
}
}
}
测试它是否有效。
BluetoothService mService = new BluetoothService(this, mHandler);
mService.write(Bytes);