java - BLE 找到设备但未连接

标签 java android bluetooth bluetooth-lowenergy

我正在使用 Android Studio (java) 制作一个应用程序来扫描 BLE 设备,然后连接到它,最终导致我向它发送数据。

到目前为止,我已经创建了一个可以检测 BLE 设备的功能扫描仪,我可以调用设备名称、MAC 地址和 RSSI 值,但无法使其连接。鉴于我有 MAC 地址,连接不是一小段简单的代码吗?

我尝试使用createBond(),它在调试部分给了我一个响应,但没有做任何事情。

现在我从实际扫描中获得了 MAC 地址,有什么方法可以直接通过该地址进行连接吗?这也适合我的目的,因为我只会连接到相同的 BLE 模块。

这是我的代码,这样你就可以看到我所拥有的,所有这些都在运行

public class BluetoothConnect extends AppCompatActivity {

    BluetoothManager btManager;
    BluetoothAdapter btAdapter;
    BluetoothLeScanner btScanner;
    Button startScanningButton;
    Button stopScanningButton;
    TextView peripheralTextView;
    private final static int REQUEST_ENABLE_BT = 1;
    private static final int PERMISSION_REQUEST_COARSE_LOCATION = 1;
    final Intent startMainActivity = new Intent();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.scan_and_connect);

        controlTankScreen();

        //sets us the window for devices to be listed
        peripheralTextView = (TextView) findViewById(R.id.PeripheralTextView);
        peripheralTextView.setMovementMethod(new ScrollingMovementMethod());

        //button id 6 is start scanning
        startScanningButton = findViewById(R.id.button6);
        startScanningButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                startScanning();
            }
        });
        //button id 7 is stop scanning
        stopScanningButton = findViewById(R.id.button7);
        stopScanningButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                stopScanning();
            }
        });

        //enables bluetooth, Adapter refers to the local device, in this case, my smart phone
        btManager = (BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE);
        btAdapter = btManager.getAdapter();
        btScanner = btAdapter.getBluetoothLeScanner();


        if (btAdapter != null && !btAdapter.isEnabled()) {
            Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableIntent,REQUEST_ENABLE_BT);

        }

    // Make sure we have access coarse location enabled, if not, prompt the user to enable it
    if (this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        final AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("This app needs location access");
        builder.setMessage("Please grant location access so this app can detect peripherals.");
        builder.setPositiveButton(android.R.string.ok, null);
        builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
            @Override
            public void onDismiss(DialogInterface dialog) {
                requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_COARSE_LOCATION);
            }
        });
        builder.show();
    }
}


// this will scan for devices, displaying the device name, the mac address, and the RSSI, recieved signal strength indicator
public ScanCallback leScanCallback = new ScanCallback() {
    @Override
    public void onScanResult(int callbackType, ScanResult result) {
        peripheralTextView.append("Device Name: " + result.getDevice().getName() +"Mac Address: "+ result.getDevice().getAddress() +" rssi: " + result.getRssi() + "\n");
        String deviceName = result.getDevice().getName();
        String deviceAddress = result.getDevice().getAddress();
        result.getDevice().createBond();

        // auto scroll for text view
        final int scrollAmount = peripheralTextView.getLayout().getLineTop(peripheralTextView.getLineCount()) - peripheralTextView.getHeight();
        // if there is no need to scroll, scrollAmount will be <=0
        if (scrollAmount > 0)
            peripheralTextView.scrollTo(0, scrollAmount);
    }
};



@Override
//This makes sure that Bluetooth and correct permissions are allowed
public void onRequestPermissionsResult(int requestCode,
                                       String permissions[], int[] grantResults) {
    switch (requestCode) {
        case PERMISSION_REQUEST_COARSE_LOCATION: {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                System.out.println("coarse location permission granted");
            } else {
                final AlertDialog.Builder builder = new AlertDialog.Builder(this);
                builder.setTitle("Functionality limited");
                builder.setMessage("Since location access has not been granted, this app will not be able to discover beacons when in the background.");
                builder.setPositiveButton(android.R.string.ok, null);
                builder.setOnDismissListener(new DialogInterface.OnDismissListener() {

                    @Override
                    public void onDismiss(DialogInterface dialog) {
                    }

                });
                builder.show();
            }
            return;
        }
    }
}
//ran when button id 6, start scan is pressed
public void startScanning() {
    System.out.println("start scanning");
    peripheralTextView.setText("Started Scanning");
    //startScanningButton.setVisibility(View.INVISIBLE);
    //stopScanningButton.setVisibility(View.VISIBLE);
    AsyncTask.execute(new Runnable() {
        @Override
        public void run() {
            btScanner.startScan(leScanCallback);
        }
    });
}
//ran when button id 7, stop scan is pressed
public void stopScanning() {
    System.out.println("stopping scanning");
    peripheralTextView.append("Stopped Scanning");
    //startScanningButton.setVisibility(View.VISIBLE);
    //stopScanningButton.setVisibility(View.INVISIBLE);
    AsyncTask.execute(new Runnable() {
        @Override
        public void run() {
            btScanner.stopScan(leScanCallback);
        }
    });
}
//ran from onCreate on app boot up, just sets the app up to control the tank
public void controlTankScreen() {
    startMainActivity.setComponent(new ComponentName("smiths.tankcontroller", "smiths.tankcontroller.MainActivity"));

    final Button button = findViewById(R.id.button5);
    button.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            startActivity(startMainActivity);
            setContentView(R.layout.activity_main);

            //what to do when the button is pressed
            finish();

        }
    });
}



IntentFilter intent = new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED);


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

        if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
            final int state        = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR);
            final int prevState    = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, BluetoothDevice.ERROR);

            if (state == BluetoothDevice.BOND_BONDED && prevState == BluetoothDevice.BOND_BONDING) {
                System.out.println("Paired");
            } else if (state == BluetoothDevice.BOND_NONE && prevState == BluetoothDevice.BOND_BONDED){
                System.out.println("Unpaired");
            }

        }
    }
};

public void pairDevice(BluetoothDevice device) {
    try {
        Method method = device.getClass().getMethod("createBond", (Class[]) null);
        method.invoke(device, (Object[]) null);
    } catch (Exception e) {
        e.printStackTrace();
    }
}
}

最佳答案

连接 BLE 外设的正确方法:

final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);

mBluetoothGatt = device.connectGatt(this, false, mGattCallback);

如果任何特征需要加密,您需要处理读/写结果“BluetoothGatt.GATT_INSUFFICIENT_AUTHENTICATION”并重试。

关于java - BLE 找到设备但未连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47248413/

相关文章:

java - 如何在pom.xml中配置 "tomcat7-maven-plugin"?

java - 保持 JPA EntityManager 打开?

android - 将蓝牙配对请求通知对话框放在前面以询问 PIN

python - 用于手机的远程蓝牙摄像头触发器

java - 使用以下代码输出错误

JavaFX登录不同页面

android - 空指针异常 - fragment Activity

java - android - 比较两个非常大的ArrayList,其中一个从firebase检索

android - 是否可以在 xml 中创建一个 "dp"变量?

html - 将 HTML 转换为 ZPL - javascript