Android蓝牙开发与串口蓝牙通讯

Android APP实现与串口蓝牙模块通讯,单次接收20bytes,发送10bytes

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
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值