Android - 蓝牙发现找不到任何设备

Ame*_*sys 39 android bluetooth receiver

我目前正在开发一个小应用程序,以开始使用蓝牙Android API提供的服务.

编辑 - >答案:

似乎问题是由于特定的Nexus 5设备.好像他们的蓝牙接收器不能正常工作.以下解决方案适用于其他设备

备注:

  1. 我在这里阅读了文档:http://developer.android.com/guide/topics/connectivity/bluetooth.html 以及本教程的以下源代码http://www.londatiga.net/it/programming/android/how-to-programmatically-scan-or-discover-android-bluetooth-device /位于/ lorensiuswlt/AndroBluetooth下的github上

  2. 我已经完成了几乎所有感兴趣的功能(例如检查适配器是否存在,启用/禁用蓝牙,查询配对的divices,设置适配器是否可发现).

问题:

实际上,当我启动.onDiscovery()方法时,找不到任何设备,即使在我的Nexus 5上的设置/蓝牙中找到了设备.

我是如何处理的:

public class MainActivity extends AppCompatActivity {
private BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

...

protected void onCreate(Bundle savedInstanceState) {
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
filter.addAction(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(mReceiver, filter); 
}
Run Code Online (Sandbox Code Playgroud)

过滤器工作良好,据我可以尝试,即ACTION_STATE_CHANGED(蓝牙启用)和两个ACTION_DISCOVERY _***.

然后成功地调用以下方法:

public void onDiscovery(View view)
{
    mBluetoothAdapter.startDiscovery();
}
Run Code Online (Sandbox Code Playgroud)

然后我有我的蓝牙接收器:

private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();

        if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
            final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);

            if (state == BluetoothAdapter.STATE_ON) {
                showToast("ACTION_STATE_CHANGED: STATE_ON");
            }
        }

        else if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
            mDeviceList = new ArrayList<>();
            showToast("ACTION_DISCOVERY_STARTED");
            mProgressDlg.show();
        }

        else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action) && !bluetoothSwitchedOFF) {
            mProgressDlg.dismiss();
            showToast("ACTION_DISCOVERY_FINISHED");

            Intent newIntent = new Intent(MainActivity.this, DeviceListActivity.class);

            newIntent.putParcelableArrayListExtra("device.list", mDeviceList);

            startActivity(newIntent);
        }

        else if (BluetoothDevice.ACTION_FOUND.equals(action)) {// When discovery finds a device
            // Get the BluetoothDevice object from the Intent
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            mDeviceList.add(device);
            showToast("Device found = " + device.getName());
        }
    }
};
Run Code Online (Sandbox Code Playgroud)

我在logcat中没有任何问题,在测试过程中没有发现任何问题.唯一的问题是在扫描结束时没有发现任何设备,当时可以发现许多可发现的设备.

我试图不要放太多代码,以免淹没主题.问我是否需要更多.

感谢您的阅读,并提前感谢您的答案.

nve*_*eek 73

你在运行什么版本的Android?如果是Android 6.x,我相信您需要为ACCESS_COURSE_LOCATION清单添加权限.例如:

ACCESS_FINE_LOCATION

我有一个类似的问题,这为我修复了它.

更新:直接从Google添加文档:

要通过蓝牙和Wi-Fi扫描访问附近外部设备的硬件标识符,您的应用现在必须拥有ACCESS_COARSE_LOCATION或拥有ACCESS_COURSE_LOCATION权限

  • @nverbeek感谢您的解决方案!也许您还应该提到仅仅在清单中设置权限是不够的,还需要在运行时请求它,因为两个权限都需要这样做. (3认同)

小智 64

派对迟到了,但这对其他人来说可能会派上用场.

你需要做两件事

  1. <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

要么 <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

到您的AndroidManifest.xml

  1. 通过使用类似的东西,确保您在运行时以及Android 6.0设备上请求权限

    int MY_PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION = 1; 
    ActivityCompat.requestPermissions(this,
            new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
            MY_PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION);
    
    Run Code Online (Sandbox Code Playgroud)

    就在此之前 mBluetoothAdapter.startDiscovery();

如果您不执行第2步,则无法在Android> = 6.0的设备上获取任何硬件标识符信息

更新/编辑:
将Android版本检查和警告对话框作为警告示例

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {  // Only ask for these permissions on runtime when running Android 6.0 or higher
    switch (ContextCompat.checkSelfPermission(getBaseContext(), Manifest.permission.ACCESS_COARSE_LOCATION)) {
        case PackageManager.PERMISSION_DENIED:
            ((TextView) new AlertDialog.Builder(this)
                    .setTitle("Runtime Permissions up ahead")
                    .setMessage(Html.fromHtml("<p>To find nearby bluetooth devices please click \"Allow\" on the runtime permissions popup.</p>" +
                            "<p>For more info see <a href=\"http://developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior-hardware-id\">here</a>.</p>"))
                    .setNeutralButton("Okay", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            if (ContextCompat.checkSelfPermission(getBaseContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                                ActivityCompat.requestPermissions(DeviceListActivity.this,
                                        new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
                                        REQUEST_ACCESS_COARSE_LOCATION);
                            }
                        }
                    })
                    .show()
                    .findViewById(android.R.id.message))
                    .setMovementMethod(LinkMovementMethod.getInstance());       // Make the link clickable. Needs to be called after show(), in order to generate hyperlinks
            break;
        case PackageManager.PERMISSION_GRANTED:
            break;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 为我工作但是startDiscovery()应该返回false,以防它无法访问.它仍然返回true,这有点误导...... (5认同)
  • 我已经把我的头撞在墙上三天了,试图让它扭曲。然后找到这个帖子,然后按照步骤2和宾果游戏!有用。谢谢 (2认同)
  • 将此代码添加到我的项目时,我有很多未解决的引用,但它是缺少的链接 - 谢谢! (2认同)
  • 我并没有被迫在装有Android 8.0.0的个人android设备上使用“步骤2”。相反,在另一台设备上,我被迫以这种方式请求许可。因此,我认为并非所有Android&gt; = 6.0的设备都必须执行“步骤2”。需要进一步调查... (2认同)