这里直接上代码吧,我这边的应用场景是,比如我扫描附近的体重秤,注意,我扫描的时候,需要过滤,只把扫描到的特定型号的,体重秤
显示出来,比如附近的手机,血压计等都不能扫描出来.同时比如如果有两台体重秤的话,一台离的近,一台离的远,我需要把
离得近的体重秤,在显示的时候,优先显示在上面.根据离扫描设备的距离,做个倒序排序:
这里有个不好的地方,就是,我是用扫描到的设备的蓝牙的名称来进行过滤的,比如体重秤的话,他这个型号的,的蓝牙名称都是以
QN- 开头的,我直接判断,我扫描到的蓝牙设备是否以QN-开头,如果是,就认为是我要的体重秤设备..
实际上,对于不同的设备,连接蓝牙等的操作,要么会提供特定的操作API,来扫描,要么会提供蓝牙的UUID,我们可以通过UUID来过滤.
后面会实现一个用这种方法过滤的版本,再发出来.
这个蓝牙设备的UUID,一般都是一种品牌的机器,是一个UUID,所以可以用UUID进行过滤蓝牙设备.
去看代码吧:
1.这个是MainActivity的onCreate方法,里面initView()方法不用管,
去看看这个initBluetooth方法,用来判断当前设备是否支持蓝牙.后面searchDevices()方法,先不用管,deviceNum也不用管.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_setting);
initView();
//初始化蓝牙设备:
initBluetooth();
//搜索蓝牙设备
//searchDevices();
//初始化蓝牙搜索设备编号
deviceNum ="0";
}
2.initBluetooth方法,可以看到这个方法,里面可以判断设备是否支持蓝牙
private void initBluetooth() {
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null) {
Toast.makeText(this, "此设备不支持蓝牙操作", Toast.LENGTH_LONG).show();
return;
}
}
3.然后,比如我们点击按钮的时候开始扫描.
@Override
public void onClick(View v) {
int id = v.getId();
if (id == R.id.set_btn_tzc) {
.....其他按钮点击处理
}else if(id == R.id.set_btn_ipset){
.....其他按钮点击处理事件
}else if(id == R.id.set_btn_search){
//判断用户是否未选择设备
if(deviceNum.equals("0")){
Toast.makeText(SettingActivity.this,"请选择先你要扫描的设备类型",Toast.LENGTH_SHORT).show();
return;
}
//1.显示正在扫描
BaseApplication.context().showDialog(SettingActivity.this, "正在扫描请稍后...");
final int[] deviceCount = {0};
macLists = new ArrayList<DeviceInfo>();
//定时器循环
final Timer scanTimer = new Timer();
TimerTask scanTask = new TimerTask(){
public void run() {
//Looper.prepare();
if((deviceCount[0] < macLists.size()) && (macLists.size()>0)){
//1.有新设备添加,记录设备数量
deviceCount[0] = macLists.size();
}else if((deviceCount[0] == macLists.size()) && (macLists.size() > 0)){
//2.已经没有新设备被扫描到,扫描结束
BaseApplication.context().closeDialog();
scanTimer.cancel();
//3.按照信号强度排序
Collections.sort(macLists, new ComparatorSort());
ArrayList<String> tempDeviceList = new ArrayList<>();
for (DeviceInfo macList : macLists) {
tempDeviceList.add(macList.getName()+"->"+macList.getAddress());
}
//搜索蓝牙设备按钮
//String[] items3 = new String[]{"苍老湿", "小泽老湿", "波多野结衣老湿", "吉泽明步老湿"};//创建item
final String[] items3 = (String[]) tempDeviceList.toArray(new String[tempDeviceList.size()]);//创建item
new Thread(){
@Override
public void run() {
Looper.prepare();
alertDialog alertDialog3 = new AlertDialog.Builder(SettingActivity.this)
.setTitle("扫描设备列表:")
.setIcon(R.mipmap.ic_launcher)
.setItems(items3, new DialogInterface.OnClickListener() {//添加列表
@Override
public void onClick(DialogInterface dialogInterface, int i) {
//Toast.makeText(SettingActivity.this, "点的是:" + items3[i], Toast.LENGTH_SHORT).show();
//EditText mac_edit_text = findViewById(R.id.set_edittext_mac);
//获取mac地址
//mac_edit_text.setText(items3[i]);
Message message=new Message();
Bundle bundle=new Bundle();
bundle.putString("deviceMac", items3[i]);
message.setData(bundle);//b
message.what = 310;
setMacHandler.sendMessage(message);
}
})
.create();
alertDialog3.show();
alertDialog3.getWindow().setLayout(1600,800);
Looper.loop();
}
}.start();
}else if(macLists.size() == 0 ){
BaseApplication.context().closeDialog();
scanTimer.cancel();
//Toast.makeText(this,"121",Toast.LENGTH_SHORT).show();
new Thread(){
@Override
public void run() {
Looper.prepare();
Toast.makeText(SettingActivity.this, "未扫描到设备", Toast.LENGTH_SHORT).show();
Looper.loop();
}
}.start();
}
//Looper.loop();
}
};
scanTimer.schedule(scanTask,8000,5000);
//这里就是说,点击按钮以后,接着去扫描蓝牙设备,先去扫描8秒钟,
//然后去判断扫描到了多少设备,然后每隔5秒钟判断是否又扫描到了新设备
//如果没有新设备被扫描到了,这个时候取消timer,停止扫描,用一个alertDialog
//来显示结果,并且把离扫描设备近的设备排序到前面.
searchDevices(); //这里开始扫描蓝牙设备
}
}
4.然后再去看蓝牙扫描方法,searchDevices()
private void searchDevices() {
// 3、创建自定义蓝牙服务对象
// 注册Receiver来获取蓝牙设备相关的结果
IntentFilter intent = new IntentFilter("android.bluetooth.device.action.UUID");
intent.addAction(BluetoothDevice.ACTION_FOUND); // 用BroadcastReceiver来取得搜索结果
intent.addAction(BluetoothDevice.EXTRA_UUID);
intent.addAction(BluetoothDevice.ACTION_UUID);
intent.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
intent.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
intent.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
intent.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
registerReceiver(lk_hxq_searchDevices, intent);
bluetoothAdapter.startDiscovery();
//BaseApplication.context().showDialog(SettingActivity.this, "正在连接设备...");
}
5.这里lk_hxq_searchDevices()就是扫描蓝牙设备的具体方法了
//2.搜索力康呼吸器设备
private BroadcastReceiver lk_hxq_searchDevices = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
//commLock.lock();
if (action.equals(BluetoothDevice.ACTION_FOUND)) { //found device
BluetoothDevice device = intent
.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String uuid = "";
Log.e("Adress001_Address:",device.getAddress());
Log.e("Adress001_Name:",device.getName()+"");
Log.e("Adress001_Type:",device.getType()+"");
if(device.getUuids()!=null){
ParcelUuid[] uudis = device.getUuids();
for (ParcelUuid uudi : uudis) {
uuid = uuid + uudi.toString();
}
}
Log.e("Adress001_UUID:",uuid+"");
//String deviceAddress = device.getName()+"->"+device.getAddress();
String deviceAddress = "";
String deviceName ="";
double deviceSignal = 0.0;
boolean isFind = false;
if(deviceNum.equals("0")){
isFind = false;
deviceName = "未知设备";
//deviceAddress = "未知设备->"+ device.getAddress();
deviceAddress = device.getAddress();
}else if(deviceNum.equals("1") && device.getName()!=null && device.getName().toString().startsWith("QN-")){
isFind = true;
deviceName = "体重秤";
//deviceAddress = "体重秤->"+ device.getAddress();
deviceAddress = device.getAddress();
}else if(deviceNum.equals("2") && device.getName()!=null && device.getName().toString().startsWith("BPM-")){
isFind = true;
deviceName = "血压计";
//deviceAddress = "血压计->"+ device.getAddress();
deviceAddress = device.getAddress();
}else if(deviceNum.equals("3") && device.getName()!=null && device.getName().toString().startsWith("BLE Device-")){
isFind = true;
deviceName = "血压计";
//deviceAddress = "三合一->"+ device.getAddress();
deviceAddress = device.getAddress();
}else if(deviceNum.equals("4") && device.getName()!=null && device.getName().toString().startsWith("B20")){
isFind = true;
deviceName = "呼吸器";
//deviceAddress = "呼吸器->"+ device.getAddress();
deviceAddress = device.getAddress();
}else if(deviceNum.equals("5") && device.getName()!=null && device.getName().toString().startsWith("weixin-")){
isFind = true;
deviceName = "握力球";
//deviceAddress = "握力球->"+ device.getAddress();
deviceAddress = device.getAddress();
}else if(deviceNum.equals("6") && device.getName()!=null && device.getName().toString().startsWith("PC80B-")){
isFind = true;
deviceName = "握力球";
//deviceAddress = "心电仪->"+ device.getAddress();
deviceAddress = device.getAddress();
}else if(deviceNum.equals("7")){
deviceName = "未知设备";
//deviceAddress = "未知设备->"+ device.getAddress();
deviceAddress = device.getAddress();
}else if(deviceNum.equals("8")){
deviceName = "未知设备";
//deviceAddress = "未知设备->"+ device.getAddress();
deviceAddress = device.getAddress();
}else{
isFind = false;
}
//找到检测设备以后,添加到设备列表中去
if(isFind){
if(macLists.contains(deviceAddress)){
}else{
//获取蓝牙信号强度,信号强度强的放在前面
//添加到列表
short rssi = intent.getExtras().getShort(
BluetoothDevice.EXTRA_RSSI);
int iRssi = abs(rssi);
// 将蓝牙信号强度换算为距离
double power = (iRssi - 59) / 25.0;
deviceSignal = power;
//macLists.add(device.getAddress());
DeviceInfo deviceInfo = new DeviceInfo();
deviceInfo.setAddress(deviceAddress);
deviceInfo.setName(deviceName);
deviceInfo.setSignal(deviceSignal);
macLists.add(deviceInfo);
}
}else{}
mBluetoothGatt = device.connectGatt(SettingActivity.this, false, gattCallback);
} else if (BluetoothDevice.ACTION_UUID.equals(action)) {
BluetoothDevice device = intent
.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
//String deviceAddress = device.getName()+"->"+device.getAddress();
String deviceAddress = "";
String deviceName ="";
double deviceSignal = 0.0;
boolean isFind = false;
if(deviceNum.equals("0")){
isFind = false;
deviceName = "未知设备";
//deviceAddress = "未知设备->"+ device.getAddress();
deviceAddress = device.getAddress();
}else if(deviceNum.equals("1") && device.getName()!=null && device.getName().toString().startsWith("QN-")){
isFind = true;
deviceName = "体重秤";
//deviceAddress = "体重秤->"+ device.getAddress();
deviceAddress = device.getAddress();
}else if(deviceNum.equals("2") && device.getName()!=null && device.getName().toString().startsWith("BPM-")){
isFind = true;
deviceName = "血压计";
//deviceAddress = "血压计->"+ device.getAddress();
deviceAddress = device.getAddress();
}else if(deviceNum.equals("3") && device.getName()!=null && device.getName().toString().startsWith("BLE Device-")){
isFind = true;
deviceName = "血压计";
//deviceAddress = "三合一->"+ device.getAddress();
deviceAddress = device.getAddress();
}else if(deviceNum.equals("4") && device.getName()!=null && device.getName().toString().startsWith("B20")){
isFind = true;
deviceName = "呼吸器";
//deviceAddress = "呼吸器->"+ device.getAddress();
deviceAddress = device.getAddress();
}else if(deviceNum.equals("5") && device.getName()!=null && device.getName().toString().startsWith("weixin-")){
isFind = true;
deviceName = "握力球";
//deviceAddress = "握力球->"+ device.getAddress();
deviceAddress = device.getAddress();
}else if(deviceNum.equals("6") && device.getName()!=null && device.getName().toString().startsWith("PC80B-")){
isFind = true;
deviceName = "握力球";
//deviceAddress = "心电仪->"+ device.getAddress();
deviceAddress = device.getAddress();
}else if(deviceNum.equals("7")){
deviceName = "未知设备";
//deviceAddress = "未知设备->"+ device.getAddress();
deviceAddress = device.getAddress();
}else if(deviceNum.equals("8")){
deviceName = "未知设备";
//deviceAddress = "未知设备->"+ device.getAddress();
deviceAddress = device.getAddress();
}else{
isFind = false;
}
//找到检测设备以后,添加到设备列表中去
if(isFind){
if(macLists.contains(deviceAddress)){
}else{
//获取蓝牙信号强度,信号强度强的放在前面
//添加到列表
short rssi = intent.getExtras().getShort(
BluetoothDevice.EXTRA_RSSI);
int iRssi = abs(rssi);
// 将蓝牙信号强度换算为距离
double power = (iRssi - 59) / 25.0;
deviceSignal = power;
//macLists.add(device.getAddress());
DeviceInfo deviceInfo = new DeviceInfo();
deviceInfo.setAddress(deviceAddress);
deviceInfo.setName(deviceName);
deviceInfo.setSignal(deviceSignal);
macLists.add(deviceInfo);
}
}else{}
mBluetoothGatt = device.connectGatt(SettingActivity.this, false, gattCallback);
}
}
};
6.扫描到了设备以后,然后会走到,扫描到设备以后的回调函数中去,
然后在回调函数中,可以判断,扫描到的设备具体是不是某个设备,比如判断是不是体重秤,或者是什么设备,这里通过UUID过滤,
不过因为上面我通过蓝牙的名称过滤的,所以我这里就没用到,但是我没有删除代码,实际上是可以通过这种方式过滤的,而且
正常情况下,通过这种方式过滤比较好,因为如果通过蓝牙名称过滤,蓝牙名称如果被修改了,或者有重名的,就会导致,程序,列出
的设备列表不太准确了.
注释掉的部分不用关注,用的时候删除就可以了.
Handler mainHandler = new Handler();
private BluetoothGattCallback gattCallback = new BluetoothGattCallback() {
// 这里有9个要实现的方法,看情况要实现那些,用到那些就实现那些
//当连接状态发生改变的时候
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, final int newState) {
mBluetoothGatt.discoverServices();
mainHandler.post(new Runnable() {
@Override
public void run() {
if (newState == BluetoothProfile.STATE_CONNECTED) {
// lk_fgn_msg.setText("连接成功,请操作设备测量");
// xyy_start.setVisibility(View.GONE);
// fgn_sub.setVisibility(View.GONE);
//lk_hxq_deviceOnline = true;
System.out.println("onConnectionStateChange连接成功");
//BaseApplication.context().closeDialog();
//ToastUtils.toast(SettingActivity.this,"设备启动成功");
} else {
//msg = null;
//ToastUtils.toast(FaceBodyCheckActivity.this,"点击开始测量");
// lk_fgn_msg.setText("点击开始测量");
// fgn_sub.setVisibility(View.VISIBLE);
// fgn_start.setVisibility(View.VISIBLE);
//lk_hxq_deviceOnline = false;
//BaseApplication.context().closeDialog();
System.out.println("onConnectionStateChange连接断开");
//Toast.makeText(SettingActivity.this, "设备连接已断开", Toast.LENGTH_SHORT).show();
}
}
});
}
//回调响应特征写操作的结果。
@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
System.out.println(status);
if (status == BluetoothGatt.GATT_SUCCESS) {
System.out.println("onCharacteristicWrite: 写入成功");
} else {
System.out.println("onCharacteristicWrite: 失败");
}
}
//回调响应特征读操作的结果。
@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
System.out.println(3333333);
}
//当服务被发现的时候回调的结果
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
try {
//设置serviceUUID,原型是:BluetoothGattService bluetoothGattService = bluetoothGatt.getService(UUID.fromString(SERVICESUUID));
bluetoothGattService = mBluetoothGatt.getService(UUID.fromString(DeviceFinal.LK_HXQ_SERVICESUUID));
//设置写入特征UUID,原型是:BluetoothGattCharacteristic writeCharacteristic = bluetoothGattService.getCharacteristic(UUID.fromString(WRITEUUID));
writeCharacteristic = bluetoothGattService.getCharacteristic(UUID.fromString(DeviceFinal.LK_HXQ_WRITEUUID));
//设置监听特征UUID,原型是:BluetoothGattCharacteristic notifyCharacteristic = bluetoothGattService.getCharacteristic(UUID.fromString(NOTIFYUUID));
notifyCharacteristic = bluetoothGattService.getCharacteristic(UUID.fromString(DeviceFinal.LK_HXQ_NOTIFYUUID));
//开启监听
//lk_hxq_resultValue = new ArrayList<>();
boolean notification = gatt.setCharacteristicNotification(notifyCharacteristic, true);
// if (notification) {
// List<BluetoothGattDescriptor> descriptorList = notifyCharacteristic.getDescriptors();
// if (descriptorList != null && descriptorList.size() > 0) {
// for (BluetoothGattDescriptor descriptor : descriptorList) {
// descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
// mBluetoothGatt.writeDescriptor(descriptor);
// }
// }
// }
// int properties = notifyCharacteristic.getProperties();//16
// System.out.println(notification + "" + properties);
} catch (Exception e) {
e.printStackTrace();
mainHandler.post(new Runnable() {
@Override
public void run() {
// fgn_start.setVisibility(View.GONE);
// fgn_sub.setVisibility(View.GONE);
// lk_fgn_msg.setText("所选设备不是呼吸器,请确认后再试!");
//ToastUtils.toast(SettingActivity.this,"所选设备不是呼吸器,请确认后再试!");
System.out.println("所选设备不是呼吸器,请确认后再试!");
}
});
}
}
//接受数据回调
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
byte[] value = characteristic.getValue();
//final String str = lk_hxq_bytesToHex(value);
//System.out.println(str);
//lk_hxq_resultValue.add(str);
mainHandler.post(new Runnable() {
@Override
public void run() {
//lk_hxq_fgn();
}
// xyz.setText("spo2:" + new BigInteger(spo2, 16) + '%' + " pr:" + new BigInteger(pr, 16) + "次/分");
});
}
//当连接能被被读的操作
@Override
public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
super.onDescriptorRead(gatt, descriptor, status);
System.out.println(555555);
}
};
7.然后过程中,还用到一个实体类,用来封装蓝牙设备的,信号强度,蓝牙设备的名称,以及蓝牙设备的mac地址的.
DeviceInfo.java
package com.baidu.idl.main.facesdk.utils;
public class DeviceInfo {
private String name;
private String address;
private double signal;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public double getSignal() {
return signal;
}
public void setSignal(double signal) {
this.signal = signal;
}
}
放在这里了.
最新评论