Bluetooth startDiscovery()在Android 10上不起作用

问题描述 投票:1回答:1

我陷入了一个问题。我尝试了Stack Overflow和其他网站的一些提示。

我想编写一个应用程序,该应用程序搜索周围的所有蓝牙设备,如果找到了匹配的设备(以MAC地址作为参考,该应用程序将开始连接。)>

因此,我已经编写了一个测试应用程序以测试发现功能。但是不幸的是,在我的Android 10设备上启动发现过程存在一个大问题。我有一个较旧的Samsung S3 Mini,上面装有Android 4.1.2(SDK 16),我的代码可以正常工作。在Android 10设备上,startDiscovery()返回false,与Android 4设备不同,后者返回true。他们在android开发人员页面上说,如果发生错误,则false为返回值。 BroadcastReceiver应该可以正常工作,因为Android 9手机上的应用程序检测到设置中已启动蓝牙搜索。问题仅在于startDiscovery()函数(在我看来)。

我正在开始发现过程之前检查所有权限和蓝牙状态。但是我认为,它不能是书面代码,因为它可以在旧设备上完美运行。也许我缺少一些较新的设备。

编辑

正如Thomas Morris在下面解释的那样,在Android 10中,您需要由用户打开位置。在Android 9或更低版本中,Thomas Morris的回答是正确的,因为在29以下的所有SDK中,仅需要权限,而无需启用的位置服务。

是否有解决方案可以避免要求用户自行打开位置?

这是我的MainActivity:

public class MainActivity extends AppCompatActivity {
final String TAG = "MainActivity";
BluetoothAdapter bluetoothAdapter;
int status = 0;     //0 = start discovering, 1 = cancel discovering

public static final int REQUEST_ACCESS_COARSE_LOCATION = 1;
public static final int REQUEST_ENABLE_BLUETOOTH = 11;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    registerReceiver(receiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
    registerReceiver(receiver, new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_STARTED));
    registerReceiver(receiver, new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED));

    bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

    checkBluetoothState();

    final Button test = findViewById(R.id.testbutton);
    test.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if(status == 0) {
                if(bluetoothAdapter != null && bluetoothAdapter.isEnabled()) {
                    if (checkCoarseLocationPermission()) {
                        Boolean result = bluetoothAdapter.startDiscovery(); //start discovering and show result of function
                        Toast.makeText(getApplicationContext(), "Start discovery result: " + result, Toast.LENGTH_SHORT).show();
                        Log.d(TAG, "Start discovery: " + result);
                        test.setText("Stop");
                        status = 1;
                    }
                }else{
                    checkBluetoothState();
                }
            }else{
                Log.d(TAG,"Stop");
                status = 0;
                bluetoothAdapter.cancelDiscovery();
                test.setText("Start");
            }
        }
    });

    checkCoarseLocationPermission();
}

private boolean checkCoarseLocationPermission() {
    //checks all needed permissions
    if(ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED){
        ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.ACCESS_COARSE_LOCATION}, REQUEST_ACCESS_COARSE_LOCATION);
        return false;
    }else{
        return true;
    }

}

private void checkBluetoothState() {
    //checks if bluetooth is available and if it´s enabled or not
    if(bluetoothAdapter == null){
        Toast.makeText(getApplicationContext(), "Bluetooth not available", Toast.LENGTH_SHORT).show();
    }else{
        if(bluetoothAdapter.isEnabled()){
            if(bluetoothAdapter.isDiscovering()){
                Toast.makeText(getApplicationContext(), "Device is discovering...", Toast.LENGTH_SHORT).show();
            }else{
                Toast.makeText(getApplicationContext(), "Bluetooth is enabled", Toast.LENGTH_SHORT).show();
            }
        }else{
            Toast.makeText(getApplicationContext(), "You need to enabled bluetooth", Toast.LENGTH_SHORT).show();
            Intent enabledIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enabledIntent, REQUEST_ENABLE_BLUETOOTH);
        }
    }
}

// Create a BroadcastReceiver for ACTION_FOUND.
private final BroadcastReceiver receiver = new BroadcastReceiver() {
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (BluetoothDevice.ACTION_FOUND.equals(action)) {
            // Discovery has found a device. Get the BluetoothDevice
            // object and its info from the Intent.
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            String deviceName = device.getName();
            String deviceHardwareAddress = device.getAddress(); // MAC address
            Log.d(TAG,"Device found: " + deviceName + "|" + deviceHardwareAddress);
            Toast.makeText(getApplicationContext(), "FOUND: " + deviceName + "|" + deviceHardwareAddress, Toast.LENGTH_SHORT).show();
        }

        if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
            //report user
            Log.d(TAG,"Started");
            Toast.makeText(getApplicationContext(), "STARTED", Toast.LENGTH_SHORT).show();
        }

        if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
            //change button back to "Start"
            status = 0;
            final Button test = findViewById(R.id.testbutton);
            test.setText("Start");
            //report user
            Log.d(TAG,"Finished");
            Toast.makeText(getApplicationContext(), "FINISHED", Toast.LENGTH_SHORT).show();
        }

        if(BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)){
            final int extra = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,-1);
            if(extra == (BluetoothAdapter.STATE_ON)) {
                if (bluetoothAdapter.isDiscovering()) {
                    bluetoothAdapter.cancelDiscovery();
                }
                Boolean b = bluetoothAdapter.startDiscovery();
                Toast.makeText(getApplicationContext(), "Start discovery" + b, Toast.LENGTH_SHORT).show();
            }
        }
    }
};


@Override
protected void onDestroy() {
    super.onDestroy();
    if (bluetoothAdapter.isDiscovering()){
        bluetoothAdapter.cancelDiscovery();
    }

    unregisterReceiver(receiver);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
    super.onActivityResult(requestCode,resultCode,data);

    if(requestCode == REQUEST_ENABLE_BLUETOOTH){
        checkBluetoothState();
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults){
    super.onRequestPermissionsResult(requestCode,permissions,grantResults);

    switch (requestCode){
        case REQUEST_ACCESS_COARSE_LOCATION:
            if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
                Toast.makeText(getApplicationContext(),"Permission granted",Toast.LENGTH_SHORT).show();
            }else{
                Toast.makeText(getApplicationContext(),"Permission denied",Toast.LENGTH_SHORT).show();
            }
    }
}



}

这是我的清单:

<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>

<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-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

我陷入了一个问题。我尝试了Stack Overflow和其他网站的一些提示。我想编写一个应用程序,该应用程序搜索周围的所有蓝牙设备以及匹配的设备...

android bluetooth android-bluetooth
1个回答
0
投票

在应用程序上启用位置权限。为此,请转到:

© www.soinside.com 2019 - 2024. All rights reserved.