因为项目需要,需要将本地数据库的数据,通过蓝牙传输到另一台设备上。然后百度了蛮久,看了蛮多的,觉得有必要自己整理一下,蓝牙的传输功能。


首先,我们都知道的,蓝牙连接数需要先配对的,两台手机配对后才可进行蓝牙处理。对于蓝牙配对的方法网上一大堆,我也就不具体说了,大概记录一下。基本的我们可以通过手机原有的蓝牙功能,进行搜索配对后在自身的APK中,直接启动蓝牙,然后查询已匹配设备就行了。因为项目目前没有要求实现匹配功能,我也就能省则省了...不过还是总体介绍一下吧。

在安卓源码中,首先要知道有提供了一个蓝牙类:BluetoothAdapter , 我们需要先初始化这个类,才能huod获得蓝牙的相关数据。
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();  
接着我们需要先注册广播,广播的注册有静态注册和动态注册,我就不详说了,我这用的是动态注册: 
//注册蓝牙广播 IntentFilter filter = new IntentFilter(
BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
getActivity().registerReceiver(receiver, filter); filter = new
IntentFilter(BluetoothDevice.ACTION_FOUND);
getActivity().registerReceiver(receiver, filter);
然后再实现广播的处理:
public class BluetoothReceiver extends BroadcastReceiver { @Override public
void onReceive(Context context, Intent intent) { String action =
intent.getAction(); if (action.equals(BluetoothDevice.ACTION_FOUND)) { //未匹配
BluetoothDevice device =
intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); } else if
(action.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) { //搜索完成 } } }

基本就是这样,里面的参数判断的话,蓝牙有各种不同的状态,可以根据搜索到的设备进行检查,然后区分当前蓝牙处于什么状态。而我因为业务原因,暂时也不需要去监听匹配,所以,我用的是以下这个方法:
Set<BluetoothDevice> bondedDevices = mBluetoothAdapter.getBondedDevices();
for (BluetoothDevice bondedDevice : bondedDevices) {
bluetoothDevices.add(bondedDevice); }
当蓝牙开启后,通过此方法,获得已匹配的设备。

另外补充一个开启蓝牙的方法:此方法为了让其他设备可以搜索到本机,里面的300表示暴露时间秒
//开启显示,让本机可以被搜索到 if (mBluetoothAdapter.getScanMode() !=
BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) { Intent
discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent); } else { showToast("蓝牙已开启"); }
 

好了,以上是一些基本的蓝牙功能,到哪里都可以找到一大堆的。下面开始记录关键,蓝牙数据传输

既然要传输数据,和给api通讯一样,肯定是要有一个服务端,一个客户端的。而服务端是需要在开启状态,监听客户端发送的数据。而服务属于阻塞操作,所以要开启一个线程
,再来开启一个服务:
BluetoothServerSocket
mmServerSocket=mBluetoothAdapter.listenUsingRfcommWithServiceRecord("Name",
UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66")); BluetoothSocket
socket = mmServerSocket.accept();
通过以上方法来开启一个服务,这里“Name”,UUID,服务端和客户端都必须一样,这是识别用的。另外要注意mmServerSocket 是否为 null
,若未null 则也是无法开启的。另外在之后若出现无法连接的情况,这里我们可以查下缓一缓UUID的值,具体这个坑什么原因我也说不清,反正换一换呗。

当以上的方法调用了之后,服务器基本就算开启了的。只要没抛异常的话。

然后我们需要一个输入流,可以写循环,也可以不写循环。循环的话就通过传输过来的数据,做个标记结束它。这些都是一些废话,就直接写个流吧...
InputStream mmInStream = socket.getInputStream(); bytes =
mmInStream.read(buffer); String data = new String(buffer, 0, bytes, "UTF-8");
Message msg = Message.obtain(); msg.what = Constants.MESSAGE_READ; msg.obj =
data; mHandler.sendMessage(msg);
这里注意,我们在之前开启服务端的时候,要获得一个蓝牙的操作类:BluetoothSocket ,这个类是用来操作流,服务的。ranho然后通过handler
将接收的数据回传到主线程。服务端到这里就完了。

接着写客户端的:

客户端这边就轻松多了,既然服务端已经开启,我们就进行连接,通过BluetoothAdapter 
我们已经得到了已经匹配的设备,然后选择你要连接的蓝牙设备,不过记得先关闭蓝牙搜索功能:
mBluetoothAdapter.cancelDiscovery(); BluetoothSocket mmSocket=
device.createRfcommSocketToServiceRecord(UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66"));
mmSocket.connect();
然后用要连接的设备device,输入服务端的UUID,接着连接。当然,以上的操作也是需要在子线程中进行的。

连接结束后,可以写个方法通知服务端,谁谁谁连接了。当然我们也要写一个输出流,用于一会输出数据到服务端去。

最后,最最重要的,用完了li流一定要记得关闭。

为了以后方便,我也做了一个功能类,之后需要用时就直接调用。这里就贡献给大家分享一下吧!
public class BluetoothChatService { private static final String TAG =
"BluetoothChatService"; private static final String NAME_SECURE =
"BluetoothChatSecure"; private static final String NAME_INSECURE =
"BluetoothChatInsecure"; private static final UUID MY_UUID_SECURE =
UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66"); public final
BluetoothAdapter mAdapter; public final Handler mHandler; public AcceptThread
mSecureAcceptThread; public AcceptThread mInsecureAcceptThread; public
ConnectThread mConnectThread; public ConnectedThread mConnectedThread; private
int mState; 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; public BluetoothChatService(Context context,
Handler handler) { mAdapter = BluetoothAdapter.getDefaultAdapter(); mState =
STATE_NONE; mHandler = handler; } private synchronized void setState(int state)
{ Log.d(TAG, "setState() " + mState + " -> " + state); mState = state;
mHandler.obtainMessage(Constants.MESSAGE_STATE_CHANGE, state,
-1).sendToTarget(); } public synchronized int getState() { return mState; }
public synchronized void start() { Log.d(TAG, "start"); if (mConnectThread !=
null) { mConnectThread.cancel(); mConnectThread = null; } if (mConnectedThread
!= null) { mConnectedThread.cancel(); mConnectedThread = null; }
setState(STATE_LISTEN); if (mSecureAcceptThread == null) { mSecureAcceptThread
= new AcceptThread(); mSecureAcceptThread.start(); } } public synchronized void
connect(BluetoothDevice device) { Log.d(TAG, "connect to: " + device); if
(mState == STATE_CONNECTING) { if (mConnectThread != null) {
mConnectThread.cancel(); mConnectThread = null; } } if (mConnectedThread !=
null) { mConnectedThread.cancel(); mConnectedThread = null; } mConnectThread =
new ConnectThread(device); mConnectThread.start(); setState(STATE_CONNECTING);
} public synchronized void connected(BluetoothSocket socket, BluetoothDevice
device) { if (mConnectThread != null) { mConnectThread.cancel(); mConnectThread
= null; } if (mConnectedThread != null) { mConnectedThread.cancel();
mConnectedThread = null; } if (mSecureAcceptThread != null) {
mSecureAcceptThread.cancel(); mSecureAcceptThread = null; } if
(mInsecureAcceptThread != null) { mInsecureAcceptThread.cancel();
mInsecureAcceptThread = null; } mConnectedThread = new ConnectedThread(socket);
mConnectedThread.start(); Message msg =
mHandler.obtainMessage(Constants.MESSAGE_DEVICE_NAME); Bundle bundle = new
Bundle(); bundle.putString(Constants.DEVICE_NAME, device.getName());
msg.setData(bundle); mHandler.sendMessage(msg); setState(STATE_CONNECTED); }
public synchronized void stop() { Log.d(TAG, "stop"); if (mConnectThread !=
null) { mConnectThread.cancel(); mConnectThread = null; } if (mConnectedThread
!= null) { mConnectedThread.cancel(); mConnectedThread = null; } if
(mSecureAcceptThread != null) { mSecureAcceptThread.cancel();
mSecureAcceptThread = null; } if (mInsecureAcceptThread != null) {
mInsecureAcceptThread.cancel(); mInsecureAcceptThread = null; }
setState(STATE_NONE); } public void write(byte[] out) { ConnectedThread r;
synchronized (this) { if (mState != STATE_CONNECTED) return; r =
mConnectedThread; } r.write(out); } private void connectionFailed() { Message
msg = mHandler.obtainMessage(Constants.MESSAGE_TOAST); Bundle bundle = new
Bundle(); bundle.putString(Constants.TOAST, "无法连接设备!"); msg.setData(bundle);
mHandler.sendMessage(msg); BluetoothChatService.this.start(); } private void
connectionLost() { Message msg =
mHandler.obtainMessage(Constants.MESSAGE_TOAST); Bundle bundle = new Bundle();
bundle.putString(Constants.TOAST, "设备连接已断开"); msg.setData(bundle);
mHandler.sendMessage(msg); BluetoothChatService.this.start(); } private class
AcceptThread extends Thread { // The local server socket private final
BluetoothServerSocket mmServerSocket; private String mSocketType; public
AcceptThread() { BluetoothServerSocket tmp = null; try { tmp =
mAdapter.listenUsingRfcommWithServiceRecord(NAME_SECURE, MY_UUID_SECURE); }
catch (IOException e) { // Log.e(TAG, "Socket Type: " + mSocketType + "listen()
failed", e); } mmServerSocket = tmp; } public void run() { BluetoothSocket
socket = null; while (mState != STATE_CONNECTED) { try { socket =
mmServerSocket.accept(); } catch (IOException e) { // Log.e(TAG, "Socket Type:
" + mSocketType + "accept() failed", e); break; } if (socket != null) {
synchronized (BluetoothChatService.this) { switch (mState) { case STATE_LISTEN:
case STATE_CONNECTING: // Situation normal. Start the connected thread.
connected(socket, socket.getRemoteDevice()); 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()
{ // Log.d(TAG, "Socket Type" + mSocketType + "cancel " + this); try {
mmServerSocket.close(); } catch (IOException e) { // Log.e(TAG, "Socket Type" +
mSocketType + "close() of server failed", e); } } } private class ConnectThread
extends Thread { private final BluetoothSocket mmSocket; private final
BluetoothDevice mmDevice; public ConnectThread(BluetoothDevice device) {
mmDevice = device; BluetoothSocket tmp = null; try { tmp =
device.createRfcommSocketToServiceRecord( MY_UUID_SECURE); } catch (IOException
e) { // Log.e(TAG, "Socket Type: " + mSocketType + "create() failed", e); }
mmSocket = tmp; } public void run() { // Log.i(TAG, "BEGIN mConnectThread
SocketType:" + mSocketType); mAdapter.cancelDiscovery(); try {
mmSocket.connect(); } catch (IOException e) { try { mmSocket.close(); } catch
(IOException e2) { // Log.e(TAG, "unable to close() " + mSocketType + // "
socket during connection failure", e2); } connectionFailed(); return; }
synchronized (BluetoothChatService.this) { mConnectThread = null; }
connected(mmSocket, mmDevice); } public void cancel() { try { mmSocket.close();
} catch (IOException e) { // Log.e(TAG, "close() of connect " + mSocketType + "
socket failed", e); } } } private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket; private final InputStream mmInStream;
private final OutputStream mmOutStream; public ConnectedThread(BluetoothSocket
socket) { // Log.d(TAG, "create ConnectedThread: " + socketType); mmSocket =
socket; InputStream tmpIn = null; OutputStream tmpOut = null; try { tmpIn =
socket.getInputStream(); tmpOut = socket.getOutputStream(); } catch
(IOException e) { // Log.e(TAG, "temp sockets not created", e); } mmInStream =
tmpIn; mmOutStream = tmpOut; } public void run() { synchronized
(BluetoothChatService.class) { byte[] buffer = new byte[1024 * 4]; int bytes;
while (mState == STATE_CONNECTED) { try { bytes = mmInStream.read(buffer);
String data = new String(buffer, 0, bytes, "UTF-8"); Message msg =
Message.obtain(); msg.what = Constants.MESSAGE_READ; msg.obj = data;
mHandler.sendMessage(msg); } catch (IOException e) { connectionLost();
BluetoothChatService.this.start(); break; } } } } public void write(byte[]
buffer) { try { mmOutStream.write(buffer); mmOutStream.flush();
mHandler.obtainMessage(Constants.MESSAGE_WRITE, -1, -1, buffer)
.sendToTarget(); } catch (IOException e) { //Log.e(TAG, "Exception during
write", e); } } public void cancel() { try { mmSocket.close(); } catch
(IOException e) { // Log.e(TAG, "close() of connect socket failed", e); } } } }
/** * @desc ${BluetoothService 中使用的常量} */ public class Constants { public
static final int MESSAGE_STATE_CHANGE = 1; //状态改变 public static final int
MESSAGE_READ = 2; //读取 public static final int MESSAGE_WRITE = 3; //写出 public
static final int MESSAGE_DEVICE_NAME = 4; //设备 名称 public static final int
MESSAGE_TOAST = 5; //连接失败 public static final String DEVICE_NAME =
"device_name"; public static final String TOAST = "toast"; } private Handler
mHandler = new Handler() { @Override public void handleMessage(Message msg) {
super.handleMessage(msg); switch (msg.what) { case Constants.MESSAGE_TOAST:
String statu = msg.getData().getString(Constants.TOAST); showToast(statu + "");
break; case Constants.MESSAGE_DEVICE_NAME: String string =
msg.getData().getString(Constants.DEVICE_NAME); showToast("已连接设备" + string);
break; case Constants.MESSAGE_READ: //读取接收数据 break; case
Constants.MESSAGE_WRITE: //发送端,正在发送的数据 break; } } }; private void iniData(){
省****** ****** ******略 BluetoothChatService chatService = new
BluetoothChatService(getActivity(), mHandler);
Listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override public void onItemClick(AdapterView<?> parent, View view, int
position, long id) { // 判断当前是否还是正在搜索周边设备,如果是则暂停搜索 if
(mBluetoothAdapter.isDiscovering()) { mBluetoothAdapter.cancelDiscovery(); }
BluetoothDevice bluetoothDevice = bluetoothDevices.get(position); //客户端连接
chatService.connect(bluetoothDevice); } }); //如果要开启服务端直接调用以下语句
//chatService.start(); } /** * 准备开始发送数据 */ private void snedInfo() { if
(chatService.getState() != BluetoothChatService.STATE_CONNECTED) {
showToast("连接失败"); return; } String toSendJson = new Gson().toJson(“Bean数据”);
if (toSendJson.length() > 0) { byte[] send = new byte[0]; try { send =
toSendJson.getBytes(); } catch (Exception e) { e.printStackTrace(); }
chatService.write(send); } } }); }
以上就是我目前做的蓝牙传输功能了,先这样吧...然后再慢慢优化改进的。各种状态也都有了的,自己慢慢调整一下吧..

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:ixiaoyang8@qq.com
QQ群:637538335
关注微信