1.背景需求
根据需求,在Android系统的蓝牙模块的基础上,对蓝牙机能进行自定义开发。主要还是调用Android中蓝牙相关的API,具体的实现过程后续会详细讲解。
2.开发流程
通过调用BluetoothAdapter.java中的源生接口,来封装一些符合自己需求的接口。
//使用蓝牙,需要声明BLUETOOTH权限,如果需要扫描设备或者操作蓝牙设置,则还需要BLUETOOTH_ADMIN权限
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
private BluetoothAdapter m_bluetoothAdapter = null;
// get the bluetoothAdapter
m_bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
// save bt devices
private ArrayList<BluetoothDevice> m_searchListItem = new ArrayList<BluetoothDevice>();
//检索可连接的蓝牙设备
private boolean startSearch() {
if (null != m_bluetoothAdapter) {
return m_bluetoothAdapter.startDiscovery();
}
}
//停止检索设备
private boolean cancelDiscovery(){
if(null != m_bluetoothAdapter){
//判断当前是否在检索中
if(m_bluetoothAdapter.isDiscovering()){
return m_bluetoothAdapter.cancelDiscovery();
}
}else{
return false;
}
}
//关闭蓝牙
private void closeBT(){
if(mBluetoothAdapter == null){
mBluetoothAdapter.disable();
}
}
//打开蓝牙
private void openBT(){
//方法一:优雅的践行开启并且有弹框进行提示,隐式启动Intent:
if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
//没打开请求打开
Intent btEnable = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(btEnable, REQUEST_BT_ENABLE_CODE);
}
//方法二:直接简单暴力不给用户进行提示
if (!mBluetoothAdapter.isEnabled()) {
mBluetoothAdapter.enable();
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_BT_ENABLE_CODE) {
if (resultCode == RESULT_OK) {
//用户允许打开蓝牙
mMessageAdapter.addMessage("用户同意打开蓝牙");
} else if (resultCode == RESULT_CANCELED) {
//用户取消打开蓝牙
mMessageAdapter.addMessage("用户拒绝打开蓝牙");
}
}
super.onActivityResult(requestCode, resultCode, data);
}
//动态注册蓝牙广播
private void registerRec() {
mReceiver = new BlueToothStateReceiver(); //见BlueTooth开发(2)
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothDevice.ACTION_FOUND);//搜多到蓝牙
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);//搜索结束
registerReceiver(mReceiver, filter);
}
//客户端 发起连接方,用于点击某个设备后建立连接
class ConnectThread extends Thread {
private BluetoothDevice mDevice;
private BluetoothSocket mSocket;
private InputStream btIs;
private OutputStream btOs;
private boolean canRecv;
private PrintWriter writer;
public ConnectThread(BluetoothDevice device) {
mDevice = device;//被点击设备
canRecv = true;
}
@Override
public void run() {
if (mDevice != null) {
try {
//获取套接字
BluetoothSocket temp = mDevice.createInsecureRfcommSocketToServiceRecord(UUID.fromString(BT_UUID));
//mDevice.createRfcommSocketToServiceRecord(UUID.fromString(BT_UUID));//sdk 2.3以下使用
mSocket = temp;
//发起连接请求
if (mSocket != null) {
mSocket.connect();
}
sendHandlerMsg("连接 " + mDevice.getName() + "成功!");
//获取输入输出流
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();
sendHandlerMsg("错误:" + e.getMessage());
} 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());
}
}
}
}
//服务端 接受连接方
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());
}
}
}
}