您的位置 首页 java

AndroidStudio安卓原生开发_Android扫描指定蓝牙设备_并计算距离

这里直接上代码吧,我这边的应用场景是,比如我扫描附近的体重秤,注意,我扫描的时候,需要过滤,只把扫描到的特定型号的,体重秤

显示出来,比如附近的手机, 血压计 等都不能扫描出来.同时比如如果有两台体重秤的话,一台离的近,一台离的远,我需要把

离得近的体重秤,在显示的时候,优先显示在上面.根据离扫描设备的距离,做个倒序排序:

这里有个不好的地方,就是,我是用扫描到的设备的 蓝牙 的名称来进行过滤的,比如体重秤的话,他这个型号的,的蓝牙名称都是以

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();
                                 alert Dialog 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来获取蓝牙设备相关的结果
         Intent Filter intent = new IntentFilter("android.bluetooth.device.action.UUID");
        intent.addAction( Bluetooth Device.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;
    }
}
  

放在这里了.

文章来源:智云一二三科技

文章标题:AndroidStudio安卓原生开发_Android扫描指定蓝牙设备_并计算距离

文章地址:https://www.zhihuclub.com/198930.shtml

关于作者: 智云科技

热门文章

网站地图