#android #bluetooth
#Android #bluetooth
Вопрос:
я борюсь с одной из проблем, связанных с сопряжением Bluetooth на моем устройстве (Samsung Galaxy S6). У меня есть просмотр списка, где я заполняю имена своих устройств BLE, как показано на рисунке ниже
Когда пользователь нажимает на любой BLE, он должен получить сопряжение с этим BLE. Мои усилия по написанию кода приведены ниже:
-
Для вызова широковещательного приемника (для повторения имени BLEs)
// Quick permission check if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { int permissionCheck = getActivity().checkSelfPermission("Manifest.permission.ACCESS_FINE_LOCATION"); permissionCheck = getActivity().checkSelfPermission("Manifest.permission.ACCESS_COARSE_LOCATION"); if (permissionCheck != 0) { this.requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, 1001); //Any number } } getActivity().registerReceiver(FoundReceiver, new IntentFilter(BluetoothDevice.ACTION_FOUND)); IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); getActivity().registerReceiver(FoundReceiver, filter); mBluetoothAdapter.startDiscovery();
-
Ниже приведен код для заполнения списка BLES, который работает нормально.
private final BroadcastReceiver FoundReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); // When discovery finds a new device if (BluetoothDevice.ACTION_FOUND.equals(action)) { // Get the BluetoothDevice object from the Intent BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); if (!bleName.contains(device)) { if(device.getName() != null){ bleName.add(device.getName()); } Toast.makeText(getActivity(), "name: " device.getName() " " device.getAddress(), Toast.LENGTH_LONG).show(); bedListADPT = new BleList(context, bleName); listView.setAdapter(bedListADPT); if(!dvcNameBle.containsKey(device.getName())) { dvcNameBle.put(device.getName(), device); } bedListADPT.notifyDataSetChanged(); } } // When discovery cycle finished if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) { if (bleName == null || bleName.isEmpty()) { Toast.makeText(getActivity(), "No Devices", Toast.LENGTH_LONG).show(); } } } };
-
Теперь, когда пользователь нажмет на элемент списка, он должен получить сопряжение с этим именем BLE.
-
Щелкните событие для элемента списка
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) { Toast.makeText(getActivity(),bedListADPT.getItem(position).toString(),Toast.LENGTH_LONG).show(); IntentFilter filter = new IntentFilter("android.bluetooth.device.action.PAIRING_REQUEST"); /** * Registering a new BTBroadcast receiver from the Main Activity context * with pairing request event */ selectedDevice = bedListADPT.getItem(position).toString(); getActivity().registerReceiver(new PairingRequest(dvcNameBle,selectedDevice), filter); Toast.makeText(getActivity(),"" dvcNameBle.size(),Toast.LENGTH_LONG).show(); } });
И широковещательный приемник ниже, чтобы получить сопряжение с BLE
public class PairingRequest extends BroadcastReceiver {
private static HashMap<String, BluetoothDevice> mdvcNameBle = new HashMap<String, BluetoothDevice>();
private static String mselectedDevice = "";
public PairingRequest() {
super();
}
public PairingRequest(HashMap<String, BluetoothDevice> dvcNameBle, String mselectedDevice){
super();
this.mdvcNameBle = dvcNameBle;
this.mselectedDevice = mselectedDevice;
}
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("android.bluetooth.device.action.PAIRING_REQUEST")) {
try {
BluetoothDevice device = mdvcNameBle.get(mselectedDevice);
int pin=intent.getIntExtra("android.bluetooth.device.extra.PAIRING_KEY", 0);
//the pin in case you need to accept for an specific pin
Log.d("PIN", " " intent.getIntExtra("android.bluetooth.device.extra.PAIRING_KEY",0));
//maybe you look for a name or address
Log.d("Bonded", device.getName());
byte[] pinBytes;
pinBytes = ("" pin).getBytes("UTF-8");
device.setPin(pinBytes);
//setPairing confirmation if neeeded
device.setPairingConfirmation(true);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Внутри файла манифеста я объявил широковещательный приемник и требуемые разрешения для приложения
<receiver android:name=".PairingRequest">
<intent-filter>
<action android:name="android.bluetooth.device.action.PAIRING_REQUEST" />
</intent-filter>
</receiver>
<uses-permission android:name="android.permission.BLUETOOTH" android:label="BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Когда я звоню
Запрос сопряжения
ничего не происходит; это означает, что без исключения сопряжения нет.
Любая помощь будет действительно ощутимой. Пожалуйста, помогите мне избавиться от этой проблемы.
Комментарии:
1. Я думаю, что у вас проблема с разрешениями. С Android 6.0 вы должны запросить разрешение во время выполнения. Посмотри на это developer.android.com/training/permissions/requesting.html
2. ОК. Конечно, я проверю это и свяжусь с вами.
3. Любые комментарии или предложения будут действительно полезны.
Ответ №1:
Я получил ответ
public boolean createBond(BluetoothDevice btDevice)
throws Exception {
Class class1 = Class.forName("android.bluetooth.BluetoothDevice");
Method createBondMethod = class1.getMethod("createBond");
Boolean returnValue = (Boolean) createBondMethod.invoke(btDevice);
return returnValue.booleanValue();
}
Если приведенный выше код не работает в API 23, выполните быструю проверку разрешений Android.
// Quick permission check
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
int permissionCheck = getActivity().checkSelfPermission("Manifest.permission.ACCESS_FINE_LOCATION");
permissionCheck = getActivity().checkSelfPermission("Manifest.permission.ACCESS_COARSE_LOCATION");
if (permissionCheck != 0) {
this.requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, 1001); //Any number
}
}