Подтвердить что ты не робот

Android - обнаружение Bluetooth не находит никакого устройства

В настоящее время я работаю над небольшим приложением, чтобы начать работу с услугами, которые может предоставить Bluetooth Android API.

Изменить → Ответ:

Кажется, что проблема связана с конкретными устройствами Nexus 5. Похоже, их приемник Bluetooth работает не очень хорошо. Решение ниже должно работать для других устройств.

Примечание:

Вопрос:

Фактически устройство не найдено, когда я запускаю метод .onDiscovery(), даже если устройства найдены из настроек /Bluetooth на моем 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 (при включении bluetooth) и двух ACTION_DISCOVERY _ ***.

Затем успешно применяется следующий метод:

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

А потом у меня есть приемник Bluetooth:

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

У меня нет каких-либо проблем, выходящих из логарифма, и я не заметил никаких проблем во время теста, который я сделал. Единственная проблема заключается в том, что не обнаружено устройство в конце сканирования, когда доступно много доступных для поиска файлов arround.

Я старался не вводить слишком много кода, чтобы не наводнять тему. Спросите меня, нужно ли вам больше.

Спасибо, что прочитал меня и заблаговременно за вас ответил.

4b9b3361

Ответ 1

Какую версию Android вы используете? Если это Android 6.x, я считаю, что вам нужно добавить разрешение ACCESS_COURSE_LOCATION на ваш манифест. Например:

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

У меня была аналогичная проблема, и это исправило это для меня.

UPDATE: Добавление документации прямо из Google по этому вопросу:

Чтобы получить доступ к идентификаторам оборудования соседних внешних устройств через Bluetooth и сканирование Wi-Fi, ваше приложение должно теперь иметь разрешения ACCESS_FINE_LOCATION или ACCESS_COARSE_LOCATION

Ответ 2

Бит опоздал на вечеринку, но это может пригодиться другим людям.

Вам нужно сделать две вещи

  • Добавить <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);
    

    непосредственно перед mBluetoothAdapter.startDiscovery();

Если вы не сделаете шаг 2, вы не сможете получить информацию об аппаратном идентификаторе на устройстве с Android >= 6.0

UPDATE/EDIT:
Пример с диалоговым окном проверки и предупреждения версии 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;
    }
}