首页 > 解决方案 > 开始蓝牙扫描时未找到设备

问题描述

我目前正在开发一个 android 应用程序来控制蓝牙设备,但即使我可以从内置设置>蓝牙菜单中找到它们,也没有显示可用的设备。

我最初遵循了开箱即用的android 入门示例,但无法使其工作。然后我遇到了几个类似的帖子并尝试了这些帖子,但仍然无法使其工作。到目前为止,这是我的代码:```

public class MainActivity extends AppCompatActivity {
private static final int REQUEST_LOCATION_BT = 3;
private static final int REQUEST_ENABLE_BT = 2;
private BluetoothAdapter bluetoothAdapter;
private ArrayList<String> deviceList;
private ActivityMainBinding binding;
private ArrayAdapter<String> listAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    binding = ActivityMainBinding.inflate(getLayoutInflater());
    setContentView(binding.getRoot());

    requiredSetup();
    setupListView();


}

private void setupListView() {
    Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
    deviceList = new ArrayList<>();
    if (pairedDevices.size() > 0) {
        // There are paired devices. Get the name and address of each paired device.
        for (BluetoothDevice device : pairedDevices) {
            deviceList.add(device.getName());
            //String deviceHardwareAddress = device.getAddress(); // MAC address
        }
    }


    listAdapter = new ArrayAdapter<>(this,
            android.R.layout.simple_list_item_1, deviceList);

    binding.listView.setAdapter(listAdapter);

}

private void requiredSetup() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        if (ContextCompat.checkSelfPermission(getApplicationContext(),
                Manifest.permission.ACCESS_BACKGROUND_LOCATION)
                != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(
                    MainActivity.this,
                    new String[]{Manifest.permission.ACCESS_BACKGROUND_LOCATION},
                    REQUEST_LOCATION_BT);
        }
    }

    // checking if device supports bluetooth
    bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    if (bluetoothAdapter == null) {
        // Device doesn't support Bluetooth
        Toast.makeText(this, "Device doesnt support bluetooth", Toast.LENGTH_SHORT).show();
        return;
    }

    // enabling bluetooth if disabled
    if (!bluetoothAdapter.isEnabled()) {
        Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
    }

}

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_ENABLE_BT && resultCode == RESULT_OK) {
        Toast.makeText(this, "Bluetooth enabled", Toast.LENGTH_SHORT).show();
    } else if (requestCode == REQUEST_ENABLE_BT && resultCode == RESULT_CANCELED) {
        Toast.makeText(this, "App requires bluetooth to function", Toast.LENGTH_SHORT).show();
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
    if (requestCode == REQUEST_LOCATION_BT) {
        if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            // Permission granted, yay! Start the Bluetooth device scan.
            startScan();
        } else {
            // Alert the user that this application requires the location permission to perform the scan.
            Toast.makeText(this, "Requires location permission to work", Toast.LENGTH_SHORT).show();
        }
    }
}

/**
 * initializes device discovery. The list of devices are sent to the broadcast receiver
 * The discovery process usually involves an inquiry scan of about 12 seconds,
 * followed by a page scan of each device found to retrieve its Bluetooth name.
 */
private void startScan() {
    // If we're already discovering, stop it
    if (bluetoothAdapter.isDiscovering()) {
        Toast.makeText(this, "stopping discovery", Toast.LENGTH_SHORT).show();
        bluetoothAdapter.cancelDiscovery();
    } else {
        try {
            // Register for broadcasts when a device is discovered
            IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
            this.registerReceiver(mReceiver, filter);
            // Request discover from BluetoothAdapter
            bluetoothAdapter.startDiscovery();
            binding.progressBar.setVisibility(View.VISIBLE);

        } catch (IllegalArgumentException e) {
            e.printStackTrace();
            Toast.makeText(this, "receivers not registered", Toast.LENGTH_SHORT).show();
        }

    }
}

/**
 * @param view the button view that is pressed and the scanning begins
 */
public void searchDevices(View view) {
    // checking if location permissions enabled
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, REQUEST_LOCATION_BT);
    } else {
        startScan();
    }
}

/**
 * The BroadcastReceiver that listens for discovered devices and changes the title when
 * discovery is finished
 */
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        Toast.makeText(getApplicationContext(), "reeiver working", Toast.LENGTH_SHORT).show();

        // When discovery finds a device
        if (BluetoothDevice.ACTION_FOUND.equals(action)) {
            // Get the BluetoothDevice object from the Intent
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            // If it's already paired, skip it, because it's been listed already
            if (device != null && device.getBondState() != BluetoothDevice.BOND_BONDED) {
                listAdapter.add(device.getName() + "\n" + device.getAddress());
                Log.i("NEW DEVICE", device.getName());
                listAdapter.notifyDataSetChanged();
            }
            // When discovery is finished, change the Activity title
        } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
            //setProgressBarIndeterminateVisibility(false);
            //setTitle(R.string.select_device);
            binding.progressBar.setVisibility(View.INVISIBLE);
            if (listAdapter.getCount() == 0) {
                Toast.makeText(context, "no devices found", Toast.LENGTH_SHORT).show();
            }
        } else if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
            Toast.makeText(context, "Bluetooth state changed", Toast.LENGTH_SHORT).show();
        } else if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
            Toast.makeText(context, "Discovery started", Toast.LENGTH_SHORT).show();

        }
    }
};


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

    // Make sure we're not doing discovery anymore
    if (bluetoothAdapter != null) {
        bluetoothAdapter.cancelDiscovery();
    }

    // Unregister broadcast listeners
    this.unregisterReceiver(mReceiver);
}}

这是我的清单权限:

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

这是我的存储库。如果有人能在这里阐明一下,那将非常有帮助。

标签: androidbluetooth

解决方案


看起来代码很好。问题出在目标 SDK 版本上。将版本从 30 更改为 28 后,它起作用了。感谢MatejC的回答。


推荐阅读