Добавление пользовательских данных во время рекламы с использованием формата AltBeacon
Я изучаю разработку приложений для Android, создавая приложение, которое взаимодействует с физической сетью. Я хочу разместить рекламу на основе спецификации AltBeacon и добавить небольшую полезную нагрузку в виде строки или байтов. Я наткнулся на Beacon.Builder Javadoc, но он не очень хорошо написан. Какую функцию я должен использовать из приведенного выше Javadoc или есть что-то еще доступно?
Моя цель - рекламировать с помощью моего приложения и передавать определенную строку. Если на другом устройстве есть мое приложение, оно должно показывать уведомление с этой строкой. Весь мой код был взят из этого.
1 ответ
Стандартные макеты маяка Bluetooth (iBeacon, AltBeacon, Eddystone-UID) предназначены для передачи уникального числового идентификатора, а не строки. (Eddystone-URL является исключением из-за того, что он предназначен для передачи закодированной строки URL.)
Тем не менее, безусловно, можно передавать строку, закодированную при передаче маяка. Просто поймите, что у этого есть несколько ограничений:
Количество места ограничено. Только около 20 байтов используемого пространства доступно в передачах маяка, что составляет 20 символов, если используется кодировка, подобная ASCII, и, возможно, меньше в зависимости от символов, если используется UTF-8.
Вам нужно определенное количество совпадающих байтов, чтобы выяснить (с некоторой разумной уверенностью), является ли реклама "вашей" и должна ли она вообще декодироваться как строка. Использование двухбайтового совпадающего значения даст вам 1 из 65536 шансов случайного декодирования чужого маяка в виде строки.
Если вы хотите получать и декодировать на iOS, вы действительно не можете использовать iBeacon, потому что для сопоставления должен использоваться 16-байтовый UUID, оставляя два байта для хранения строки.
Вот пример того, как вы могли бы сделать это, используя модифицированную компоновку AltBeacon, с первым двухбайтовым идентификатором соответствия 0x8b9c, используемым для проверки того, что это ваш маяк, и вторым 18-байтовым идентификатором, используемым для хранения закодированной строки. Фрагмент кода, который показывает передачу строки ASCII длиной не более 18 символов:
public static final Identifier MY_MATCHING_IDENTIFIER = Identifier.fromInt(0x8b9c);
...
mBeaconManager.getBeaconParsers().clear();
BeaconParser customBeaconParser = new BeaconParser().setBeaconLayout("m:2-3=beac,i:4-5,i:6-23,p:24-24,d:25-25");
mBeaconManager.addBeaconParser(customBeaconParser);
String stringToTransmit = "Only 18 chars fit!";
byte[] stringToTransmitAsAsciiBytes = stringToTransmit.getBytes(StandardCharsets.US_ASCII);
Beacon beacon = new Beacon.Builder().setId1(MY_MATCHING_IDENTIFIER.toString())
.setId2(Identifier.fromBytes(stringToTransmitAsAsciiBytes, 0, 18, false).toString())
.setTxPower(-59).build();
mBeaconTransmitter = new BeaconTransmitter(this, customBeaconParser);
mBeaconTransmitter.startAdvertising(beacon);
И вот получаю это:
@Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
for (Beacon beacon : beacons) {
if (beacon.getId1().equals(MY_MATCHING_IDENTIFIER)) {
byte[] bytes = beacon.getId2().toByteArray();
String receivedString = null;
try {
receivedString = new String(bytes, 0, bytes.length, "ASCII");
} catch (UnsupportedEncodingException e) {
Log.d(TAG, "Cannot decode ASII");
}
Log.d(TAG, "I just received: "+receivedString);
}
}
}
РЕДАКТИРОВАТЬ: Убедитесь, что вы очистили парсеры маяка, как показано выше, иначе ваш код будет пытаться использовать парсер маяка по умолчанию. Смотрите изменения кода выше.