You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Android蓝牙搜索异常:无法检测附近Bluetooth设备技术求助

解决蓝牙设备搜索不到的问题

看起来你的代码逻辑本身没问题,但权限配置和蓝牙状态检查的缺失是导致搜不到设备的核心原因,我帮你一步步修正:

1. 补全权限配置(最关键)

Android系统从6.0开始对蓝牙扫描增加了位置权限限制,12及以上版本又新增了专属蓝牙权限,你的Manifest权限完全不够。更新你的AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.findbluetoothdemo">

    <!-- 适配Android 11及以下的蓝牙权限 -->
    <uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
    
    <!-- 蓝牙扫描必须的位置权限(Android 6.0+) -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    
    <!-- Android 12+ 专属蓝牙权限 -->
    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
    
    <!-- 声明设备支持蓝牙(可选但推荐) -->
    <uses-feature android:name="android.hardware.bluetooth" android:required="true" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

2. 添加动态权限请求

光在Manifest里声明还不够,危险权限需要在代码中主动请求。在MainActivity.java中添加权限请求逻辑:

首先导入必要的包:

import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Build;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

然后添加权限请求方法:

private void requestBluetoothPermissions() {
    String[] requiredPermissions;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        // Android 12+ 需要的权限
        requiredPermissions = new String[]{
                Manifest.permission.BLUETOOTH_SCAN,
                Manifest.permission.BLUETOOTH_CONNECT,
                Manifest.permission.ACCESS_FINE_LOCATION
        };
    } else {
        // Android 6.0-11 需要的权限
        requiredPermissions = new String[]{
                Manifest.permission.ACCESS_FINE_LOCATION,
                Manifest.permission.BLUETOOTH_ADMIN,
                Manifest.permission.BLUETOOTH
        };
    }

    // 检查是否有权限,没有就请求
    if (ContextCompat.checkSelfPermission(this, requiredPermissions[0]) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, requiredPermissions, 100);
    }
}

onCreate方法末尾调用这个方法:

@Override
protected void onCreate(Bundle savedInstanceState) {
    // ... 你的原有代码 ...
    registerReceiver(broadcastReceiver ,intentFilter);
    // 添加权限请求
    requestBluetoothPermissions();
}

3. 完善蓝牙状态检查

你的代码没有检查蓝牙是否开启,也没有处理设备不支持蓝牙的情况。修改searchFunction方法:

public void searchFunction(View view) {
    // 先检查权限
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        requestBluetoothPermissions();
        return;
    }

    // 检查设备是否支持蓝牙
    if (bluetoothAdapter == null) {
        statusTextView.setText("Device doesn't support Bluetooth");
        searchButton.setEnabled(false);
        return;
    }

    // 检查蓝牙是否开启,没开就请求开启
    if (!bluetoothAdapter.isEnabled()) {
        Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        startActivityForResult(enableBtIntent, 1);
        return;
    }

    // 清空旧数据,显示搜索提示
    bluetoothDevices.clear();
    addresses.clear();
    bluetoothDevices.add("Searching for devices...");
    statusTextView.setText("Searching...");
    searchButton.setEnabled(false);
    arrayAdapter.notifyDataSetChanged();

    // 如果正在扫描,先停止再重新开始
    if (bluetoothAdapter.isDiscovering()) {
        bluetoothAdapter.cancelDiscovery();
    }
    bluetoothAdapter.startDiscovery();
}

另外,重写onActivityResult处理蓝牙开启后的扫描:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == 1) {
        if (resultCode == RESULT_OK) {
            // 蓝牙开启成功,自动开始扫描
            searchFunction(searchButton);
        } else {
            statusTextView.setText("Bluetooth is required to search devices");
            searchButton.setEnabled(true);
        }
    }
}

4. 修复代码中的小问题

  • 你原来的searchFunction里先添加提示文字再立刻清空,导致用户看不到搜索提示,上面的代码已经调整了顺序
  • 日志里的拼写错误:Nmae改成Name,不影响功能但更规范:
    Log.i("Device Found","Name :"+name+" Address :"+address+" RSSI :"+rssi);
    

最后注意事项

  • 蓝牙扫描比较耗电,建议添加超时停止逻辑,比如用Handler延迟调用bluetoothAdapter.cancelDiscovery()
  • 如果你的目标是BLE(低功耗蓝牙)设备,经典蓝牙的startDiscovery无法扫描到,需要改用BluetoothLeScanner API

内容的提问来源于stack exchange,提问作者TanikshG

火山引擎 最新活动