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.
Я старался не вводить слишком много кода, чтобы не наводнять тему. Спросите меня, нужно ли вам больше.
Спасибо, что прочитал меня и заблаговременно за вас ответил.
Ответы
Ответ 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
-
Убедитесь, что вы запрашиваете разрешение на время выполнения также для устройств 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;
}
}