又到了Android小白的开发之路上写笔记的时间了~~
开篇都不知道说什么好... ...前两个月写了WIFI,后来也想写一下蓝牙的,可惜公司产品不给力,出现了很多BUG,一直在修啊修,最近终于有点空闲时间了。那就来简单的尝试一下
关于蓝牙开发,优秀博客一大片,你能来看我这篇辣鸡文章真是不胜感激。基础知识/理论什么的我就不说了,我也是一边看着官方文档来的,想深入了解去看看官方文档也是极好的。
我们知道Andorid的蓝牙分为两种,一种是传统的一种是低功耗蓝牙(BLE),一步一步来,这里先写一下传统蓝牙~
功能实现
主要是实现两台手机能通过蓝牙相互发送消息。两手机可以任意一台充当服务端,一台充当客户端。过程尽量越简单,让大家看的更清楚!
代码-准备工作
1.首先我们需要一个蓝牙适配器,用于搜索设备/连接设备;一个UUID,用于创建服务端;一个广播接收器,用于监听搜索结果。
public static final String BT_UUID = "00001101-0000-1000-8000-00805F9B34FB";//uuid
private BluetoothAdapter mBluetoothAdapter;//蓝牙适配器
private BlueToothStateReceiver mReceiver;//广播接收器
private ConnectThread mConnectThread; //客户端线程
private AcceptThread mAcceptThread; //服务端线程
2.然后先打开蓝牙
private void openBT() {
if (mBluetoothAdapter == null) {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
}
//1.设备不支持蓝牙,结束应用
if (mBluetoothAdapter == null) {
finish();
return;
}
//2.判断蓝牙是否打开
if (!mBluetoothAdapter.enable()) {
//没打开请求打开
Intent btEnable = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(btEnable, REQUEST_BT_ENABLE_CODE);
}
}
3.注册广播接收器
private void registerRec() {
//3.注册蓝牙广播
mReceiver = new BlueToothStateReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothDevice.ACTION_FOUND);//搜多到蓝牙
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);//搜索结束
registerReceiver(mReceiver, filter);
}
4.开始搜索设备
if (mBluetoothAdapter != null) {
mBluetoothAdapter.startDiscovery();
}
5.获取搜索结果
class BlueToothStateReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(MainActivity.this, "触发广播", Toast.LENGTH_SHORT).show();
String action = intent.getAction();
switch (action) {
case BluetoothDevice.ACTION_FOUND:
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Toast.makeText(MainActivity.this, "找到设备" + device.getName(), Toast.LENGTH_SHORT).show();
if (mRvAdapter != null) {
mRvAdapter.addDevice(device);
}
break;
case BluetoothAdapter.ACTION_DISCOVERY_FINISHED:
mMessageAdapter.addMessage("搜索结束");
break;
}
}
}
额~~还忘了一步,搜索完到指定设备后要记得关闭搜索
if (mBluetoothAdapter != null && mBluetoothAdapter.isDiscovering()) {
mBluetoothAdapter.cancelDiscovery();
}
----------------------------然后基础的就到这里了----------------------------------
接下来,是点击列表,然后连接对应的蓝牙。
开头说了,要实现两台手机任意充当客户端或者服务端,所以在程序中应该包含有服务端也要有客户端,因此我们需要两个线程,分别处理这两种情况。
6.首先服务端线程代码--里面有些没用到或者注释的代码还有一些通知UI更新的代码,大家可以忽略
class AcceptThread extends Thread {
private BluetoothServerSocket mServerSocket;
private BluetoothSocket mSocket;
private InputStream btIs;
private OutputStream btOs;
private PrintWriter writer;
private boolean canAccept;
private boolean canRecv;
public AcceptThread() {
canAccept = true;
canRecv = true;
}
@Override
public void run() {
try {
//获取套接字
BluetoothServerSocket temp = mBluetoothAdapter.listenUsingInsecureRfcommWithServiceRecord("TEST", UUID.fromString(BT_UUID));
mServerSocket = temp;
//监听连接请求 -- 作为测试,只允许连接一个设备
if (mServerSocket != null) {
// while (canAccept) {
mSocket = mServerSocket.accept();//阻塞等待客户端连接
sendHandlerMsg("有客户端连接");
// }
}
//获取输入输出流
btIs = mSocket.getInputStream();
btOs = mSocket.getOutputStream();
//通讯-接收消息
BufferedReader reader = new BufferedReader(new InputStreamReader(btIs, "UTF-8"));
String content = null;
while (canRecv) {
content = reader.readLine();
sendHandlerMsg("收到消息:" + content);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (mSocket != null) {
mSocket.close();
}
// btIs.close();//两个输出流都依赖socket,关闭socket即可
// btOs.close();
} catch (IOException e) {
e.printStackTrace();
sendHandlerMsg("错误:" + e.getMessage());
}
}
}
private void sendHandlerMsg(String content) {
Message msg = mHandler.obtainMessage();
msg.what = 1001;
msg.obj = content;
mHandler.sendMessage(msg);
}
public void write(String msg) {
if (btOs != null) {
try {
if (writer == null) {
writer = new PrintWriter(new OutputStreamWriter(btOs, "UTF-8"), true);
}
writer.println(msg);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
writer.close();
sendHandlerMsg("错误:" + e.getMessage());
}
}
}
}
7.连接线程代码--用于点击某个设备后建立连接--同样里面有些没用到或者注释的代码用于以后拓展的,还有一些通知UI更新的代码,大家可以忽略