准备
1.蓝牙串行端口基于SPP协议(Serial Port Profile),能在蓝牙设备之间创建串口进行数据传输
2.SPP的UUID:00001101-0000-1000-8000-00805F9B34FB
3.Android手机一般以客户端的角色主动连接SPP协议设备
连接流程
1.检测蓝牙状态
若蓝牙未打开,则打开蓝牙~
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
@Override
protected void onResume() {
super.onResume();
if (!bluetoothAdapter.isEnabled()) {
// open blueTooth
Intent enableBtIntent = new Intent( BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_ENABLE_BT && resultCode == Activity.RESULT_CANCELED) {
finish();
return;
}
}
2.注册设备搜索广播信息
使用registerReceiver注册broadcastReceiver来获取搜索设备等消息
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(receiver, intentFilter);
// receiver
private final BroadcastReceiver receiver = new BroadcastReceiver(){
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// find a device
BluetoothDevice device = intent .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
//未配对设备
newDeviceArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}else {
//已经配对过的设备
TextView tvPaired = (TextView)findViewById(R.id.tv_paired);
tvPaired.setVisibility(View.VISIBLE);
lvPairedDevices.setVisibility(View.VISIBLE);
pairedDeviceArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
Log.i(TAG,"name:" + device.getName() + " address"+ device.getAddress());
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action){
// search finish
Log.i(TAG, "search finish!");
}
}
};
3.使用BlueAdatper搜索
使用bluetoothAdapter搜索设备,bluetoothAdapter.startDiscovery()在搜索过程中,系统会发出三个广播信息:
ACTION_DISCOVERY_START:开始搜索
ACTION_DISCOVERY_FINISHED:搜索结束
ACTION_FOUND:找到设备
@Override
public void onClick(View v) {
if (bluetoothAdapter.isDiscovering()) {
bluetoothAdapter.cancelDiscovery();
}
bluetoothAdapter.startDiscovery();
}
4.获取搜索到的蓝牙设备信息
在BroadcastReceiver的onReceive()里取得搜索到的蓝牙设备信息(如名称,MAC,RSSI)
5.通过蓝牙设备的MAC地址来建立一个BluetoothDevice对象:
BluetoothDevice romoteDevice = bluetoothAdapter.getRemoteDevice(mDeviceAddress);
6.由BluetoothDevice衍生BluetoothSocket
通过BluetoothSocket的createRfcommSocketToServiceRecord()方法来选择连接的协议/服务,这里用的是SPP(UUID:00001101-0000-1000-8000-00805F9B34FB)
try {
bluetoothSocket = romoteDevice.createRfcommSocketToServiceRecord(UUID.fromString(SPP_UUID));
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(this, "socket init failed", Toast.LENGTH_SHORT).show();
}
7.使用BluetoothSocket来连接、读写蓝牙设备
读写可以归到一个独立线程去实现~
try {
bluetoothSocket.connect();
Toast.makeText(this, "connect success", Toast.LENGTH_SHORT).show();
} catch (IOException e2) {
e2.printStackTrace();
Toast.makeText(this, "connect failed", Toast.LENGTH_SHORT).show();
try {
bluetoothSocket.close();
bluetoothSocket = null;
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(this, "socket close failed", Toast.LENGTH_SHORT).show();
}
return;
}
try {
inputStream = bluetoothSocket.getInputStream();
} catch (IOException e2) {
e2.printStackTrace();
Toast.makeText(this, "get inputstream failed", Toast.LENGTH_SHORT).show();
return;
}
try {
OutputStream os = bluetoothSocket.getOutputStream();
byte[] osBytes = etInput.getText().toString().getBytes();
for (int i = 0; i < osBytes.length; i++) {
if (osBytes[i] == 0x0a)
n++;
}
byte[] osBytesNew = new byte[osBytes.length+n];
n = 0;
for (int i = 0; i < osBytesNew.length; i++) {
//mobile "\n"is 0a,modify 0d 0a then send
if (osBytesNew[i] == 0x0a) {
osBytesNew[n] = 0x0d;
n++;
osBytesNew[n] = 0x0a;
}else {
osBytesNew[n] = osBytes[i];
}
n++;
}
os.write(osBytesNew);
} catch (Exception e) {
e.printStackTrace();
}