1.扫描设备
bluetoothAdapter.startLeScan(scaleCallback); handler.postDelayed(new Runnable() { @Override public void run() { bluetoothAdapter.stopLeScan(scaleCallback); progressbar.setVisibility(View.GONE); } },10000);
扫描结果的回调
//扫描到设备之后的回调方法 private BluetoothAdapter.LeScanCallback scaleCallback = new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) { if(device.getName()!=null && device.getAddress()!=null) { runOnUiThread(new Runnable() { @Override public void run() { final BlueToothItemBean bean = new BlueToothItemBean(); bean.blueToothDevie_Name = device.getName(); bean.blueToothDevie_Adress = device.getAddress(); if(BlueToothDevice_Info.contains(bean)) { //如果集合中已经包含相同的对象,则不添加进去 }else{ BlueToothDevice_Info.add(bean); bluetoothDevices.add(device); adapter.notifyDataSetChanged(); } } }); } } };
2,既然获取到了mac地址那么就可以进行连接了
device = bluetoothAdapter.getRemoteDevice(deviceInfo.blueToothDevie_Adress); bluetoothGatt = device.connectGatt(showBluetoothInfoActivity.this,false,callback);
连接结果的回调
BluetoothGattCallback callback = new BluetoothGattCallback() { @Override public void onConnectionStateChange(BluetoothGatt gatt, final int status, int newState) { super.onConnectionStateChange(gatt, status, newState); //连接状态 e("linxin", "onConnectionStateChange: status="+status+"----newState:"+newState ); final String statusStr2; String statusStr = "status="+status+"---newStatus"+newState+"---"; if(newState == BluetoothProfile.STATE_CONNECTED){ statusStr = statusStr+"连接成功"; statusStr = statusStr; statusStr2 = statusStr; //发现服务 bluetoothGatt.discoverServices(); runOnUiThread(new Runnable() { @Override public void run(){ Toast.makeText(showBluetoothInfoActivity.this,"连接成功",Toast.LENGTH_SHORT); deviceStatusTv.setText("连接成功"); tv_Connectinfo.setText(tv_Connectinfo.getText()+"------------------------------"+ statusStr2); } }); }else if(newState==BluetoothProfile.STATE_DISCONNECTED){ statusStr = statusStr+"连接失败"; statusStr2 = statusStr; runOnUiThread(new Runnable() { @Override public void run(){ Toast.makeText(showBluetoothInfoActivity.this,"连接失败",Toast.LENGTH_SHORT); deviceStatusTv.setText("连接失败"); tv_Connectinfo.setText(tv_Connectinfo.getText()+"\\n"+ statusStr2); } }); if(deviceInfo.blueToothDevie_Adress!=null){ connect(); //继续连接 } } }
连接之后发现服务的回调
//服务方法回调 @Override public void onServicesDiscovered(BluetoothGatt gatt, int status) { super.onServicesDiscovered(gatt, status); if(status == BluetoothGatt.GATT_SUCCESS){ e("linxin", "onServicesDiscovered: 发现服务" ); bluetoothGattService = bluetoothGatt.getService(UUID.fromString("0000fff0-0000-1000-8000-00805f9b34fb")); bluetoothGattCharacteristic = bluetoothGattService.getCharacteristic(UUID.fromString("0000fff1-0000-1000-8000-00805f9b34fb")); }else{ //没有发现服务 e("linxin", "onServicesDiscovered: 没有发现服务" ); } }
3通过获取到的服务和特征值发送消息
byte[] value = new byte[20]; value[0] = (byte) 0x66; value[1] = (byte) 0X01; value[2] = (byte) 0XA1; int sum = 0; for (int i = 0; i < 19; i++) { if (value[i] >= 0) { sum = sum + value[i]; } else { sum = sum + 256 + value[i]; } } value[19] = (byte) (sum % 256);
bluetoothGattCharacteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT);bluetoothGattCharacteristic.setValue(value) ; // 将设置好的特征发送出去 bluetoothGatt.writeCharacteristic( bluetoothGattCharacteristic) ; // 已经发设置好的特征发出
写入数据成功的回调
//发送之后的回调 @Override public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { super.onCharacteristicWrite(gatt, characteristic, status); if(status==BluetoothGatt.GATT_SUCCESS){ //写入成功 e("linxin", "onCharacteristicWrite:写入成功 " ); }else if(status == BluetoothGatt.GATT_FAILURE){ //失败 e("linxin", "onCharacteristicWrite:写入失败 " ); }else if(status ==BluetoothGatt.GATT_WRITE_NOT_PERMITTED){ //没有写入权限 e("linxin", "onCharacteristicWrite:没有写入成功 " ); } }
当指定特征值改变的时候
//当指定特征值改变的时候调用 @Override public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { super.onCharacteristicChanged(gatt, characteristic); e("linxin", "onCharacteristicChanged: 特征值改变" ); }
@Override public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { super.onCharacteristicRead(gatt, characteristic, status); e(TAG, "onCharacteristicRead:被调用 " ); }
下面是连接,获取服务特征值,发送消息进行绑定,并且设置特征值有通知的完整代码
public class showBluetoothInfoActivity extends AppCompatActivity implements View.OnClickListener { private static final String TAG = "linxin"; private TextView deviceNameTV, deviceAddressTV, deviceStatusTv; private TextView tv_Connectinfo; private Button Btn_SBI_connectDevice,tv_sendMessage; private BlueToothItemBean deviceInfo; //设备的信息 private String deviceName; //设备的名字 private String deviceAddress; //设备的mac地址 private ServiceConnection serviceConnection; private BluetoothManager bluetoothManager; private BluetoothAdapter bluetoothAdapter; private String position; private BlueToothService.Mybinder mybinder; Intent startServiceIntent;//用于启动服务 //listview对应的device // List<BluetoothDevice> bluetoothDevices; //获得单一的device】 BluetoothDevice device ; BluetoothGatt bluetoothGatt; BluetoothGattService bluetoothGattService ; //BLe的服务 BluetoothGattCharacteristic bluetoothGattCharacteristic; //特征 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_show_bluetooth_info); Bundle bundle = getIntent().getBundleExtra("device"); deviceInfo = (BlueToothItemBean) bundle.get("device"); // this.position = getIntent().getStringExtra("position"); // bluetoothDevices = new GetDevice().getDevice(); // Log.e("linxin", "onCreate: ----" + (bluetoothDevices == null)); initData(); initView(); initEvent(); deviceNameTV.setText(deviceInfo.blueToothDevie_Name); deviceAddressTV.setText(deviceInfo.blueToothDevie_Adress); deviceStatusTv.setText("没连接"); serviceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { mybinder = (BlueToothService.Mybinder) service; } @Override public void onServiceDisconnected(ComponentName name) { } }; //启动服务 /* startServiceIntent = new Intent(this, BlueToothService.class); bindService(startServiceIntent, serviceConnection, BIND_AUTO_CREATE);*/ } private void initData() { bluetoothManager = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE); bluetoothAdapter = bluetoothManager.getAdapter(); } private void initEvent() { Btn_SBI_connectDevice.setOnClickListener(this); tv_sendMessage.setOnClickListener(this); } private void initView() { deviceNameTV = (TextView) findViewById(R.id.device_Name); deviceAddressTV = (TextView) findViewById(R.id.device_Address); deviceStatusTv = (TextView) findViewById(R.id._Statusing); Btn_SBI_connectDevice = (Button) findViewById(R.id.btn_sbi_connectDevice); tv_Connectinfo = (TextView) findViewById(R.id.tv_connectinfo); tv_sendMessage = (Button) findViewById(R.id.tv_sendMessage); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_sbi_connectDevice: //连接设备 //device.connectGatt(showBluetoothInfoActivity.this,false,callback); connect(); break; case R.id.tv_sendMessage: //设备连接后,发现服务, //发送信息进行绑定 Log.e("linxin", "onClick:点击 " ); byte[] value = new byte[20]; value[0] = (byte) 0x66; value[1] = (byte) 0X01; value[2] = (byte) 0XA1; int sum = 0; for (int i = 0; i < 19; i++) { if (value[i] >= 0) { sum = sum + value[i]; } else { sum = sum + 256 + value[i]; } } value[19] = (byte) (sum % 256); bluetoothGattCharacteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT); bluetoothGattCharacteristic.setValue(value); //BluetoothGattService service = bluetoothGatt.getService(UUID.fromString("0000fff0-0000-1000-8000-00805f9b34fb")); // BluetoothGattCharacteristic characteri = service.getCharacteristic( UUID.fromString("0000fff1-0000-1000-8000-00805f9b34fb")); //BluetoothGattDescriptor desc = characteri.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb")); setCharactoristicNotifyAndWriteDescriptor( UUID.fromString("0000fff0-0000-1000-8000-00805f9b34fb"), UUID.fromString("0000fff1-0000-1000-8000-00805f9b34fb"), UUID.fromString("00002902-0000-1000-8000-00805f9b34fb") ); //将设置好的特征发送出去 bluetoothGatt.writeCharacteristic(bluetoothGattCharacteristic); //已经发设置好的特征发出 break; } } private void setCharactoristicNotifyAndWriteDescriptor(UUID uuidService, UUID uuidCharacter, UUID uuid_descriptor) { //获得设备的特征 if (bluetoothGatt != null && bluetoothGattCharacteristic != null) { bluetoothGatt.setCharacteristicNotification(bluetoothGattCharacteristic, true); BluetoothGattDescriptor bluetoothGattDescriptor = bluetoothGattCharacteristic.getDescriptor(uuid_descriptor); if (bluetoothGattDescriptor != null) { bluetoothGattDescriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); //descriptor 写入操作 bluetoothGatt.writeDescriptor(bluetoothGattDescriptor); } } } //连接 private void connect(){ device = bluetoothAdapter.getRemoteDevice(deviceInfo.blueToothDevie_Adress); bluetoothGatt = device.connectGatt(showBluetoothInfoActivity.this,false,callback); } @Override protected void onDestroy() { super.onDestroy(); unbindService(serviceConnection); } BluetoothGattCallback callback = new BluetoothGattCallback() { @Override public void onConnectionStateChange(BluetoothGatt gatt, final int status, int newState) { super.onConnectionStateChange(gatt, status, newState); //连接状态 e("linxin", "onConnectionStateChange: status="+status+"----newState:"+newState ); final String statusStr2; String statusStr = "status="+status+"---newStatus"+newState+"---"; if(newState == BluetoothProfile.STATE_CONNECTED){ statusStr = statusStr+"连接成功"; statusStr = statusStr; statusStr2 = statusStr; //发现服务 bluetoothGatt.discoverServices(); runOnUiThread(new Runnable() { @Override public void run(){ Toast.makeText(showBluetoothInfoActivity.this,"连接成功",Toast.LENGTH_SHORT); deviceStatusTv.setText("连接成功"); tv_Connectinfo.setText(tv_Connectinfo.getText()+"------------------------------"+ statusStr2); } }); }else if(newState==BluetoothProfile.STATE_DISCONNECTED){ statusStr = statusStr+"连接失败"; statusStr2 = statusStr; runOnUiThread(new Runnable() { @Override public void run(){ Toast.makeText(showBluetoothInfoActivity.this,"连接失败",Toast.LENGTH_SHORT); deviceStatusTv.setText("连接失败"); tv_Connectinfo.setText(tv_Connectinfo.getText()+"\\n"+ statusStr2); } }); if(deviceInfo.blueToothDevie_Adress!=null){ connect(); //继续连接 } } } //服务方法回调 @Override public void onServicesDiscovered(BluetoothGatt gatt, int status) { super.onServicesDiscovered(gatt, status); if(status == BluetoothGatt.GATT_SUCCESS){ e("linxin", "onServicesDiscovered: 发现服务" ); bluetoothGattService = bluetoothGatt.getService(UUID.fromString("0000fff0-0000-1000-8000-00805f9b34fb")); bluetoothGattCharacteristic = bluetoothGattService.getCharacteristic(UUID.fromString("0000fff1-0000-1000-8000-00805f9b34fb")); }else{ //没有发现服务 e("linxin", "onServicesDiscovered: 没有发现服务" ); } } //发送之后的回调 @Override public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { super.onCharacteristicWrite(gatt, characteristic, status); if(status==BluetoothGatt.GATT_SUCCESS){ //写入成功 e("linxin", "onCharacteristicWrite:写入成功 " ); }else if(status == BluetoothGatt.GATT_FAILURE){ //失败 e("linxin", "onCharacteristicWrite:写入失败 " ); }else if(status ==BluetoothGatt.GATT_WRITE_NOT_PERMITTED){ //没有写入权限 e("linxin", "onCharacteristicWrite:没有写入成功 " ); } } //当指定特征值改变的时候调用 @Override public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { super.onCharacteristicChanged(gatt, characteristic); e("linxin", "onCharacteristicChanged: 特征值改变" ); } @Override public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { super.onCharacteristicRead(gatt, characteristic, status); e(TAG, "onCharacteristicRead:被调用 " ); } }; }
//当指定特征值改变的时候调用
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
super.onCharacteristicChanged(gatt, characteristic);
e("linxin", "onCharacteristicChanged: 特征值改变" );
//发消息前我们要设置当某个特征值改变的时候有通知,然后我们给该特征发送信息,当我们发送信息后,特征值发生改变返回数据
//我们可以在这里获取返回的值
Log.e(TAG, "onCharacteristicChanged: "+characteristic.getUuid() );
/* if(characteristic.getUuid().equals("0000fff1-0000-1000-8000-00805f9b34fb")){
Log.e("linxin", "onCharacteristicChanged:相等 ");
}*/
byte[] bytes= characteristic.getValue();
Log.e(TAG, "onCharacteristicChanged: " + Arrays.toString(bytes)); //这就是BLE设备返回的数据
for(int i = 0 ; i <bytes.length;i++){
Log.e(TAG, "bytes[i]: ===="+bytes[i]); //打印时会自动把16进制转换成10进制,如果有负数各位大佬就要小心了
}
//下面的就看你的需求了。。。。。。。
/*
* 一个字节占8位,最大表示到256
* */
//BLE给我们返回的一般是16进制,我们如何把返回的16进制 打印出的int类型转换为16进制呢?
//这个也是我在群里问dalao的
for(int i = 0 ;i<bytes.length;i++){
Log.e("linxin", "byte---16进制输出: "+String.format("0x%02x",(byte)bytes[i]));
}
}
BluetoothGattCallback
BluetoothGattCallback一共有9个方法,那么只有当你调用或者和连接的设备发生互动的时候,他的与之对应的方法才会回调,下面就是方法的对应
notification对应onCharacteristicChanged;gatt.setCharacteristicNotification(characteristic, true);
readCharacteristic对应onCharacteristicRead;gatt.readCharacteristic(characteristic);
writeCharacteristic对应onCharacteristicWrite;gatt.wirteCharacteristic(mCurrentcharacteristic);
连接蓝牙或者断开蓝牙 对应 onConnectionStateChange;
readDescriptor对应onDescriptorRead;
writeDescriptor对应onDescriptorWrite;gatt.writeDescriptor(descriptor);
readRemoteRssi对应onReadRemoteRssi;gatt.readRemoteRssi()
executeReliableWrite对应onReliableWriteCompleted;
discoverServices对应onServicesDiscoveredgatt.discoverServices()