簡體   English   中英

如何連接到特定的BLE設備?

[英]How do I connect to specific BLE device?

我正在使用redbearlabs的SimpleControls應用程序,並將其修改為我的個人用途。

主要布局如下所示,查找並連接到BLE設備的方法是單擊“連接”按鈕,該按鈕會自動掃描並連接到找到的設備。

問題:
該應用程序幾乎可以連接到它檢測到的任何BLE設備,因此我想知道是否有可能以這樣的方式指定我擁有的BLE設備的MAC地址:

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


我嘗試連接的設備: 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設備控制燈光的按鈕。

任何幫助表示贊賞,在此先感謝!

在LeScanCallback中,您可以從BluetoothDevice對象獲取mac地址,使用該地址檢查它是否為您要查找的設備。 如果不是您的設備,請不要運行可運行程序。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM