【问题标题】:Android Bluetooth StartDiscovery() always returns falseAndroid 蓝牙 StartDiscovery() 总是返回 false
【发布时间】:2021-11-18 16:12:53
【问题描述】:

我试图发现附近的蓝牙设备,但 startDiscovery() 总是返回 false,就好像它不工作一样。因此它无法找到设备。

我看到除了蓝牙和 Bluetooth_Admin 之外,我必须包含 Coarse_Location 权限,但无论如何,它不起作用。

这是我现在正在尝试的代码,其中主要有痕迹来看看它是如何工作的:

public class BluetoothActivity extends AppCompatActivity {

    RecyclerView recyclerView;
    ArrayList<BluetoothDevice> dispositivos;
    BTAdapter adaptador;
    BluetoothAdapter mBluetoothAdapter;
    Button buscar;

    final int REQUEST_ACCESS_COARSE_LOCATION = 16;
    @Override
    public void onCreate(Bundle savedInsanceState){
        super.onCreate(savedInsanceState);
        setContentView(R.layout.bluetooth_activity);

        recyclerView = findViewById(R.id.recycler_view);
        recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));

        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

        if(mBluetoothAdapter != null) {
            Toast.makeText(this, "No es nulo", Toast.LENGTH_SHORT).show();
            if (!mBluetoothAdapter.isEnabled()) {
                Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                startActivityForResult(intent, RESULT_OK);
            }

            IntentFilter filter = new IntentFilter();

            filter.addAction(BluetoothDevice.ACTION_FOUND);
            filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
            filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);

            registerReceiver(mReceiver, filter);

        }

        buscar = findViewById(R.id.buscar);
        buscar.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(BluetoothActivity.this, "Empezar a buscar", Toast.LENGTH_SHORT).show();

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    switch (ContextCompat.checkSelfPermission(BluetoothActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION)) {
                        case PackageManager.PERMISSION_DENIED:
                            ActivityCompat.requestPermissions(BluetoothActivity.this,
                                    new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
                                    REQUEST_ACCESS_COARSE_LOCATION);

                            break;
                        case PackageManager.PERMISSION_GRANTED:
                            boolean a = mBluetoothAdapter.startDiscovery();
                            Toast.makeText(BluetoothActivity.this, "Start discovery es "+a, Toast.LENGTH_SHORT).show();
                            break;
                    }
                }
            }
        });
    }

    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if(BluetoothDevice.ACTION_FOUND.equals(action)){
                Toast.makeText(BluetoothActivity.this, "Encontrado", Toast.LENGTH_SHORT).show();
            }
        }
    };

    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           String permissions[], int[] grantResults) {
        switch (requestCode) {
            case REQUEST_ACCESS_COARSE_LOCATION: {
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    boolean a = mBluetoothAdapter.startDiscovery();
                    Toast.makeText(BluetoothActivity.this, "Start discovery es "+a, Toast.LENGTH_SHORT).show();
                }
                else {
                    //exit application or do the needful
                }
                return;
            }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(mReceiver);
    }


}

这里是 android manifest 中的权限:


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

    <uses-feature android:name="android.hardware.bluetooth" />

更新:当我点击查看 startDiscovery 方法的描述时,我得到了这个,RequiresPermission 和 startDiscovery 是红色的,说“无法解析方法”和 Manifest.permission.BLUETOOTH_ADMIN 下划线并说“找不到方法值”:

@RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
    public boolean startDiscovery() {
        if (getState() != STATE_ON) {
            return false;
        }
        try {
            mServiceLock.readLock().lock();
            if (mService != null) {
                return mService.startDiscovery(getOpPackageName());
            }
        } catch (RemoteException e) {
            Log.e(TAG, "", e);
        } finally {
            mServiceLock.readLock().unlock();
        }
        return false;
    }

【问题讨论】:

  • 你解决了吗?

标签: android bluetooth find discovery


【解决方案1】:

您是否检查过该位置已在您的设备上激活?

即使授予位置权限,当它被禁用时,蓝牙API也不起作用。

所以我建议你添加以下代码以确保权限有效:

LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
boolean isGpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
if (!isGpsEnabled) {
  startActivityForResult(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS), MY_REQUEST_CODE);
}

【讨论】:

  • 谢谢,这为我解决了。永远不会想到需要为蓝牙设备激活 GPS 位置。
【解决方案2】:

我不得不将蓝牙权限转为“始终允许”。我在位置设置中手动将其设置为“始终允许”。我还没有测试你是否可以用你的应用程序自动设置它。

蓝牙访问“仅在使用时”应用不起作用!

小米红米 Note 10 Pro / Android 11

【讨论】:

    【解决方案3】:

    如果您打算在 Google Play 商店中分发您的应用程序,那么降级到 28 将不再有效。 我遇到了同样的问题(Android 9 有效,Android 10:startDiscovery() 返回 false)。我唯一要做的就是将权限从 ACCESS_COARSE_LOCATION 更改为 ACCESS_FINE_LOCATION。不要忘记随处更改它!我明白了,它在您的清单中,但在您的活动中您请求 ACCESS_COARSE_LOCATION。也不要忘记改变 onRequestPermissionsResult ;)

    最后一件事:在设置中应该启用定位服务。还有允许BT扫描的选项。

    【讨论】:

      【解决方案4】:

      我遇到了同样的问题。即使在授予位置权限后,我也没有让它工作。但后来我发现我的 BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE 没有设置。然后我添加了以下代码,一切正常(在 OnCreate 内)。

      if(bluetoothAdapter.getScanMode()!=BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE){ System.out.println(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE); }

      完整代码:

      package com.example.bluetoothapi22;
      
      import androidx.appcompat.app.AppCompatActivity;
      
      import android.Manifest;
      import android.bluetooth.BluetoothAdapter;
      import android.bluetooth.BluetoothDevice;
      import android.content.BroadcastReceiver;
      import android.content.Context;
      import android.content.Intent;
      import android.content.IntentFilter;
      import android.location.LocationManager;
      import android.os.Bundle;
      import android.provider.Settings;
      import android.view.View;
      import android.widget.Button;
      import android.widget.ListView;
      import android.widget.TextView;
      
      public class MainActivity extends AppCompatActivity {
      
          TextView textView;
          Button button;
          ListView listView;
          BluetoothAdapter bluetoothAdapter;
      
          public void search(View view){
              textView.setText("Searching...");
              button.setEnabled(false);
              System.out.println(bluetoothAdapter.startDiscovery());
          }
      
          private final BroadcastReceiver broadcastReceiver=new BroadcastReceiver() {
              @Override
              public void onReceive(Context context, Intent intent) {
                  String action=intent.getAction();
                  System.out.println(action);
              }
          };
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main);
              textView=findViewById(R.id.loadingTextView);
              button=findViewById(R.id.searchButton);
              listView=findViewById(R.id.listView);
              bluetoothAdapter=BluetoothAdapter.getDefaultAdapter();
              IntentFilter intentFilter=new IntentFilter();
              intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
              intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
              intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
              intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
              registerReceiver(broadcastReceiver,intentFilter);
              if(!bluetoothAdapter.isEnabled()){
                  System.out.println(bluetoothAdapter.enable());
              }
              if(bluetoothAdapter.isDiscovering()){
                  System.out.println(bluetoothAdapter.cancelDiscovery());
              }
              if(bluetoothAdapter.getScanMode()!=BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE){
                  System.out.println(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
              }
          }
      }
      

      【讨论】:

        【解决方案5】:

        可能是 targetSdkVersion 29 权限相关的问题。 一个简单的解决方法是降级目标 SDK。在文件 build.gradle (app) 更改例如:

                targetSdkVersion 29 -> targetSdkVersion 28
        

        【讨论】:

          【解决方案6】:

          我遇到了类似的问题。后来发现是位置权限有问题。我把APP设置为禁用定位,导致一直错误返回;

          【讨论】:

            【解决方案7】:

            唯一对我有用的是将 targetSdkVersion 降级到 28。当然位置权限仍然适用。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2020-08-30
              • 2023-03-19
              • 2012-05-20
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多