如何连接到特定的BLE设备?

时间:2016-07-07 14:10:56

标签: android bluetooth-lowenergy

我正在使用redbearlabs的SimpleControls应用程序并将其修改为我个人使用。

主要布局如下所示,查找和连接BLE设备的方法是单击连接按钮,该按钮会自动扫描并连接到找到的设备(<?)。

问题:
该应用程序几乎可以连接到它检测到的任何BLE设备,所以我想知道是否有可能指定我拥有的BLE设备的MAC地址,这样逻辑就像这样:

if (address == "BB:EE:7A:89:B3:19")
{
    //connect
}


设备I尝试连接到: redbearlabs BLE Nano

这是包含连接函数的 SimpleControls代码

private Button connectBtn = null;
private TextView rssiValue = null;
//private TextView AnalogInValue = null;
private ToggleButton digitalOutBtn1, digitalOutBtn2, digitalOutBtn3;


private BluetoothGattCharacteristic characteristicTx = null;
private RBLService mBluetoothLeService;
private BluetoothAdapter mBluetoothAdapter;
private BluetoothDevice mDevice = null;
private String mDeviceAddress;

private boolean flag = true;
private boolean connState = false;
private boolean scanFlag = false;

private byte[] data = new byte[3];
private static final int REQUEST_ENABLE_BT = 1;
private static final long SCAN_PERIOD = 2000;

final private static char[] hexArray = { '0', '1', '2', '3', '4', '5', '6',
        '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

private final ServiceConnection mServiceConnection = new ServiceConnection() {

    @Override
    public void onServiceConnected(ComponentName componentName,
            IBinder service) {
        mBluetoothLeService = ((RBLService.LocalBinder) service)
                .getService();
        if (!mBluetoothLeService.initialize()) {
            Log.e(TAG, "Unable to initialize Bluetooth");
            finish();
        }
    }

    @Override
    public void onServiceDisconnected(ComponentName componentName) {
        mBluetoothLeService = null;
    }
};

private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        final String action = intent.getAction();

        if (RBLService.ACTION_GATT_DISCONNECTED.equals(action)) {
            Toast.makeText(getApplicationContext(), "Disconnected",
                    Toast.LENGTH_SHORT).show();
            setButtonDisable();
        } else if (RBLService.ACTION_GATT_SERVICES_DISCOVERED
                .equals(action)) {
            Toast.makeText(getApplicationContext(), "Connected to BLE Nano",
                    Toast.LENGTH_SHORT).show();

            getGattService(mBluetoothLeService.getSupportedGattService());
        } else if (RBLService.ACTION_DATA_AVAILABLE.equals(action)) {
            data = intent.getByteArrayExtra(RBLService.EXTRA_DATA);

            //readAnalogInValue(data);
        } else if (RBLService.ACTION_GATT_RSSI.equals(action)) {
            displayData(intent.getStringExtra(RBLService.EXTRA_DATA));
        }
    }
};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
    setContentView(R.layout.main);
    getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title);

    rssiValue = (TextView) findViewById(R.id.rssiValue);

    //AnalogInValue = (TextView) findViewById(R.id.AIText);

    digitalOutBtn2 = (ToggleButton) findViewById(R.id.digitalOutBtn2);

    connectBtn = (Button) findViewById(R.id.connect);
    connectBtn.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            if (scanFlag == false) {
                scanLeDevice();

                Timer mTimer = new Timer();
                mTimer.schedule(new TimerTask() {

                    @Override
                    public void run() {
                        if (mDevice != null) {
                            mDeviceAddress = mDevice.getAddress();
                            mBluetoothLeService.connect(mDeviceAddress);
                            scanFlag = true;
                        } else {
                            runOnUiThread(new Runnable() {
                                public void run() {
                                    Toast toast = Toast
                                            .makeText(
                                                    SimpleControls.this,
                                                    "Couldn't search Ble Shield device!",
                                                    Toast.LENGTH_SHORT);
                                    toast.setGravity(0, 0, Gravity.CENTER);
                                    toast.show();
                                }
                            });
                        }
                    }
                }, SCAN_PERIOD);
            }

            System.out.println(connState);
            if (connState == false) {
                mBluetoothLeService.connect(mDeviceAddress);
            } else {
                mBluetoothLeService.disconnect();
                mBluetoothLeService.close();
                setButtonDisable();
            }
        }
    });

    digitalOutBtn1 = (ToggleButton) findViewById(R.id.digitalOutBtn1);
    digitalOutBtn1.setOnCheckedChangeListener(new OnCheckedChangeListener() {

        @Override
        public void onCheckedChanged(CompoundButton buttonView,
                boolean isChecked) {
            byte buf[] = new byte[] { (byte) 0x01, (byte) 0x00, (byte) 0x00 };

            if (isChecked == true)
                buf[1] = 0x01; //turn on
            else
                buf[1] = 0x00; //turn off

            characteristicTx.setValue(buf);
            mBluetoothLeService.writeCharacteristic(characteristicTx);
        }
    });

    digitalOutBtn3 = (ToggleButton) findViewById(R.id.digitalOutBtn3);
    digitalOutBtn3.setOnCheckedChangeListener(new OnCheckedChangeListener() {

        @Override
        public void onCheckedChanged(CompoundButton buttonView,
                boolean isChecked) {
            byte[] buf = new byte[] { (byte) 0xA0, (byte) 0x00, (byte) 0x00 };

            if (isChecked == true)
                buf[1] = 0x01;
            else
                buf[1] = 0x00;

            characteristicTx.setValue(buf);
            mBluetoothLeService.writeCharacteristic(characteristicTx);
        }
    });

    if (!getPackageManager().hasSystemFeature(
            PackageManager.FEATURE_BLUETOOTH_LE)) {
        Toast.makeText(this, "Ble not supported", Toast.LENGTH_SHORT)
                .show();
        finish();
    }

    final BluetoothManager mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
    mBluetoothAdapter = mBluetoothManager.getAdapter();
    if (mBluetoothAdapter == null) {
        Toast.makeText(this, "Ble not supported", Toast.LENGTH_SHORT)
                .show();
        finish();
        return;
    }

    Intent gattServiceIntent = new Intent(SimpleControls.this,
            RBLService.class);
    bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);
}

@Override
protected void onResume() {
    super.onResume();

    if (!mBluetoothAdapter.isEnabled()) {
        Intent enableBtIntent = new Intent(
                BluetoothAdapter.ACTION_REQUEST_ENABLE);
        startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
    }

    registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());
}

private void displayData(String data) {
    if (data != null) {
        rssiValue.setText(data);
    }
}

private void setButtonEnable() {
    flag = true;
    connState = true;

    digitalOutBtn1.setEnabled(flag);
    digitalOutBtn3.setEnabled(flag);
    connectBtn.setText("Disconnect");
}

private void setButtonDisable() {
    flag = false;
    connState = false;

    digitalOutBtn1.setEnabled(flag);
    digitalOutBtn3.setEnabled(flag);
    connectBtn.setText("Connect");
}

private void startReadRssi() {
    new Thread() {
        public void run() {

            while (flag) {
                mBluetoothLeService.readRssi();
                try {
                    sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
    }.start();
}

private void getGattService(BluetoothGattService gattService) {
    if (gattService == null)
        return;

    setButtonEnable();
    startReadRssi();

    characteristicTx = gattService
            .getCharacteristic(RBLService.UUID_BLE_SHIELD_TX);

    BluetoothGattCharacteristic characteristicRx = gattService
            .getCharacteristic(RBLService.UUID_BLE_SHIELD_RX);
    mBluetoothLeService.setCharacteristicNotification(characteristicRx,
            true);
    mBluetoothLeService.readCharacteristic(characteristicRx);
}

private static IntentFilter makeGattUpdateIntentFilter() {
    final IntentFilter intentFilter = new IntentFilter();

    intentFilter.addAction(RBLService.ACTION_GATT_CONNECTED);
    intentFilter.addAction(RBLService.ACTION_GATT_DISCONNECTED);
    intentFilter.addAction(RBLService.ACTION_GATT_SERVICES_DISCOVERED);
    intentFilter.addAction(RBLService.ACTION_DATA_AVAILABLE);
    intentFilter.addAction(RBLService.ACTION_GATT_RSSI);

    return intentFilter;
}

private void scanLeDevice() {
    new Thread() {

        @Override
        public void run() {
            mBluetoothAdapter.startLeScan(mLeScanCallback);

            try {
                Thread.sleep(SCAN_PERIOD);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            mBluetoothAdapter.stopLeScan(mLeScanCallback);
        }
    }.start();
}

private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {

    @Override
    public void onLeScan(final BluetoothDevice device, final int rssi,
            final byte[] scanRecord) {

        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                byte[] serviceUuidBytes = new byte[16];
                String serviceUuid = "";
                for (int i = 30, j = 0; i >= 15; i--, j++) {
                    serviceUuidBytes[j] = scanRecord[i];
                }
                serviceUuid = bytesToHex(serviceUuidBytes);
                if (stringToUuidString(serviceUuid).equals(
                        RBLGattAttributes.BLE_SHIELD_SERVICE
                                .toUpperCase(Locale.ENGLISH))) {
                    mDevice = device;
                }
            }
        });
    }
};

private String bytesToHex(byte[] bytes) {
    char[] hexChars = new char[bytes.length * 2];
    int v;
    for (int j = 0; j < bytes.length; j++) {
        v = bytes[j] & 0xFF;
        hexChars[j * 2] = hexArray[v >>> 4];
        hexChars[j * 2 + 1] = hexArray[v & 0x0F];
    }
    return new String(hexChars);
}

private String stringToUuidString(String uuid) {
    StringBuffer newString = new StringBuffer();
    newString.append(uuid.toUpperCase(Locale.ENGLISH).substring(0, 8));
    newString.append("-");
    newString.append(uuid.toUpperCase(Locale.ENGLISH).substring(8, 12));
    newString.append("-");
    newString.append(uuid.toUpperCase(Locale.ENGLISH).substring(12, 16));
    newString.append("-");
    newString.append(uuid.toUpperCase(Locale.ENGLISH).substring(16, 20));
    newString.append("-");
    newString.append(uuid.toUpperCase(Locale.ENGLISH).substring(20, 32));

    return newString.toString();
}

@Override
protected void onStop() {
    super.onStop();

    flag = false;

    unregisterReceiver(mGattUpdateReceiver);
}

@Override
protected void onDestroy() {
    super.onDestroy();

    if (mServiceConnection != null)
        unbindService(mServiceConnection);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // User chose not to enable Bluetooth.
    if (requestCode == REQUEST_ENABLE_BT
            && resultCode == Activity.RESULT_CANCELED) {
        finish();
        return;
    }

    super.onActivityResult(requestCode, resultCode, data);
}

我不确定如何在此代码中实现我想要的功能。 digitalOutBtn是用于使用BLE设备控制灯光的按钮。

感谢任何帮助,提前谢谢!

1 个答案:

答案 0 :(得分:0)

在LeScanCallback中,您可以从BluetoothDevice对象获取mac地址,使用它来检查它是否是您正在寻找的设备。如果不是您的设备,请不要运行runnable。