一 蓝牙开启
首先需要获取系统的蓝牙适配器,如果适配器不为空且没有开启的话,通过intent进行开启操作,相关代码如下:
BluetoothAdapter blueadapter = BluetoothAdapter.getDefaultAdapter(); if (blueadapter != null) { //Device support Bluetooth //确认开启蓝牙 if (!blueadapter.isEnabled()) { //请求用户开启 Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(intent, RESULT_FIRST_USER); //使蓝牙设备可见,方便配对 Intent in = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); in.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 200); startActivity(in); //直接开启,不经过提示 // blueadapter.enable(); } }
二 设备搜索
主动发起搜索:
blueadapter.startDiscovery()
获取配对过的蓝牙设备:
Set<BluetoothDevice> device = blueadapter.getBondedDevices(); data.clear(); if (blueadapter != null && blueadapter.isDiscovering()) { adapter.notifyDataSetChanged(); } if (device.size() > 0) { //存在已经配对过的蓝牙设备 for (Iterator<BluetoothDevice> it = device.iterator(); it.hasNext(); ) { BluetoothDevice btd = it.next(); blueadapter.getProfileConnectionState(BluetoothProfile.A2DP); data.add(btd); } } else { //不存在已经配对过的蓝牙设备 }
需要注意的是服务端的蓝牙设备类型要与BluetoothProfile.A2DP统一
三 状态监听
首先先注册广播:
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); filter.addAction(ACTION_STATE_CHANGED); filter.addAction(ACTION_DISCOVERY_FINISHED); registerReceiver(receiver, filter);
编写广播类:
private DeviceReceiver receiver = new DeviceReceiver();
private class DeviceReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); Logd("-----------DeviceReceiver:"+action); if (BluetoothDevice.ACTION_FOUND.equals(action)) { //搜索到新设备 // data.clear(); BluetoothDevice btd = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); //搜索没有配过对的蓝牙设备 if (btd.getBondState() != BluetoothDevice.BOND_BONDED) { data.add(btd); adapter.notifyDataSetChanged(); } } else if (ACTION_DISCOVERY_FINISHED.equals(action)) { //搜索结束 if (binding.listview.getCount() == 0) { adapter.notifyDataSetChanged(); } } else if (action.equals(ACTION_STATE_CHANGED)) { int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR); switch (state) { case BluetoothAdapter.STATE_OFF: Log.d("aaa", "STATE_OFF 手机蓝牙关闭"); binding.tvState.setText(R.string.tip_bluetooth_close); break; case BluetoothAdapter.STATE_TURNING_OFF: Log.d("aaa", "STATE_TURNING_OFF 手机蓝牙正在关闭"); break; case BluetoothAdapter.STATE_ON: Log.d("aaa", "STATE_ON 手机蓝牙开启"); binding.tvState.setText(R.string.tip_bluetooth_open); search(null); break; case BluetoothAdapter.STATE_TURNING_ON: Log.d("aaa", "STATE_TURNING_ON 手机蓝牙正在开启"); findAvalibleDevice(); break; } } } }
四 蓝牙通信
服务端
蓝牙Server端就是通过线程来注册一个具有名称和唯一识别的UUID号的BluetoothServerSocket, 然后就一直监听Client端(BluetoothSocket)的请求,并对这些请求做出相应的处理。
// 注册蓝牙Server
/* 创建一个蓝牙服务器 * 参数分别:服务器名称、UUID */ mserverSocket = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(PROTOCOL_SCHEME_RFCOMM, UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
参数PROTOCOL_SCHEME_RFCOMM是一个String类型的常量,表示蓝牙Server的名称,而UUID.fromString()表示蓝牙Server的唯一标识UUID。
在Client连接到Server时需要使用该UUID号。
// 接收Client的连接请求
socket = mserverSocket.accept();
// 处理接收内容
//读取数据 private class readThread extends Thread { @Override public void run() { byte[] buffer = new byte[1024]; int bytes; InputStream mmInStream = null; try { mmInStream = socket.getInputStream(); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } while (true) { try { // Read from the InputStream if( (bytes = mmInStream.read(buffer)) > 0 ) { byte[] buf_data = new byte[bytes]; for(int i=0; i<bytes; i++) { buf_data[i] = buffer[i]; } String s = new String(buf_data); Message msg = new Message(); msg.obj = s; msg.what = 1; LinkDetectedHandler.sendMessage(msg); } } catch (IOException e) { try { mmInStream.close(); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } break; } } } }
客户端
客户端连接时需要知道服务端的UUID号,代码如下:
socket = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB")); socket.connect();
发送数据
if (socket == null) { Toast.makeText(mContext, "没有连接", Toast.LENGTH_SHORT).show(); return; } try { OutputStream os = socket.getOutputStream(); os.write(msg.getBytes()); } catch (IOException e) { e.printStackTrace(); }