Android蓝牙连接的一些心得

最近做一个项目,主要是给蓝牙发送指令的,boss要求能够最快速度的搜索到蓝牙,并且发送数据.

刚开始也遇到很多133,各种断开连接的问题.android蓝牙搜索有两种方式,一种startLeScan,另一种startDiscovery.因为项目要讲究搜索蓝牙的速度,一开始我一直用的startDiscovery,,但是这个搜索的速度有的手机太慢了,有的手机会达到5-6秒,不能满足需求,后面又尝试了startLeScan,发现搜索速度很快,基本上1秒以内都能搜索到需要的蓝牙.但是startLeScan这个方法,搜索到的蓝牙有的机型会拿不到蓝牙的名称,因为项目是根据蓝牙名称来匹配的,这就很尴尬,拿不到名称就匹配不了,搜到了也没用.

因为考虑到startLeScan搜到的速度很快,但只是小部分机型拿不到设备名称,所有就尝试了新的方法.先用旧的方法搜索蓝牙,在1000ms以内搜不到想要的蓝牙设备名称,就用startDiscovery方法来搜索.

private BluetoothAdapter mBtAdapter;
public void judgeBluth() {
    if (mBtAdapter == null) mBtAdapter = BluetoothAdapter.getDefaultAdapter();
    if (!mBtAdapter.isEnabled()) {
        Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        startActivity(enableIntent);
    }else{
        checkGPSPermission();
    }
}
@Override
public void GPSsure() {
    if(mBtAdapter==null){
        CommonUtils.showToast(this,"设备上没有发现有蓝牙设备");
        return;
    }
    if(!mBtAdapter.isEnabled()){//开启蓝牙设备
        mBtAdapter.enable();
        return;
    }

    if(MyUtils.newInstance().getBluetoothDevice()!=null){
        connect(MyUtils.newInstance().getBluetoothDevice());
    }else{
        mBtAdapter.startLeScan(mLeScanCallback);
        mHandler.postDelayed(new Runnable() {//1000ms后没有搜索到,用新方法
            @Override
            public void run() {
                if(!isGet){
                    mBtAdapter.stopLeScan(mLeScanCallback);
                    IntentFilter mFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
                    registerReceiver(mReceiver, mFilter);
                    // 注册搜索完时的receiver
                    IntentFilter mFilter1 = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
                    registerReceiver(mReceiver, mFilter1);
                    isNew = true;
                    mBtAdapter.startDiscovery();
                }
            }
        },1000);
    }
}

 

private volatile   boolean  isGet = false;
private BluetoothAdapter.LeScanCallback mLeScanCallback =
        new BluetoothAdapter.LeScanCallback() {
            @Override
            public void onLeScan(final BluetoothDevice device, final int rssi, byte[] scanRecord) {
                if(isGet)return;
                if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
                        if((device.getName()!=null&&bean.getBluetooth().equals(device.getName()))||(MyUtils.newInstance().getMac()!=null&&device.getAddress().equals(MyUtils.newInstance().getMac()))){
                            isGet = true;
                            mBtAdapter.stopLeScan(mLeScanCallback);
                       mHandler.post(new Runnable() { @Override public void run() { connect(device); } });
                            SharedPreferencesUtil.addBluetoothMac(SuccessActivity.this,device.getAddress());
                                break;
                    
                        }
                    }
                }
            }

        };

private boolean isNew = false;
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        if(isGet)return;
        String action = intent.getAction();
        // 获得已经搜索到的蓝牙设备
        if (action.equals(BluetoothDevice.ACTION_FOUND)) {
            BluetoothDevice device = intent
                    .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            // 搜索到的不是已经绑定的蓝牙设备
            if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
                for (int i = 0; i < str.size(); i++) {
                    UserBean bean = str.get(i);
                    if((device.getName()!=null&&bean.getBluetooth().equals(device.getName()))||(MyUtils.newInstance().getMac()!=null&&device.getAddress().equals(MyUtils.newInstance().getMac()))){
                        isGet = true;
                        handlerSendString("搜到蓝牙新",System.currentTimeMillis());
                        if(mBtAdapter.isDiscovering()){
                            mBtAdapter.cancelDiscovery();
                        }
                        connect(device);
                   
                    }
                }
            }
            // 搜索完成
        } else if (action.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) {
            if(mBtAdapter==null)return;
            if(mBtAdapter.isDiscovering()){
                mBtAdapter.cancelDiscovery();//关闭搜索
            }
            if(!isGet){//未搜索到相关蓝牙
                handlerSendString("未搜索到蓝牙",System.currentTimeMillis());
            }
        }
    }
};


public boolean refreshDeviceCache(BluetoothGatt mBluetoothGatt) {
    if (mBluetoothGatt != null) {
        try {
            Method localMethod = mBluetoothGatt.getClass().getMethod( "refresh", new Class[0]);
            if (localMethod != null) {
                boolean bool = ((Boolean) localMethod.invoke( mBluetoothGatt, new Object[0])).booleanValue();
                return bool;
            }
        } catch (Exception localException) {

        }
    }
    return false;}

搜索到蓝牙后就开始连接蓝牙了,这里连接我刚开始写的时候,出现很多问题,这里就不一一说了,有的时候会出现开始连接之后就直接断开连接,有的时候又连接不上,有的时候又会发现不了服务,所以我在连接断开的情况下尝试了重新连接.

 

public volatile int isConnect = 0;
private BluetoothGatt gatts;
public  void connect(final BluetoothDevice device){
    if(isConnect ==1||isConnect==2||isConnect==3){//防止重复连接的情况
        return;
    }

    if(gatts!=null){
        isConnect = 0;
        gatts.close();
        gatts = null;
    }
    handlerSendString("开始连接",System.currentTimeMillis());

    gatts = device.connectGatt(this, false, new BluetoothGattCallback() {
            @Override
            public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
                if (newState == BluetoothGatt.STATE_CONNECTED) {
                     gatt.discoverServices();
                    handlerSendString("连接成功",System.currentTimeMillis());
                    isConnect = 1;
                } else {
                    handlerSendString("断开连接"+"--code:"+newState,System.currentTimeMillis());
                    refreshDeviceCache(gatt);
                    gatt.close();
                    gatt=null;
                    if(isConnect == 2||isConnect ==0){//未发现蓝牙服务,连接直接断开,没有写入数据,重新连接
                        mHandler.postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                connect(device);
                            }
                        },100);
                    }
                    isConnect = 0;
                }
            }


            @Override
            public void onServicesDiscovered(final BluetoothGatt gatt, int status) {
                isConnect = 2;
                handlerSendString("发现服务",System.currentTimeMillis());
                List<BluetoothGattService> services = gatt.getServices();
                boolean is = true;
                for (int i = services.size()-1; i >= 0; i--) {
                    BluetoothGattService service = services.get(i);
                    if(service.getUuid().toString().equals(MyUtils.service_uuid)){
                        List<BluetoothGattCharacteristic> characteristics = service.getCharacteristics();
                        BluetoothGattCharacteristic characteristic = characteristics.get(characteristics.size()-1);
                        characteristic.setValue(MyUtils.a);
                        gatt.setCharacteristicNotification(characteristic,false);
                        handlerSendString("发送指令",System.currentTimeMillis());
                        gatt.writeCharacteristic(characteristic);
                        is = false;
                        break;
                    }
                }
                if(is){
                    handlerSendString("未检测到蓝牙服务",System.currentTimeMillis());
                    gatt.disconnect();
                }
            }

            @Override
            public void onCharacteristicWrite(final BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
                isConnect = 3;
                if(status == BluetoothGatt.GATT_SUCCESS){//写入成功
                    handlerSendString("写入成功",System.currentTimeMillis());
                }else if (status == BluetoothGatt.GATT_FAILURE){
                    Log.e("onCharacteristicWrite中", "写入失败");
                }else if (status == BluetoothGatt.GATT_WRITE_NOT_PERMITTED){
                    Log.e("onCharacteristicWrite中", "没权限");
                }

                mHandler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        gatt.disconnect();
                    }
                },200);
            }

    });
}

 

@Override
protected void onDestroy() {
    if(isNew)unregisterReceiver(mReceiver);
    super.onDestroy();
}

这些就是我这个项目的时候,尝试了多次的之后的代码,还有需要完善的地方希望有大神能多多指教.

最后总结了一下,android蓝牙连接需要定位的,有的机型如果没有请求定位权限的话,会出现找不到蓝牙,找不到服务的情况.

android蓝牙连接机型不一样,稳定性也不一样,连接的速度也不一样,弄的我焦头烂额的.

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值