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