本文简要介绍如何在Android中进行BLE device的Scan,实验平台Android 7, 编译SDK 28(android 9).

增加权限 链接到标题

manifest 修改 链接到标题

在AndroidManifest.xml中增加

 <uses-feature android:name="android.bluetooth.le" android:required="true"/>
 <uses-permission android:name="android.permission.BLUETOOTH"/>
 <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
 <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
 <uses-permission android:name="andriod.permission.ACCESS_FINE_LOCATION"/>

APK中请求位置权限 链接到标题

Android5以上版本必须要ACCESS_COARSE_LOCATION权限,否则无法scan到device, 在scan device前调用mayRequestLocation请求ACCESS_COARSE_LOCATION权限

    private static final int REQUEST_COARSE_LOCATION = 0;

    private void mayRequestLocation() {
        if (Build.VERSION.SDK_INT >= 23) {
            int checkCallPhonePermission = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION);
            if (checkCalldePhonePermission != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, REQUEST_COARSE_LOCATION);
                return;
            }
        }
    }
    
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        if (requestCode == REQUEST_COARSE_LOCATION) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(this, "权限被授予", Toast.LENGTH_SHORT).show();
            } else if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(this, "权限被拒绝", Toast.LENGTH_SHORT).show();
            }
        } else {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

扫描过程 链接到标题

检查SDK是否支援BLE 链接到标题

if(!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)){
    Toast.makeText(MainActivity.this, R.string.noble, Toast.LENGTH_LONG);
}

检查HW是否有蓝牙 链接到标题

BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
BluetoothAdapter mBluetoothAdapter = bluetoothManager.getAdapter();
if(mBluetoothAdapter == null){
    Toast.makeText(MainActivity.this, R.string.nobleerr, Toast.LENGTH_LONG);
}

检查是否开启蓝牙 链接到标题

if(!mBluetoothAdapter.isEnabled()){
    //未开启蓝牙,询问是否开启蓝牙
    Intent enableBLE = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
    startActivity(enableBLE);
}

扫描BLE Device 链接到标题

实现扫描Callback 链接到标题

ScanCallback mScanCB = new ScanCallback() {
                @Override
                public void onScanResult(int callbackType, ScanResult result) {
                    super.onScanResult(callbackType, result);
                    BluetoothDevice device = result.getDevice();
                    if(!mDeviceList.contains(device)) {
                        mDeviceList.add(device);                        
                    }
                }

                @Override
                public void onScanFailed(int errorCode) {
                    super.onScanFailed(errorCode);
                    Log.e(TAG, "Scan Fail " + errorCode);
                }
            };

启动扫描 链接到标题

将实现的扫描callback注册启动扫描,如果由扫到device会回调到onScanResult,在onScanResult中处理扫描到的device

BluetoothLeScanner mScanner = mBluetoothAdapter.getBluetoothLeScanner();
mScanner.startScan(mScanCB);

停止扫描 链接到标题

mScanner.stopScan(mScanCB);