Android蓝牙连接及获取蓝牙信号强度RSSI的基本实现


本文是关于Android的BLE蓝牙连接以及 获取蓝牙RSSI的基本实现 , 基于SDK中的Sample略作修改



效果图

扫描设备 已连接的设备

关于RSSI

  • 什么是RSSI

    Received Signal Strength Indicator , 接收的信号强度指示 , 单位是dbm , 无线发送层的可选部分 , 用来判定链接质量,以及是否增大广播发送强度。它的实现是在反向通道基带接收滤波器之后进行的。百度百科

  • 关于接收率

    一般为负值,反映的是信号的衰减程度,理想状态下(无衰减)Rssi值为0dBm,实际情况是,即使蓝牙设备挨得非常近,Rssi也只有-50dBm的强度,在传输过程中,不可避免要损耗。

    一般情况下,经典蓝牙强度

    信号强 0dBm ~ -50dBm
    信号中 -50dBm ~ -70dBm
    信号弱 -70dBm ~ dBm

    低功耗蓝牙分四级

    4 0 ~ -60
    3 -60 ~ -70
    2 -70 ~ -80
    1 -80 ~

  • Android中BLE蓝牙获取RSSI

    Android平台中,通过蓝牙设备扫描回调和蓝牙设备连接监听两种方式可以获取到每个蓝牙设备的RSSI。

  • 测距理论

    通过接收到的信号强弱测定信号点与接收点的距离,进而根据相应数据进行定位计算的一种定位技术。

获取蓝牙RSSI

  • 蓝牙权限

    <uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
    <uses-permission android:name="android.permission.BLUETOOTH"/>
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
    
  • 检查是否支持BLE和蓝牙

    // Use this check to determine whether BLE is supported on the device.  Then you can
    // selectively disable BLE-related features.
    if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
                Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
                finish();
    }
    
    // Initializes a Bluetooth adapter.  For API level 18 and above, get a reference to
    // BluetoothAdapter through BluetoothManager.
    final BluetoothManager bluetoothManager =
                    (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
    mBluetoothAdapter = bluetoothManager.getAdapter();
    
    // Checks if Bluetooth is supported on the device.
    if (mBluetoothAdapter == null) {
        Toast.makeText(this, R.string.error_bluetooth_not_supported, Toast.LENGTH_SHORT).show();
        finish();
        return;
    }
    
  • 获取RSSI方法一: 蓝牙设备扫描回调

    /**
     * 扫描蓝牙设备
     * @param enable 开始/停止扫描
     */
    private void scanLeDevice(final boolean enable) {
        if (enable) {
            // Stops scanning after a pre-defined scan period.
            mHandler.postDelayed(() -> {
                    mScanning = false;
                    mBluetoothAdapter.stopLeScan(mLeScanCallback);
                    invalidateOptionsMenu();
            }, SCAN_PERIOD);
    
            mScanning = true;
            mBluetoothAdapter.startLeScan(mLeScanCallback);
        } else {
            mScanning = false;
            mBluetoothAdapter.stopLeScan(mLeScanCallback);
        }
    }
    
    // 设备扫描回调
    private BluetoothAdapter.LeScanCallback mLeScanCallback = (device, rssi, scanRecord) -> {
    	Log.i(TAG, "rssi: " + rssi);
    };
    
  • 获取RSSI方法二: 连接蓝牙设备后读取

    • 先通过方法一的扫描设备拿到DeviceAddress
    • 在服务中注册监听
    • 通过绑定服务(BindService)管理生命周期
    • 连接蓝牙设备
    • 循环读取Rssi
    //Service中注册监听
    // Implements callback methods for GATT events that the app cares about.  For example,
    // connection change and services discovered.
    private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
    	@Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
        	String intentAction;
            if (newState == BluetoothProfile.STATE_CONNECTED) {
            	```
            } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
            	```
            }
    	}
    	@Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
        	if (status == BluetoothGatt.GATT_SUCCESS) {
        		broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
        	} else {
        		Log.w(TAG, "onServicesDiscovered received: " + status);
        	}
        }
        @Override
    	public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
    		Log.i(TAG, "gatt: " + gatt.toString() + ", rssi: " + rssi + ", status: " + status);
    		super.onReadRemoteRssi(gatt, rssi, status);
    		if (status == BluetoothGatt.GATT_SUCCESS) {
    			final Intent intent = new Intent(ACTION_READ_RSSI);
                intent.putExtra(EXTRA_DATA, String.valueOf(rssi));
                sendBroadcast(intent);
    		}
    	}
    };
    
    //绑定Service
    Intent gattServiceIntent = new Intent(this, BluetoothLeService.class);
    bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);
    
    // Code to manage Service lifecycle.
    private final ServiceConnection mServiceConnection = new ServiceConnection() {
    
    	@Override
    	public void onServiceConnected(ComponentName componentName, IBinder service) {
        	mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService();
            if (!mBluetoothLeService.initialize()) {
            	Log.e(TAG, "Unable to initialize Bluetooth");
                finish();
    		}
            mBluetoothLeService.connect(mDeviceAddress);
    	}
    
    	@Override
        public void onServiceDisconnected(ComponentName componentName) {
        	mBluetoothLeService = null;
    	}
    };
    
    private boolean isReadRssi = true;
    private Thread readRSSI;
    /**
     * 读取蓝牙RSSi线程
     */
    private void startReadRssi() {
        isReadRssi = true;
        int Rssi=0;
        readRSSI = (Thread)run() -> {
            while (isReadRssi){
                try {
                    sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //如果读取蓝牙RSSi回调成功
                if(mBluetoothLeService != null && mBluetoothLeService.getRssiVal()){
                    //获取已经读到的RSSI值
    //                Rssi=BluetoothLeService.getBLERSSI();
    //                mHandler.obtainMessage(READRSSI, Rssi).sendToTarget();
                }
            }
        };
        readRSSI.start();
    }
    
    //停止读取
    private void stopReadRssi() {
        if (readRSSI != null) {
            isReadRssi = false;
            readRSSI = null;
        }
    }
    

源码地址

项目源码, 新增了距离计算
https://github.com/ElvisGuozs/BluetoothLeGatt


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值