OBDII车载诊断仪开发记录之一波三折(二)BlueTooth 4

前言

接着上一篇博客记录,这里记录4.0的开发,废话不多说,直接开始吧。

BluetoothBle
1.权限

<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<!--高版本需要这个权限,不然搜不到蓝牙设备-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

至于动态申请权限,这里就不展开说了,自行百度吧。

2.扫描设备

    /**
     * 是否支持蓝牙
     *
     * @return
     */
    private boolean isSupportBluetooth() {
        return bluetoothAdapter != null;
    }

    /**
     * 是否支持BLE
     *
     * @return
     */
    private boolean isSupportBle() {
        return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE);
    }

    /**
     * 是否开启蓝牙
     *
     * @return
     */
    private boolean isEnableBluetooth() {
        return bluetoothAdapter.isEnabled();
    }

    /**
     * 开启蓝牙
     */
    private void enableBluetooth() {
        if (!isEnableBluetooth()) {
            Log.e(TAG, "enable bluetooth.......");
            Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            mContext.startActivityForResult(intent, Constant.REQUEST_CODE_ENABLE_BLUETOOTH_BLE);
        } else {
            Log.e(TAG, "bluetooth is already enabled........");
        }
    }

    /**
     * 请求开启蓝牙回调
     */
    public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        if (resultCode != Activity.RESULT_OK)
            return;
        if (requestCode == Constant.REQUEST_CODE_ENABLE_BLUETOOTH_BLE) {
            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    startDiscoveryBLE();
                }
            }, 3000);

        }
    }

跟蓝牙3.0其实差不多,就是多了一步判断是否支持BLE模式。
接着才是扫描设备,这里就完全不同了。

 /**
     * 开始扫描BLE,
     * 扫描会一直进行,所以需要设定一个停止时间
     */
    public void startDiscoveryBLE() {
        bluetoothAdapter.stopLeScan(scanCallback);
        bluetoothAdapter.startLeScan(scanCallback);
        mHandler.removeCallbacks(cancelRunnable);
        mHandler.postDelayed(cancelRunnable, 10 * 1000);
    }

    /**
     * 停止扫描
     */
    public void stopDiscoveryBLE() {
        if (bluetoothAdapter != null)
            bluetoothAdapter.stopLeScan(scanCallback);
    }

    private Runnable cancelRunnable = new Runnable() {
        @Override
        public void run() {
            //BLE会一直扫描,所以设置一个扫描时间
            stopDiscoveryBLE();
            mHandler.sendEmptyMessage(Constant.BLUETOOTH_FINISH_DISCOVERY_BLE);
        }
    };
    
    
        private BluetoothAdapter.LeScanCallback scanCallback = new BluetoothAdapter.LeScanCallback() {

            @Override
            public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
                Log.e(TAG, "onLeScan....."+device.getName());
                if (device == null || device.getAddress() == null || device.getName() == null) {
                    return;
                }
    
                BTDevice btDevice = new BTDevice(device.getName(), device.getAddress(), device.getBondState(), device.getUuids(), Constant.BLUETOOTH_KIND_BLE);
                Message msg = mHandler.obtainMessage(Constant.BLUETOOTH_BLE_FOUND_DEVICE);
                Bundle bundle = new Bundle();
                bundle.putParcelable(Constant.EXTRA_DEVICE, btDevice);
                msg.setData(bundle);
                mHandler.sendMessage(msg);
            }

    };

蓝牙连接
连接也跟3.0完全不同,这里启用了后台服务

    /**
     * 启动连接服务
     */
    private void startService() {
        Log.e(TAG,"startService....");
        Intent intent = new Intent(mContext, BluetoothLeService.class);
        mContext.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
    }

    /**
     * 断开连接,解绑
     */
    public void onDestory() {
        stopDiscoveryBLE();
        mContext.unbindService(mServiceConnection);
        if (bluetoothLeService != null) {
            bluetoothLeService.disconnect();
        }
        bluetoothLeService = null;
    }
    
        private final ServiceConnection mServiceConnection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                Log.e(TAG, "onservice connected..........");
                bluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService();
                if(!bluetoothLeService.initialize()){
                    return;
                }
                if (!TextUtils.isEmpty(mAddress)) {
                    bluetoothLeService.connect(mAddress);
                }
            }
    
            @Override
            public void onServiceDisconnected(ComponentName name) {
                Log.e(TAG, "onservice disconnected..........");
                bluetoothLeService = null;
            }
    };

连接的核心都在Service实现

public class BluetoothLeService extends Service {

    private final String TAG = this.getClass().getSimpleName();

    private static final int STATE_DISCONNECTED = 0;
    private static final int STATE_CONNECTING = 1;
    private static final int STATE_CONNECTED = 2;

    private final IBinder mBinder = new LocalBinder();
    private BluetoothManager mBluetoothManager;
    private BluetoothAdapter mBluetoothAdapter;
    private BluetoothGatt mBluetoothGatt;
    private String mAddress;
    private int mConnectionState = STATE_DISCONNECTED;
    private BluetoothHandler mHandler;

    private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            super.onConnectionStateChange(gatt, status, newState);
//            String intentAction;
            if(newState== BluetoothProfile.STATE_CONNECTED){//连接上
                mConnectionState = STATE_CONNECTED;
                Log.e(TAG, "-----onConnectionStateChange------STATE_CONNECTED");
                mHandler.obtainMessage(Constant.BLUETOOTH_LE_GATT_CONNECTED).sendToTarget();
            }

            if(newState==BluetoothProfile.STATE_DISCONNECTED){
                mConnectionState = STATE_DISCONNECTED;
                Log.e(TAG, "-----onConnectionStateChange------STATE_DISCONNECTED");
                mHandler.obtainMessage(Constant.BLUETOOTH_LE_GATT_DISCONNECTED).sendToTarget();
            }
        }

        //发现设备的服务回调,需要在这里处理订阅事件
        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            super.onServicesDiscovered(gatt, status);
            if(status!=BluetoothGatt.GATT_SUCCESS){//成功订阅
                return;
            }

            Log.e(TAG, "-----onServicesDiscovered------GATT_SUCCESS");
            mHandler.obtainMessage(Constant.BLUETOOTH_LE_GATT_SERVICES_DISCOVERED).sendToTarget();
            List<BluetoothGattService> services = gatt.getServices();
            for(BluetoothGattService service:services){
                for(BluetoothGattCharacteristic characteristic:service.getCharacteristics()){
                    if(TextUtils.equals(Constant.READ_UUID,characteristic.getUuid().toString())){
                        //依据协议订阅相关信息,否则收不到数据
                        mBluetoothGatt.setCharacteristicNotification(characteristic,true);
                        // 大坑,适配某些手机!!!比如小米...
                        mBluetoothGatt.readCharacteristic(characteristic);
                        for(BluetoothGattDescriptor descriptor:characteristic.getDescriptors()){
                            descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
                            mBluetoothGatt.writeDescriptor(descriptor);
                        }
                    }
                }
            }
        }

        @Override
        public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            super.onCharacteristicRead(gatt, characteristic, status);
            if(status==BluetoothGatt.GATT_SUCCESS){
                Log.e(TAG, "-----onCharacteristicRead------onCharacteristicRead");
//                mHandler.obtainMessage(Constant.BLUETOOTH_LE_DATA_AVAILABLE).sendToTarget();

            }
        }
        //发送消息结果回调
        @Override
        public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            super.onCharacteristicWrite(gatt, characteristic, status);
            if(status==BluetoothGatt.GATT_SUCCESS){
                Log.e(TAG,"------write data success---");
                return;
            }

            if(status==BluetoothGatt.GATT_FAILURE){
                Log.e(TAG,"---write data failure---");
                return;
            }

            if(status==BluetoothGatt.GATT_WRITE_NOT_PERMITTED){
                Log.e(TAG,"----write no permission---");
            }
        }

        // 当订阅的Characteristic接收到消息时回调
        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
            super.onCharacteristicChanged(gatt, characteristic);
            Log.e(TAG, "-----onCharacteristicChanged------onCharacteristicChanged");
            mHandler.obtainMessage(Constant.READ_DATA,characteristic.getValue()).sendToTarget();
        }
    };


    public boolean initialize() {
        if(mHandler ==null){
            mHandler = BluetoothHandler.getInstance(this);
        }
        if (mBluetoothManager == null) {
            mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        }
        if (mBluetoothManager == null) {
            return false;
        }
        if (mBluetoothAdapter == null) {
            mBluetoothAdapter = mBluetoothManager.getAdapter();
        }
        if (mBluetoothAdapter == null) {
            return false;
        }
        return true;
    }


    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        close();

        return super.onUnbind(intent);
    }

    public class LocalBinder extends Binder {
        BluetoothLeService getService() {
            return BluetoothLeService.this;
        }
    }


    public boolean connect(final String address) {
        if (mBluetoothAdapter == null || address == null) {
            return false;
        }
        //如果是之前已连接的,重连即可
        if (mAddress != null && address.equals(mAddress) && mBluetoothGatt != null) {
            Log.e(TAG, "trying to use an existing connection");
            if (mBluetoothGatt.connect()) {
                mConnectionState = STATE_CONNECTING;
                return true;
            } else {
                return false;
            }
        }

        final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
        if (device == null) {
            Log.e(TAG, "device not found,unable to connect");
            return false;
        }
        mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
        Log.e(TAG, " trying to create a new connection");
        mAddress = address;
        mConnectionState = STATE_CONNECTING;
        return true;

    }

    public void disconnect() {
        if (mBluetoothAdapter == null || mBluetoothGatt == null) {
            Log.e(TAG, "bluetoothadapter not initialized");
            return;
        }
        mBluetoothGatt.disconnect();
    }

    private void close() {
        if (mBluetoothGatt == null) {
            return;
        }
        mBluetoothGatt.close();
        mBluetoothGatt = null;
    }
}

结束语

蓝牙4.0就这么一点内容,记录一下,方便自己查找。都是经过我实测可用的,可放心,不是单纯copy paste的结果。

我把核心代码打包贴出来,仅供参考,不足之处欢迎留言指正。

蓝牙3.0点击这里 OBDII车载诊断仪开发记录之一波三折(一)BlueTooth 3
代码下载地址

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值