个人博客:haichenyi.com。感谢关注
之前公司做智能家居类型,其中做了一个智能衣柜项目,与衣柜通信就是用的蓝牙通信。一些操作一些简单的开关指令,蓝牙通信与socket是类似的。
不想写说明,只想贴代码
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
/**
* Author: 海晨忆.
* Date: 2018/1/4
* Desc:
*/
public class BluetoothService extends Service {
//得到蓝牙适配器
private BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
private BluetoothReceiver mReceiver;
@Override
public void onCreate() {
super.onCreate();
EventBus.getDefault().register(this);
if (mBluetoothAdapter != null) {
mReceiver = new BluetoothReceiver().setBluetoothAdapter(mBluetoothAdapter);
//注册设备被发现时的广播
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter);
//注册一个搜索结束时的广播
IntentFilter filter2 = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(mReceiver, filter2);
startLinkBluetooth();
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
/**
* 开始连接蓝牙设备.
*/
private void startLinkBluetooth() {
if (null != mBluetoothAdapter) {
//判断蓝牙是否打开
if (!mBluetoothAdapter.isEnabled()) {
//若没打开则打开蓝牙
mBluetoothAdapter.enable();
}
mBluetoothAdapter.startDiscovery();
Log.v(Constants.HTTP_WZ, "正在扫描");
}
}
@Subscribe
@SuppressWarnings("unused")
public void handleMsg(BluetoothInfo bluetoothInfo) {
if (bluetoothInfo.isLink) {
startLinkBluetooth();
}
}
public static class BluetoothInfo {
private boolean isLink = false;
public BluetoothInfo setLink(boolean link) {
this.isLink = link;
return this;
}
}
@Override
public void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
if (mReceiver != null) {
mReceiver.unRegister();
unregisterReceiver(mReceiver);
}
}
}
这个就是我的蓝牙服务类,这个类的逻辑怎么走的呢?
EventBus的东西我就不说了
首先获取蓝牙适配器
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter != null) {
mReceiver = new BluetoothReceiver().setBluetoothAdapter(mBluetoothAdapter);
//注册设备被发现时的广播
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter);
//注册一个搜索结束时的广播
IntentFilter filter2 = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(mReceiver, filter2);
startLinkBluetooth();
}
/**
* 开始连接蓝牙设备.
*/
private void startLinkBluetooth() {
if (null != mBluetoothAdapter) {
//判断蓝牙是否打开
if (!mBluetoothAdapter.isEnabled()) {
//若没打开则打开蓝牙
mBluetoothAdapter.enable();
}
mBluetoothAdapter.startDiscovery();
Log.v(Constants.HTTP_WZ, "正在扫描");
}
}
@Override
public void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
if (mReceiver != null) {
mReceiver.unRegister();
unregisterReceiver(mReceiver);
}
}
<service android:name=".service.BluetoothService"/>
Intent bluetoothService = new Intent(this, BluetoothService.class);
startService(bluetoothService);//启动蓝牙服务
stopService(bluetoothService);
@Nullable
@Override
public IBinder onBind(Intent intent) {
//非绑定方式,返回值为null
return null;
}
/**
* Author: 海晨忆.
* Date: 2018/1/4
* Desc: 蓝牙广播监听
*/
public class BluetoothReceiver extends BroadcastReceiver {
//衣柜的蓝牙名称
private static final String WARDROBE_NAME = "WARDROBE";
// 固定的UUID
private static final String SPP_UUID = "00001101-0000-1000-8000-00805F9B34FB";
private BluetoothSocket bluetoothSocket;
private BluetoothAdapter bluetoothAdapter;
private InputStream mInputStream;
private OutputStream outputStream;
private boolean isRunning = false;
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action != null) {
if (action.equals(BluetoothDevice.ACTION_FOUND)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.v(Constants.HTTP_WZ, device.getName() + device.getAddress());
if (device.getBondState() == BluetoothDevice.BOND_BONDED
&& device.getName().equals(WARDROBE_NAME)) {
UUID uuid = UUID.fromString(SPP_UUID);
try {
bluetoothSocket = device.createRfcommSocketToServiceRecord(uuid);
Log.v(Constants.HTTP_WZ, "准备连接");
connect();
} catch (IOException e) {
e.printStackTrace();
}
}
} else if (action.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) {
if (!EventBus.getDefault().isRegistered(this))
EventBus.getDefault().register(this);
Observable.timer(2, TimeUnit.SECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(aLong -> {
if (null == bluetoothSocket || !bluetoothSocket.isConnected())
ToastUtils.showTipMsg(R.string.no_wardrobe);
});
}
}
}
private void connect() {
new Thread(() -> {
if (bluetoothSocket != null) {
bluetoothAdapter.cancelDiscovery();
try {
bluetoothSocket.connect();
Observable.just(1)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(integer -> ToastUtils.showTipMsg(R.string.link_wardrobe));
Log.v(Constants.HTTP_WZ, "连接成功");
mInputStream = bluetoothSocket.getInputStream();
Log.v(Constants.HTTP_WZ, "mInputSream:" + mInputStream.toString());
isRunning = true;
outputStream = bluetoothSocket.getOutputStream();
Log.v(Constants.HTTP_WZ, "outputStream:" + outputStream.toString());
BufferedReader br;
while (isRunning) {
br = new BufferedReader(new InputStreamReader(mInputStream, "utf-8"));
String s = br.readLine();
//acceptReply(s);
Log.v(Constants.HTTP_WZ, "收到的数据:" + s);
}
} catch (IOException e) {
e.printStackTrace();
try {
if (mInputStream != null) {
mInputStream.close();
Log.v(Constants.HTTP_WZ, "mInputSream.close()");
}
if (outputStream != null) {
outputStream.close();
Log.v(Constants.HTTP_WZ, "outputStream.close()");
}
if (bluetoothSocket != null) {
bluetoothSocket.close();
Log.v(Constants.HTTP_WZ, "socket.close()");
bluetoothSocket = null;
}
isRunning = false;
} catch (Exception e2) {
// TODO: handle exception
}
}
}
}).start();
}
public BluetoothReceiver setBluetoothAdapter(BluetoothAdapter adapter) {
this.bluetoothAdapter = adapter;
return this;
}
/**
* 反注册eventBus.
*/
public void unRegister() {
EventBus.getDefault().unregister(this);
}
}
这个就是我的蓝牙广播类,这个逻辑又是怎么走的呢?
// 固定的UUID连接的时候需要uuid
private static final String SPP_UUID = "00001101-0000-1000-8000-00805F9B34FB";
//获取socket
BluetoothSocket bluetoothSocket =device.createRfcommSocketToServiceRecord(uuid);
//连接之前取消扫描,注意非空判断。adapter是在服务里面申明的,通过setBluetoothAdapter方法传过来的
bluetoothAdapter.cancelDiscovery();
//连接,这里是阻塞的方式,注意要新开线程连接
bluetoothSocket.connect();
//获取输入流对象和输出流对象
InputStream mInputStream = bluetoothSocket.getInputStream();
OutputStream outputStream = bluetoothSocket.getOutputStream();
//发送消息
private void sendInstruct(String msg) {
try {
if (null == bluetoothSocket || !bluetoothSocket.isConnected()) {
SocketUtils.reLinkBluetooth();
return;
}
Log.v(Constants.HTTP_WZ, "发送的数据-->" + msg + BluetoothInstruct.FINISH);
outputStream.write(msg.getBytes());
outputStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
//接收消息,一次读一行,简单的蓝牙通信换行符作为结束标记
BufferedReader br;
while (isRunning) {
br = new BufferedReader(new InputStreamReader(mInputStream, "utf-8"));
String s = br.readLine();
acceptReply(s);
Log.v(Constants.HTTP_WZ, "收到的数据:" + s);
}
//异常的时候释放资源
try {
if (mInputStream != null) {
mInputStream.close();
Log.v(Constants.HTTP_WZ, "mInputSream.close()");
}
if (outputStream != null) {
outputStream.close();
Log.v(Constants.HTTP_WZ, "outputStream.close()");
}
if (bluetoothSocket != null) {
bluetoothSocket.close();
Log.v(Constants.HTTP_WZ, "socket.close()");
bluetoothSocket = null;
}
isRunning = false;
} catch (Exception e2) {
// TODO: handle exception
}