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

时间:2016-01-23 16:50:31

标签: 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,设置适配器可被发现)。

  3. 问题:

    当我启动.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); 
    }
    

    过滤器运行良好尽可能尝试,即ACTION_STATE_CHANGED(启用蓝牙功能)和两个ACTION_DISCOVERY _ ***。

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

    public void onDiscovery(View view)
    {
        mBluetoothAdapter.startDiscovery();
    }
    

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

    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());
            }
        }
    };
    

    我没有在logcat上发现任何问题,在我做的测试中没有发现任何问题。唯一的问题是扫描结束时没有设备被发现,当时有许多可发现的设备可用。

    我试图不要放太多代码以免泛滥主题。问我是否需要更多。

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

2 个答案:

答案 0 :(得分:68)

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

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

我有一个类似的问题,这为我解决了。

更新:在此处添加documentation direct from Google

  

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

答案 1 :(得分:56)

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

你需要做两件事

  1. 添加<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
  2. <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);
      

      mBluetoothAdapter.startDiscovery();

    2. 之前

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

      <强> UPDATE /编辑:
      将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;
          }
      }
      
相关问题