赞
踩
Android开发平台示例:BluetoothLeGatt
https://github.com/android/connectivity-samples/tree/main/BluetoothLeGatt/
1、设备是否支持蓝牙
- //获取蓝牙适配器
- BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
- if (mBluetoothAdapter == null) {
- // 说明此设备不支持蓝牙操作
- Log.d(TAG, "onCreate: 设备不支持蓝牙操作");
- Toast.makeText(this, "设备不支持蓝牙", Toast.LENGTH_SHORT).show();
- //如果应用必须有蓝牙,则退出应用
- finish();
- }
2、设备是否开启蓝牙,未开启则开启蓝牙
- // 检测蓝牙是否开启,开启蓝牙
- if (!mBluetoothAdapter.isEnabled()) {
- //未开启
- //开启蓝牙
- Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
- startActivityForResult(enableBtIntent, REQUEST_ENBLE_BT);
- //系统会弹出是否同意打开窗口,用户点击后会回调onActivityResult
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- if (requestCode == REQUEST_ENBLE_BT) {
- if (resultCode == RESULT_OK) {
- Toast.makeText(this, "点击了OK,蓝牙已经开启", Toast.LENGTH_SHORT).show();
- } else if (resultCode == RESULT_CANCELED) {
- Toast.makeText(this, "点击了取消,蓝牙没开启", Toast.LENGTH_SHORT).show();
- //如果应用必须开启蓝牙,则退出应用
- finish();
- }
- }
- }
3、权限申请
- AndroidManifest.xml 里面声明权限:
-
- <uses-permission android:name="android.permission.BLUETOOTH" />
- <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
- <uses-feature android:name="android.hardware.location.gps" />
-
- <!-- 打开位置权限。如果应用没有位置权限,蓝牙扫描功能不能使用,需要动态申请(Build.VERSION.SDK_INT < 23 不需要) -->
- <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
- <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
4、查询手机已配对的设备
- //通过 getBondedDevices() 来实现,这将返回表示已配对设备的一组 BluetoothDevice 。
- Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
- if (pairedDevices.size() > 0) {
- for (BluetoothDevice device : pairedDevices) {
- Log.d(TAG, device.getName() + " " + device.getAddress());
- }
- }
5、创建扫描器
- if (mBluetoothAdapter != null) {
- BluetoothLeScanner mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner(); //获取扫描器
- BluetoothLeScanner mSampleScanCallback = new SampleScanCallback(); //创建扫描回调
- //注意:扫描回调只能创建一次,关闭扫描的时候也要使用同一回调,不然不能停止
- }
-
- private class SampleScanCallback extends ScanCallback {
- @Override
- public void onScanResult(int callbackType, ScanResult result) {} //得到扫描的设备
- @Override
- public void onBatchScanResults(List<ScanResult> results) {}
- @Override
- public void onScanFailed(int errorCode) {}
- }
6、开始扫描
- //蓝牙设备开始扫描 注意:扫描只能开启一次,不然不能停止。(可能是开几次就要关几次,没有验证)
- private void bluetoothStartScanDevices() {
- if (mBluetoothLeScanner != null) {
- mBluetoothLeScanner.startScan(mSampleScanCallback);
- }
- }
7、停止扫描
- private void bluetoothStopScanDevices() {
- // 通过调用 BluetoothLeScanner.stopScan 可以停止正在进行的蓝牙扫描。
- // 这里需要注意的是,传入的回调必须是开启蓝牙扫描时传入的回调,否则蓝牙扫描不会停止。
- if (mBluetoothLeScanner != null) {
- mBluetoothLeScanner.stopScan(mSampleScanCallback);
- }
- }
8、创建服务类BluetootheService
,用服务来管理蓝牙的连接与通讯
- public class BluetoothLeService extends Service {
- private final IBinder mBinder = new LocalBinder();
-
- public class LocalBinder extends Binder {
- public BluetoothLeService getService() {
- return BluetoothLeService.this;
- }
- }
-
- @Override
- public IBinder onBind(Intent intent) {
- return mBinder;
- }
-
- @Override
- public boolean onUnbind(Intent intent) {
- close();
- return super.onUnbind(intent);
- }
- }
9、声明服务
- AndroidManifest.xml 里面声明服务:
- <application
- <service android:name=".BluetoothManage.BluetoothLeService" android:enabled="true"/>
10、绑定服务,在Activity
里绑定,此Activity将收到服务的通知,并进行数据交互
- Intent gattServiceIntent = new Intent(DevicesSearchActivity.this, BluetoothLeService.class);
- boolean isOK = bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE); //绑定失败检查AndroidManifest是否有声明
-
- private final ServiceConnection mServiceConnection = new ServiceConnection() {
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) { //与服务连接完成
- mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService();
- mBluetoothLeService.connect(mDeviceAddress);
- }
- @Override
- public void onServiceDisconnected(ComponentName name) { //与服务断开连接
- mBluetoothLeService = null;
- }
- };
11、在Activity里注册广播接收器,接收服务发出的广播,后面有里面的详细处理
- private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {}
- }
12、在服务类BluetootheService
里创建连接
- public boolean connect(final String address) {
- if (mBluetoothAdapter == null || address == null) { return false;}
- if (mBluetoothDeviceAddress != null && address.equals(mBluetoothDeviceAddress) && mBluetoothGatt != null) {
- if (mBluetoothGatt.connect()) { mConnectionState = STATE_CONNECTING; return true; } else { return false;}
- }
- final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
- if (device == null) { return false; }
- mBluetoothGatt = device.connectGatt(this, true, mGattCallback);
- return true;
- }
13、连接回调
- private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
- @Override
- public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { //连接状态改变调用
- String intentAction;
- if (newState == BluetoothProfile.STATE_CONNECTED) { //连接完成
- broadcastUpdate(ACTION_GATT_CONNECTED); //连接完成广播
- } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { //连接断开
- broadcastUpdate(ACTION_GATT_DISCONNECTED); //连接断开广播
- }
- }
- @Override
- public void onServicesDiscovered(BluetoothGatt gatt, int status) {
- if (status == BluetoothGatt.GATT_SUCCESS) { //连接完成后发现服务
- broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED); //发现服务广播
- }
- }
- @Override
- public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
- if (status == BluetoothGatt.GATT_SUCCESS) {
- broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic); //收到数据广播
- }
- }
-
- @Override
- public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
- broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic); //收到数据广播
- }
- };
14、在Activity里广播接收器的详细处理
- private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- final String action = intent.getAction();
- if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) { // 连接成功
- mConnectionState = STATE_CONNECTED;
- invalidateOptionsMenu();
- } else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) { // 断开连接
- mConnectionState = STATE_DISCONNECTED;
- invalidateOptionsMenu();
- } else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) { // 发现有可支持的服务//获取GATT服务 + UUID
- mBluetoothGattService = mBluetoothLeService.getSupportedGattServices(UUID.fromString(SampleGattAttributes.UUID_SERVICE));
- //根据GATT服务获取写数据端口 + UUID
- mWriteBluetoothGattCharacteristic = mBluetoothGattService.getCharacteristic(UUID.fromString(SampleGattAttributes.UUID_WRITE));
- //根据GATT服务获取读数据端口 + UUID
- mReadBluetoothGattCharacteristic = mBluetoothGattService.getCharacteristic(UUID.fromString(SampleGattAttributes.UUID_NOTIFY));
- //打开读取数据通道
- mBluetoothLeService.setCharacteristicNotification(mReadBluetoothGattCharacteristic, true);
- Log.d(TAG, "onReceive: 发现有可支持的服务");
- } else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) { //收到数据
- String dataStr = intent.getStringExtra(BluetoothLeService.EXTRA_DATA);
- Log.d(TAG, "onReceive: Data" + dataStr);
- writeDataToBluetooth(); //发送数据
- }
- }
- };
15、发送数据,在Activity
里
- public void writeDataToBluetooth() {
- byte[] WriteBytes = new byte[10];
- mWriteBluetoothGattCharacteristic.setValue(WriteBytes);
- mWriteBluetoothGattCharacteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
- mBluetoothLeService.writeCharacteristic(mWriteBluetoothGattCharacteristic);
- }
16、读取RSSI,在BluetoothLeService
服务类里
- mBluetoothGatt.readRemoteRssi();
-
- //readRemoteRssi读取信号强度函数调用后,在BluetoothGattCallback里回调
- @Override
- public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
- super.onReadRemoteRssi(gatt, rssi, status);
- Log.d(TAG, "onReadRemoteRssi: " + rssi);
- broadcastUpdateRSSI(ACTION_RSSI_VALUE, String.valueOf(rssi)); //广播发送给activity
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。