- Русские Блоги
- Android сканирует устройство Bluetooth и получить тип устройства
- Во-первых, сканирование
- Во-вторых, получить тип устройства Bluetooth
- Русские Блоги
- Серия разработок Bluetooth для Android — Как много вы знаете о типах устройств Bluetooth?
- 1. Различение типов оборудования с помощью наложенного платежа
- 2. демонстрация демо
Русские Блоги
Android сканирует устройство Bluetooth и получить тип устройства
Текущий популярный стандарт Bluetooth 4.0 включает в себя традиционный Bluetooth (BT) и модули Bluetooth с низкой мощностью (Ble).
Здесь это традиционный модуль Bluetooth, дайте результаты сканирования до:
Во-первых, сканирование
Прошло устройство Bluetooth сканирования Android BluetoothAdapter Запустите поиск Bluetooth, затем получите результат сканирования путем широковещения, его основной код выглядит следующим образом:
1, получите Bluetoothadapter
Можно получить непосредственно через один регистр
val btAdapt = BluetoothAdapter.getDefaultAdapter()
3, регистрировать трансляцию
val intent = IntentFilter() intent.apply < addAction(BluetoothDevice.ACTION_FOUND) addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED) addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED) addAction(BluetoothAdapter.ACTION_STATE_CHANGED) priority = IntentFilter.SYSTEM_HIGH_PRIORITY >registerReceiver(searchDevices, intent) private val searchDevices: BroadcastReceiver = object : BroadcastReceiver() < override fun onReceive(context: Context, intent: Intent) < when (intent.action) < BluetoothAdapter.ACTION_STATE_CHANGED -> < LogUtil.LOGE("ACTION_STATE_CHANGED") >BluetoothDevice.ACTION_FOUND -> < //found device val device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE) if (!device.name.isNullOrEmpty()) < // получить объект устройства mData.add(device) adapter.notifyDataSetChanged() >> BluetoothAdapter.ACTION_DISCOVERY_STARTED -> < Toastutil.show («сканирование») >BluetoothAdapter.ACTION_DISCOVERY_FINISHED -> < Toastutil.show («Сканирование завершено, щелкните на устройстве в списке, чтобы попробовать») >> > >
После получения объекта устройства вы можете отображать в списке, и, наконец, не забудьте отменить регистрационную трансляцию.
Во-вторых, получить тип устройства Bluetooth
Объект устройства, приобретенный выше BluetoothDevice имеют device.getType() метод. Просмотрите исходный код, чтобы узнать, что тип, возвращенный этим методом,
/** * Тип устройства Bluetooth, неизвестный неизвестный тип */ public static final int DEVICE_TYPE_UNKNOWN = 0; /** * Тип устройства Bluetooth, Classic - Устройства BR / EDR Традиционный тип */ public static final int DEVICE_TYPE_CLASSIC = 1; /** * Тип устройства Bluetooth, низкая энергия - Le-Lo-Type Type */ public static final int DEVICE_TYPE_LE = 2; /** * Тип устройства Bluetooth, двойной режим - BR / EDR / LE Традиция и двойной тип */ public static final int DEVICE_TYPE_DUAL = 3;
Давайте посмотрим на результаты сканирования Bluetooth на вашем телефоне:
Пучок device.getType() Способ возвращения значения и вышеизложенного сделать, вы можете обнаружить, что метод не может отличить, является ли устройство мобильным телефоном, тип компьютера также является типом гарнитуры.
Так как как система Android отличается?
Командная строка вводится следующим образом:
adb shell dumpsys window | findstr mCurrentFocus
Просмотреть интерфейс Bluetooth Scan в системе мобильной связи, следующим образом:
Так что проверьте исходный код Android, чтобы найти BluetoothSettingsActivity Вы можете посмотреть, как это достигнуто, где исходный код не собирается делать, тип приобретения выглядит следующим образом:
// Получить ресурс значка, соответствующий типу int deviceTypeImg = BtUtil.getDeviceType(device.getBluetoothClass()); holder.ivType.setImageResource(deviceTypeImg);
Используемый класс инструмента выполнен на системном исходном коде, код выглядит следующим образом:
public class BtUtil < public static final int PROFILE_HEADSET = 0; public static final int PROFILE_A2DP = 1; public static final int PROFILE_OPP = 2; public static final int PROFILE_HID = 3; public static final int PROFILE_PANU = 4; public static final int PROFILE_NAP = 5; public static final int PROFILE_A2DP_SINK = 6; public static int getDeviceType(BluetoothClass bluetoothClass) < if (bluetoothClass == null) < return R.drawable.ic_settings_bluetooth; >switch (bluetoothClass.getMajorDeviceClass()) < case BluetoothClass.Device.Major.COMPUTER: return R.drawable.ic_bt_laptop; case BluetoothClass.Device.Major.PHONE: return R.drawable.ic_bt_cellphone; case BluetoothClass.Device.Major.PERIPHERAL: return R.drawable.ic_bt_misc_hid; case BluetoothClass.Device.Major.IMAGING: return R.drawable.ic_bt_imaging; default: if (BtUtil.doesClassMatch(bluetoothClass, PROFILE_HEADSET)) return R.drawable.ic_bt_headset_hfp; else if (BtUtil.doesClassMatch(bluetoothClass, PROFILE_A2DP)) < return R.drawable.ic_bt_headphones_a2dp; >else < return R.drawable.ic_settings_bluetooth; >> > public static boolean doesClassMatch(BluetoothClass bluetoothClass, int profile) < if (profile == PROFILE_A2DP) < if (bluetoothClass.hasService(BluetoothClass.Service.RENDER)) < return true; >// By the A2DP spec, sinks must indicate the RENDER service. // However we found some that do not (Chordette). So lets also // match on some other class bits. switch (bluetoothClass.getDeviceClass()) < case BluetoothClass.Device.AUDIO_VIDEO_HIFI_AUDIO: case BluetoothClass.Device.AUDIO_VIDEO_HEADPHONES: case BluetoothClass.Device.AUDIO_VIDEO_LOUDSPEAKER: case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO: return true; default: return false; >> else if (profile == PROFILE_A2DP_SINK) < if (bluetoothClass.hasService(BluetoothClass.Service.CAPTURE)) < return true; >// By the A2DP spec, srcs must indicate the CAPTURE service. // However if some device that do not, we try to // match on some other class bits. switch (bluetoothClass.getDeviceClass()) < case BluetoothClass.Device.AUDIO_VIDEO_HIFI_AUDIO: case BluetoothClass.Device.AUDIO_VIDEO_SET_TOP_BOX: case BluetoothClass.Device.AUDIO_VIDEO_VCR: return true; default: return false; >> else if (profile == PROFILE_HEADSET) < // The render service class is required by the spec for HFP, so is a // pretty good signal if (bluetoothClass.hasService(BluetoothClass.Service.RENDER)) < return true; >// Just in case they forgot the render service class switch (bluetoothClass.getDeviceClass()) < case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE: case BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET: case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO: return true; default: return false; >> else if (profile == PROFILE_OPP) < if (bluetoothClass.hasService(BluetoothClass.Service.OBJECT_TRANSFER)) < return true; >switch (bluetoothClass.getDeviceClass()) < case BluetoothClass.Device.COMPUTER_UNCATEGORIZED: case BluetoothClass.Device.COMPUTER_DESKTOP: case BluetoothClass.Device.COMPUTER_SERVER: case BluetoothClass.Device.COMPUTER_LAPTOP: case BluetoothClass.Device.COMPUTER_HANDHELD_PC_PDA: case BluetoothClass.Device.COMPUTER_PALM_SIZE_PC_PDA: case BluetoothClass.Device.COMPUTER_WEARABLE: case BluetoothClass.Device.PHONE_UNCATEGORIZED: case BluetoothClass.Device.PHONE_CELLULAR: case BluetoothClass.Device.PHONE_CORDLESS: case BluetoothClass.Device.PHONE_SMART: case BluetoothClass.Device.PHONE_MODEM_OR_GATEWAY: case BluetoothClass.Device.PHONE_ISDN: return true; default: return false; >> else if (profile == PROFILE_HID) < return (bluetoothClass.getDeviceClass() & BluetoothClass.Device.Major.PERIPHERAL) == BluetoothClass.Device.Major.PERIPHERAL; >else if (profile == PROFILE_PANU || profile == PROFILE_NAP) < // No good way to distinguish between the two, based on class bits. if (bluetoothClass.hasService(BluetoothClass.Service.NETWORKING)) < return true; >return (bluetoothClass.getDeviceClass() & BluetoothClass.Device.Major.NETWORKING) == BluetoothClass.Device.Major.NETWORKING; > else < return false; >> >
Последнее достижение заключается в следующем:
Русские Блоги
Серия разработок Bluetooth для Android — Как много вы знаете о типах устройств Bluetooth?
Письмо»Статьи по разработке Bluetooth для Android — Подключение динамика Bluetooth»В то время я планировал разработать статью, объясняющую типы устройств Bluetooth, и теперь она скоро появится ~
Чтобы прочитать другой контент, вы можете нажать«Статьи по разработке Android Bluetooth — статьи по планированию», Или отсканируйте QR-код внизу статьи, чтобы подписаться на мою личную общедоступную учетную запись ~
Зачем объяснять классификацию устройств Bluetooth?
Тип устройства — это атрибут, который характеризует возможности устройства. Разница в типе устройства определяет отображение значков в пользовательском интерфейсе, фильтрацию во время сканирования устройства и тип профиля, который используется для подключения в процессе подключения.
Чтобы уточнить:
Различные типы устройств Bluetooth будут иметь разные отображения пользовательского интерфейса в пользовательском интерфейсе. Например, устройство мыши будет отображать значок мыши, устройство с динамиком отобразит значок динамика, а устройство гарнитуры отобразит значок гарнитуры.
В процессе сканирования нам необходимо найти целевое устройство. Этот тип устройства часто является одним из подходящих элементов. Только когда оно сопряжено, мы можем рассматривать это устройство как целевое устройство, а затем переходить к следующему шагу устройства: Сопряжение, подключение и т. Д.
Во время процесса подключения нам нужно инициировать подключение через разные профили для разных типов устройств. Например, для динамиков нам нужно подключиться через профиль A2DP (если вы забыли, вы можете снова посмотреть назад.»Статьи по разработке Bluetooth для Android — Подключение динамика Bluetooth»), для устройства мыши нам нужно подключиться через профиль ввода.
Другие требования могут также использовать тип оборудования.
1. Различение типов оборудования с помощью наложенного платежа
После сканирования устройства мы можем создать объект BluetoothDevice через MAC-адрес, а затем вызвать метод getBluetoothClass (), чтобы получить его тип устройства.
1227 /** 1228 * Get the Bluetooth class of the remote device. 1229 * 1230 * @return Bluetooth class object, or null on error 1231 */ 1232 @RequiresPermission(Manifest.permission.BLUETOOTH) 1233 public BluetoothClass getBluetoothClass() < 1234 final IBluetooth service = sService; 1235 if (service == null) < 1236 Log.e(TAG, "BT not enabled. Cannot get Bluetooth Class"); 1237 return null; 1238 >1239 try < 1240 int classInt = service.getRemoteClass(this); 1241 if (classInt == BluetoothClass.ERROR) return null; 1242 return new BluetoothClass(classInt); 1243 >catch (RemoteException e) < 1244 Log.e(TAG, "", e); 1245 >1246 return null; 1247 >
Класс BluetoothClass содержит переменную mClass, которую мы используем для различения типа устройства.
Из комментариев к коду мы видим, что переменная — это COD устройства Bluetooth, и эта переменная состоит из трех частей.
private final int mClass; 282 /** 283 * Return the Bluetooth Class of Device (CoD) value including the 284 * , and 285 * minor device fields. 286 * 287 *This value is an integer representation of Bluetooth CoD as in 288 * Bluetooth specification. 289 * 290 * @see https://www.bluetooth.com/specifications/assigned-numbers/baseband 291 * 292 * @hide 293 */ 294 public int getClassOfDevice()
Эта 32-битная переменная использует фиксированные биты для обозначения класса обслуживания / основного класса / второстепенного класса. Чтобы сделать презентацию более понятной, я нарисовал схему, как показано ниже.
Биты со 2-го по 12-й представляют собой комбинацию основного и вспомогательного классов, биты с 8-го по 12-й представляют основной класс, а биты с 14-го по 23-й представляют класс обслуживания.
Здесь упоминаются три существительных, и они объясняются отдельно ниже:
Service Class:
Существует несколько типов классов обслуживания.Служба представляет собой возможность Bluetooth.Например, если устройство Bluetooth поддерживает службу A2DP, это означает, что устройство Bluetooth можно использовать в качестве динамика.
109 /** 110 * Defines all service class constants. 111 * Each encodes zero or more service classes. 112 */ 113 public static final class Service < 114 private static final int BITMASK = 0xFFE000; 115 116 public static final int LIMITED_DISCOVERABILITY = 0x002000; 117 public static final int POSITIONING = 0x010000; 118 public static final int NETWORKING = 0x020000; 119 public static final int RENDER = 0x040000; 120 public static final int CAPTURE = 0x080000; 121 public static final int OBJECT_TRANSFER = 0x100000; 122 public static final int AUDIO = 0x200000; 123 public static final int TELEPHONY = 0x400000; 124 public static final int INFORMATION = 0x800000; 125
Мы можем использовать hasService (int), чтобы определить, поддерживается ли служба.
127 /** 128 * Return true if the specified service class is supported by this 129 * . 130 * Valid service classes are the public constants in 131 * . For example, . 133 * 134 * @param service valid service class 135 * @return true if the service class is supported 136 */ 137 public boolean hasService(int service) < 138 return ((mClass & Service.BITMASK & service) != 0); 139 >140
Major Class:
Главный класс представляет основные типы устройств. Степень детализации этого различия относительно велика. Глядя на код, мы можем видеть, что устройства Bluetooth делятся на несколько категорий, таких как компьютеры и телефоны.
151 public static class Device < 152 private static final int BITMASK = 0x1FFC; 153 154 /** 155 * Defines all major device class constants. 156 * See for minor classes. 157 */ 158 public static class Major < 159 private static final int BITMASK = 0x1F00; 160 161 public static final int MISC = 0x0000; 162 public static final int COMPUTER = 0x0100; 163 public static final int PHONE = 0x0200; 164 public static final int NETWORKING = 0x0300; 165 public static final int AUDIO_VIDEO = 0x0400; 166 public static final int PERIPHERAL = 0x0500; 167 public static final int IMAGING = 0x0600; 168 public static final int WEARABLE = 0x0700; 169 public static final int TOY = 0x0800; 170 public static final int HEALTH = 0x0900; 171 public static final int UNCATEGORIZED = 0x1F00; 172 >.
Чтобы определить, какому устройству Bluetooth принадлежит, вы можете вызвать следующий интерфейс:
256 257 /** 258 * Return the major device class component of this . 259 *Values returned from this function can be compared with the 260 * public constants in to determine 261 * which major class is encoded in this Bluetooth class. 262 * 263 * @return major device class component 264 */ 265 public int getMajorDeviceClass()
Каждую категорию устройств Bluetooth можно дополнительно уточнить. Например, категорию «Компьютер» можно разделить на следующие подкатегории:
174 // Devices in the COMPUTER major class 175 public static final int COMPUTER_UNCATEGORIZED = 0x0100; 176 public static final int COMPUTER_DESKTOP = 0x0104; 177 public static final int COMPUTER_SERVER = 0x0108; 178 public static final int COMPUTER_LAPTOP = 0x010C; 179 public static final int COMPUTER_HANDHELD_PC_PDA = 0x0110; 180 public static final int COMPUTER_PALM_SIZE_PC_PDA = 0x0114; 181 public static final int COMPUTER_WEARABLE = 0x0118;
Таким образом, мы можем сначала судить о возможностях устройства, оценивая класс обслуживания. Если он соответствует нашим требованиям, затем судите об основном классе устройства. Если ваше устройство не может быть обнаружено с помощью основного класса, затем определите устройство. Подкатегорий.
2. демонстрация демо
Мы используем"Статьи по разработке Bluetooth для Android - Подключение динамика Bluetooth"Основываясь на демонстрации, давайте посмотрим, поддерживает ли наш динамик профиль a2dp и имеет ли его основной класс AUDIO_VIDEO.
После того, как устройство просканирует динамик S7, определите, соответствует ли он профилю a2dp и основному классу. Если он соответствует ожиданиям, инициируйте сопряжение и соединение с устройством. Если нет, продолжайте поиск устройства.
public void onReceive(Context context, Intent intent) < final String action = intent.getAction(); Log.d(TAG, "onReceive intent = " + action); if(action.equals(BluetoothDevice.ACTION_FOUND)) < BluetoothDevice btdevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); final String address = btdevice.getAddress(); final String deviceName = btdevice.getName(); Log.d(TAG, "onReceive found device, deivce address = " + address + ",deviceName = " + deviceName); if(isTargetDevice(btdevice)) < BluetoothClass btClass = btdevice.getBluetoothClass(); if(btClass.hasService(BluetoothClass.Service.AUDIO)) < Log.d(TAG, "btdevice: " + btdevice + "support a2dp profile"); >else < Log.d(TAG, "btdevice: " + btdevice + "not support a2dp profile"); return; >int majorClass = btClass.getMajorDeviceClass(); Log.d(TAG, "btClass: " + btClass + "majorClass = " + majorClass); stopScan(); mHandler.sendEmptyMessageDelayed(MSG_PAIR, DELAYT_TIMES); > >
Соответствующий журнал распечатан следующим образом, мы видим, что динамик действительно поддерживает профиль A2dp, а его основной класс - 1024, преобразованный в шестнадцатеричное число 0x400, которое соответствует типу AUDIO_VIDEO.
--------- beginning of system 03-15 10:53:03.305 1311-1311/com.atlas.btdemo D/MainActivity: onReceive intent = android.bluetooth.device.action.FOUND 03-15 10:53:03.309 1311-1311/com.atlas.btdemo D/MainActivity: onReceive found device, deivce address = FC:58:FA:B4:45:EA,deviceName = S7 03-15 10:53:03.318 1311-1311/com.atlas.btdemo D/MainActivity: deivce :S7is target device 03-15 10:53:03.320 1311-1311/com.atlas.btdemo D/MainActivity: btdevice: FC:58:FA:B4:45:EAsupport a2dp profile 03-15 10:53:03.320 1311-1311/com.atlas.btdemo D/MainActivity: btClass: 260404majorClass = 1024 03-15 10:53:03.331 1311-1311/com.atlas.btdemo D/MainActivity: stop scan device 03-15 10:53:03.832 1311-1311/com.atlas.btdemo D/MainActivity: dispatchMessage, msg.what = 1 03-15 10:53:03.832 1311-1311/com.atlas.btdemo D/MainActivity: start pair device = FC:58:FA:B4:45:EA
Я хочу добавить здесь еще один момент: в конце концов, не судите о типе устройства только на основе основного класса, потому что некоторые устройства не являются стандартными, то есть, хотя это динамик Bluetooth, его основной класс не 0x400.
Как это следует оценивать? Фактически, нам нужно судить только по классу обслуживания, поскольку устройство Bluetooth поддерживает профиль A2dp, тогда оно может действовать как динамик, мы можем полностью рассматривать его как говорящего, никаких других условий для оценки не требуется ~
На этом статья заканчивается, в основном рассказывается о типе BluetoothClass и объединяется опыт, чтобы дать вам несколько советов по оценке типа устройства ~
Если вы хотите и дальше следить за содержанием этого блога, отсканируйте и подпишитесь на свою личную официальную учетную запись WeChat или выполните поиск WeChat: Internet of Everything Technology.