如何通过 Bluetooth Classic HID 建立从 Android 应用程序到其他设备的连接?

问题描述 投票:0回答:0

我是 Android 新手,不幸的是我必须创建一个应用程序,该应用程序将使用 Bluetooth Classic HID 从设备 (ESP32) 发送和接收数据。我能够找到设备,但无法以任何方式建立连接。我已经为此苦苦挣扎了几天,也许有人能给我指明方向?

安卓权限

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.BLUETOOTH"/>
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />

MainActivity 类

@SuppressLint({"MissingPermission"})
public class MainActivity extends AppCompatActivity {
    public static final String TAG = "MainActivity";

    public static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
    //public static final UUID MY_UUID = UUID.fromString("00001124-0000-1000-8000-00805F9B34FB");
    Boolean secured = false;

    public BluetoothAdapter mBluetoothAdapter;
    public ArrayList<BluetoothDevice> availableDevices = new ArrayList();
    public BluetoothDevice connectedDevice;
    public String usePin = "";
    public static String MY_DEVICE_NAME = "MY_DEVICE";
    public static String MY_DEVICE_MAC_ADDRESS = "B4:8A:0A:4E:FF:8E";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

        if (mBluetoothAdapter == null) {
            // Device doesn't support Bluetooth
            Log.e(TAG, "Device doesn't support Bluetooth");
            return;
        }

        if (!mBluetoothAdapter.isEnabled()) {
            // Bluetooth is not enabled, ask the user to enable it
            Log.d(TAG, "Bluetooth is not enabled");
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
                return;
            }
            mBluetoothAdapter.enable();
        }

        IntentFilter filter = new IntentFilter("android.bluetooth.device.action.FOUND");
        filter.addAction("android.bluetooth.adapter.action.DISCOVERY_FINISHED");
        registerReceiver(discoverFinishHandler, filter);
        IntentFilter filter2 = new IntentFilter("android.bluetooth.device.action.PAIRING_REQUEST");
        registerReceiver(pairRequestHandler, filter2);

        // Buttons
        Button btnToggle = findViewById(R.id.btnToggle);
        btnToggle.setOnClickListener(v -> {
            if(mBluetoothAdapter.isDiscovering())
            {
                Log.e(TAG, "Stop discovering bt devices");
                mBluetoothAdapter.cancelDiscovery();
            }
            else
            {
                Log.e(TAG, "Start discovering bt devices");
                StartDiscovery();
            }
        });

        Button connectToggle = findViewById(R.id.connectToggle);
        connectToggle.setOnClickListener(v -> {
            Log.e(TAG, "Connecting...");
            BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
            connectedDevice = mBluetoothAdapter.getRemoteDevice(MY_DEVICE_MAC_ADDRESS);

            if(connectedDevice != null && connectedDevice.getName() != null)
            {
                Log.e(TAG, connectedDevice.getName() + " FOUND!");

                BluetoothThread bluetoothThread = new BluetoothThread(connectedDevice, secured);
                bluetoothThread.start();
            }
            else
            {
                Log.e(TAG, "DEVICE NOT FOUND!");
            }
        });

        Button logdevicesButton = findViewById(R.id.logdevicesButton);
        logdevicesButton.setOnClickListener(v -> {
            Log.e(TAG, "Avaliable devices:");

            for (BluetoothDevice device : availableDevices)
            {
                Log.e(TAG, device.getName() + " | " + device.getAddress());
            }

            Set<BluetoothDevice> pairedDevices = BluetoothAdapter.getDefaultAdapter().getBondedDevices();
            if (pairedDevices.size() < 1) {
                Log.e(TAG, "No bonded devieces.");
            }
            else
            {
                Log.e(TAG, "Bonded devices:");
                if (pairedDevices.size() > 0) {
                    for (BluetoothDevice d : pairedDevices) {
                        Log.e(TAG, d.getName() + " | " + d.getAddress());
                    }
                }
            }

            if (pairedDevices.size() < 1)
            {
                Log.e(TAG, "No connected devices.");
            }
            else
            {
                LogConnectedDevices(BluetoothProfile.GATT, "GATT");
                LogConnectedDevices(BluetoothProfile.GATT_SERVER, "GATT SERVER");
            }
        });
    }

    public void StartDiscovery() {
        availableDevices.clear();
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (!mBluetoothAdapter.isEnabled()) {
            mBluetoothAdapter.enable();
        }

        mBluetoothAdapter.startDiscovery();
        Log.e(TAG, "Start Discovery...");
    }

    public void LogConnectedDevices(Integer profile, String profileName)
    {
        BluetoothManager bluetoothManager = (BluetoothManager) getApplicationContext().getSystemService(Context.BLUETOOTH_SERVICE);
        List<BluetoothDevice> devices = bluetoothManager.getConnectedDevices(profile);

        if(devices.size()<1)
        {
            Log.e(TAG, "No connected devices [" + profileName + "]");
            return;
        }

        Log.e(TAG, "Connected devices [" + profileName + "]:");

        for (BluetoothDevice d : devices)
        {
            Log.e(TAG, d.getName() + " | " + d.getAddress());
        }
    }

    private final BroadcastReceiver discoverFinishHandler = new BroadcastReceiver()
    {
        public void onReceive(Context context, Intent intent)
        {
        String action = intent.getAction();
        if ("android.bluetooth.device.action.FOUND".equals(action))
        {
            BluetoothDevice device = (BluetoothDevice) intent.getParcelableExtra("android.bluetooth.device.extra.DEVICE");
            if (!availableDevices.contains(device))
            {
                availableDevices.add(device);
                Log.e(TAG, "Discover: " + device.getName() + "(" + device.getAddress() + ")");
            }
        }
        else if ("android.bluetooth.adapter.action.DISCOVERY_FINISHED".equals(action))
        {
            Log.e(TAG, "Discovery Finished ");
        }
        }
    };

    private final BroadcastReceiver pairRequestHandler = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
        if (!usePin.equals("")) {
            String action = intent.getAction();
            if (action.equals("android.bluetooth.device.action.PAIRING_REQUEST")) {
                try {
                    Log.e(TAG, "Start Connecting with PIN....");
                    this.abortBroadcast();
                    BluetoothDevice device = (BluetoothDevice)intent.getParcelableExtra("android.bluetooth.device.extra.DEVICE");
                    byte[] pinBytes = usePin.getBytes(StandardCharsets.UTF_8);
                    device.setPin(pinBytes);
                    device.setPairingConfirmation(true);
                } catch (Exception var6) {
                    Log.e(TAG, "Error occurs when trying to auto pair");
                    var6.printStackTrace();
                }
            }
        }
        }
    };
}

蓝牙线程

@SuppressLint({"MissingPermission"})
public class BluetoothThread extends Thread {
    private BluetoothSocket mSocket;
    private InputStream mInStream;
    BluetoothDevice mDevice;

    public BluetoothThread(final BluetoothDevice device, final Boolean secured) {
        BluetoothSocket tmp = null;
        mDevice = device;

        try {
            if(secured)
                tmp = device.createRfcommSocketToServiceRecord(MainActivity.MY_UUID);
            else
                tmp = device.createInsecureRfcommSocketToServiceRecord(MainActivity.MY_UUID);
        } catch (IOException e) {
            Log.e(MainActivity.TAG, "Socket create() failed", e);
        }
        mSocket = tmp;
    }

    public void run() {
        Log.e(MainActivity.TAG, mDevice.getName() + " bluetooth thread started");
        try {
            mSocket.connect();
            mInStream = mSocket.getInputStream();
            byte[] buffer = new byte[1024];

            int bytes;

            while (true) {
                Log.e(MainActivity.TAG, "reading data...");
                try {
                    Log.e(MainActivity.TAG, "reading data...");
                    bytes = mInStream.read(buffer);
                    // Do something with the received data
                    Log.e(MainActivity.TAG, "recieved data: " + String.valueOf(bytes));
                } catch (IOException e) {
                    Log.e(MainActivity.TAG, "Error reading from input stream", e);
                    break;
                }
            }
        } catch (IOException e) {
            Log.e(MainActivity.TAG, "Error connecting to device", e);
        }
    }

    public void cancel() {
        try {
            mSocket.close();
        } catch (IOException e) {
            Log.e(MainActivity.TAG, "Error closing socket", e);
        }
    }

}

java android bluetooth hid
© www.soinside.com 2019 - 2024. All rights reserved.