微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

蓝牙 BLE 无法连接

如何解决蓝牙 BLE 无法连接

我尝试了所有方法,但无法连接到其他蓝牙设备。我执行以下步骤:

  • 扫描设备
  • 当我找到带有“A-”的设备时停止扫描
  • 连接到设备

我可以找到所有设备,但无法连接到我想要的设备。不幸的是我找不到完整的例子

这是我使用的代码


import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanResult;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;

import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;

import java.util.List;
import java.util.Map;
import java.util.UUID;

public class MainActivity extends AppCompatActivity {

    BluetoothManager btManager;
    BluetoothAdapter btAdapter;
    BluetoothLeScanner btScanner;
    Button startScanningButton;
    Button stopScanningButton;
    TextView peripheralTextView;
    BluetoothGatt bluetoothGatt;
    BluetoothDevice device;
    private final static int REQUEST_ENABLE_BT = 1;
    private static final int PERMISSION_REQUEST_COARSE_LOCATION = 2;
    private boolean mEchoInitialized;

    private static final String TAG = "ClientActivity";

//
//    private ActivityClientBinding mBinding;

    private boolean mScanning;
    private Handler mHandler;
    private Handler mLogHandler;
    private Map<String,BluetoothDevice> mScanResults;

    private boolean mConnected;
    private ScanCallback mScanCallback;

    public static String SERVICE_STRING = "7D2EA28A-F7BD-485A-BD9D-92AD6ECFE93E";
    public static UUID SERVICE_UUID = UUID.fromString(SERVICE_STRING);

    public static String CHaraCTERISTIC_ECHO_STRING = "7D2EBAAD-F7BD-485A-BD9D-92AD6ECFE93E";
    public static UUID CHaraCTERISTIC_ECHO_UUID = UUID.fromString(CHaraCTERISTIC_ECHO_STRING);

    public static final long SCAN_PERIOD = 5000;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = findViewById(R.id.fab);
        fab.setonClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view,"Replace with your own action",Snackbar.LENGTH_LONG)
                        .setAction("Action",null).show();
            }
        });

        peripheralTextView = (TextView) findViewById(R.id.PeripheralTextView);
        peripheralTextView.setMovementMethod(new ScrollingMovementMethod());

        startScanningButton = (Button) findViewById(R.id.StartScanButton);
        startScanningButton.setonClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                startScanning();
            }
        });

        stopScanningButton = (Button) findViewById(R.id.StopScanButton);
        stopScanningButton.setonClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                stopScanning();
            }
        });
        stopScanningButton.setVisibility(View.INVISIBLE);

        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();
        }
    }

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

        // Check low energy support
        if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUetoOTH_LE)) {
            // Get a newer device
//            logError("No LE Support.");
            finish();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main,menu);
        return true;
    }

    @Override
    public boolean onoptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button,so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onoptionsItemSelected(item);
    }

    private ScanCallback leScanCallback = new ScanCallback() {
        @Override
        public void onScanResult(int callbackType,ScanResult result) {
//            Log.d("ci sono",result.getDevice().getName());
            if (result.getDevice().getName() != null && result.getDevice().getName().contains("A-"))
                stopScanning();
//            peripheralTextView.append("Device Name: " + result.getDevice().getName() + " RSSi: " + result.getRSSi() + "\n");

            // 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);

            connectDevice(result.getDevice());
//            bluetoothGatt = result.getDevice().connectGatt(MainActivity.this,false,gattClientCallback);
        }
    };

    @Override
    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;
            }
        }
    }

    public void startScanning() {
        System.out.println("start scanning");
        peripheralTextView.setText("");
        startScanningButton.setVisibility(View.INVISIBLE);
        stopScanningButton.setVisibility(View.VISIBLE);
        AsyncTask.execute(new Runnable() {
            @Override
            public void run() {
                btScanner.startScan(leScanCallback);
            }
        });
    }

    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);
            }
        });
    }

    private void connectDevice(BluetoothDevice device) {
//        log("Connecting to " + device.getAddress());
        GattClientCallback gattClientCallback = new GattClientCallback();
        bluetoothGatt = device.connectGatt(this,gattClientCallback);
    }

    protected void onStop() {
        // call the superclass method first
        super.onStop();
        Log.d("spegni","bluetooth");
        btScanner.stopScan(leScanCallback);

    }

    private class GattClientCallback extends BluetoothGattCallback {

        @Override
        public void onConnectionStateChange(BluetoothGatt gatt,int status,int newState) {
            super.onConnectionStateChange(gatt,status,newState);
//            log("onConnectionStateChange newState: " + newState);

            if (status == BluetoothGatt.GATT_FAILURE) {
//                logError("Connection Gatt failure status " + status);
                disconnectGattServer();
                return;
            } else if (status != BluetoothGatt.GATT_SUCCESS) {
                // handle anything not SUCCESS as failure
//                logError("Connection not GATT sucess status " + status);
                disconnectGattServer();
                return;
            }

            if (newState == BluetoothProfile.STATE_CONNECTED) {
//                log("Connected to device " + gatt.getDevice().getAddress());
                setConnected(true);
                gatt.discoverServices();
                Log.d("discoverRiuscito","onServicesdiscovered " + status + " " + gatt.discoverServices()
                        + " " + gatt.getServices());
            } else if (newState == BluetoothProfile.STATE_disCONNECTED) {
//                log("disconnected from device");
                disconnectGattServer();
            }
        }

        @Override
        public void onServicesdiscovered(BluetoothGatt gatt,int status) {
            super.onServicesdiscovered(gatt,status);


            if (status != BluetoothGatt.GATT_SUCCESS) {
//                log("Device service discovery unsuccessful,status " + status);
                return;
            }

            List<BluetoothGattCharacteristic> matchingcharacteristics = BluetoothUtils.findcharacteristics(gatt);
            if (matchingcharacteristics.isEmpty()) {
//                logError("Unable to find characteristics.");
                return;
            }

//            log("Initializing: setting write type and enabling notification");
            for (BluetoothGattCharacteristic characteristic : matchingcharacteristics) {
                characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT);
                enableCharacteristicNotification(gatt,characteristic);
            }
        }

        @Override
        public void onCharacteristicWrite(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic,int status) {
            super.onCharacteristicWrite(gatt,characteristic,status);
            if (status == BluetoothGatt.GATT_SUCCESS) {
//                log("Characteristic written successfully");
            } else {
//                logError("Characteristic write unsuccessful,status: " + status);
                disconnectGattServer();
            }
        }

        @Override
        public void onCharacteristicRead(BluetoothGatt gatt,int status) {
            super.onCharacteristicRead(gatt,status);
            if (status == BluetoothGatt.GATT_SUCCESS) {
//                log("Characteristic read successfully");
                readCharacteristic(characteristic);
            } else {
//                logError("Characteristic read unsuccessful,status: " + status);
                // Trying to read from the Time Characteristic? It doesnt have the property or permissions
                // set to allow this. normally this would be an error and you would want to:
                // disconnectGattServer();
            }
        }

        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic) {
            super.onCharacteristicChanged(gatt,characteristic);
//            log("Characteristic changed," + characteristic.getUuid().toString());
            readCharacteristic(characteristic);
        }

        private void enableCharacteristicNotification(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic) {
            boolean characteristicWriteSuccess = gatt.setCharacteristicNotification(characteristic,true);
            if (characteristicWriteSuccess) {
//                log("Characteristic notification set successfully for " + characteristic.getUuid().toString());
                if (BluetoothUtils.isEchoCharacteristic(characteristic)) {
                    initializeEcho();
                }
            } else {
//                logError("Characteristic notification set failure for " + characteristic.getUuid().toString());
            }
        }

        private void readCharacteristic(BluetoothGattCharacteristic characteristic) {
            byte[] messageBytes = characteristic.getValue();
//            log("Read: " + StringUtils.byteArrayInHexFormat(messageBytes));
            String message = StringUtils.stringFromBytes(messageBytes);
            if (message == null) {
//                logError("Unable to convert bytes to string");
                return;
            }

//            log("Received message: " + message);
        }
    }

    public void setConnected(boolean connected) {
        mConnected = connected;
    }

    private void sendMessage() {


        BluetoothGattCharacteristic characteristic = BluetoothUtils.findEchoCharacteristic(bluetoothGatt);
        if (characteristic == null) {
            return;
        }

        String message = "2";

        byte[] messageBytes = StringUtils.bytesFromString(message);
        if (messageBytes.length == 0) {
            return;
        }

        characteristic.setValue(messageBytes);
        boolean success = bluetoothGatt.writeCharacteristic(characteristic);
        if (success) {
//            log("Wrote: " + StringUtils.byteArrayInHexFormat(messageBytes));
        } else {
//            logError("Failed to write data");
        }
    }

    public void initializeEcho() {
        mEchoInitialized = true;
    }

    private class BtleScanCallback extends ScanCallback {

        private Map<String,BluetoothDevice> mScanResults;

        BtleScanCallback(Map<String,BluetoothDevice> scanResults) {
            mScanResults = scanResults;
        }

        @Override
        public void onScanResult(int callbackType,ScanResult result) {
            addScanResult(result);
        }

        @Override
        public void onBatchScanResults(List<ScanResult> results) {
            for (ScanResult result : results) {
                addScanResult(result);
            }
        }

        @Override
        public void onScanFailed(int errorCode) {
        }

        private void addScanResult(ScanResult result) {
            BluetoothDevice device = result.getDevice();
            String deviceAddress = device.getAddress();
            mScanResults.put(deviceAddress,device);
        }
    }

    public void disconnectGattServer() {
        mConnected = false;
        mEchoInitialized = false;
        if (bluetoothGatt != null) {
            bluetoothGatt.disconnect();
            bluetoothGatt.close();
        }
    }
}```

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。