Я пытаюсь разбудить мое приложение, когда устройство входит в область маяков с указанным c UUID.
До сих пор я пытался использовать собственный BluetoothAdapter.getBluetoothLeScanner , предоставляющий PendingIntent для запуска приемника Broadcast.
Я также попробовал RxBleClient , который является удивительной библиотекой, которая работает при выполнении обычного обнаружения.
Я попробовал AltBeacon lib, которая также является очень тщательной и блестящей.
Я также попробовал игровые сервисы Nearis Apis.
Но все не удалось. Все они могут регулярно сканировать радиомаяки, но при попытке регистрации зарегистрируйтесь и дайте устройству сканировать, находясь в bg. Трансляция никогда не запускается.
Я также пробовал все 4 при использовании службы переднего плана. Это тоже не помогло. Я также упомяну, что все это сделано на Android 8. Я просмотрел код в обеих библиотеках, и они оба в конечном итоге используют один и тот же вызов функции из собственного адаптера bluetooth. Так что я предполагаю, что если это не удастся, все остальное тоже не получится Также стоит упомянуть, что при предоставлении функции startScan функции CallBack вместо PendingIntent обратный вызов постоянно запускается для всех отсканированных BT-устройств. Если я добавлю ScanFilter, чтобы фильтровать только мой UUID, он завершится неудачно. Чего мне не хватает?
Кстати, когда я реализовал это в Ios, оно работало безупречно. Приложение запускается, как будто я использовал триггер Geofence для входа / выхода.
Почему эта работа не работает в Android ?? Есть мысли?
РЕДАКТИРОВАТЬ: Вот как я использовал код из библиотеки AltBeacon. Это в основном копия вставки из учебника DOCS. Единственное отличие состоит в том, что я инкапсулировал его в отдельный класс:
public void init(AppCompatActivity context) {
if (isRegistered) {
return;
}
BluetoothManager bluetoothManager = (BluetoothManager) context.getApplicationContext().getSystemService(Context.BLUETOOTH_SERVICE);
if (bluetoothManager != null) {
bluetoothAdapter = bluetoothManager.getAdapter();
if (!bluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
context.startActivityForResult(enableBtIntent, 1002);
} else {
register(context);
}
}
}
public void register(AppCompatActivity context) {
if (isRegistered) {
return;
}
executorService.execute(new Runnable() {
@Override
public void run() {
Region region = new Region("com.sample.WakeOnDiscovery", Identifier.parse("E2C56DB5-DFFB-48D2-B060-D0F5A71096E0"), Identifier.fromInt(11180), null);
bootstrapRegion = new RegionBootstrap(new BootstrapNotifier() {
@Override
public Context getApplicationContext() {
return Application.getContextFromApplicationClass();
}
@Override
public void didEnterRegion(Region region) {
Logger.log(TAG, "didEnterRegion: " + region.toString());
}
@Override
public void didExitRegion(Region region) {
Logger.log(TAG, "didExitRegion: " + region.toString());
}
@Override
public void didDetermineStateForRegion(int i, Region region) {
Logger.log(TAG, "didDetermineStateForRegion: " + region.toString() + "|" + i);
}
}, region);
}
});
isRegistered = true;
}
Это когда я пытаюсь найти этот специфицированный c UUID и major int (и без major int). Как только я думаю, срабатывает только didDetermineStateForRegion. С int i = 0 или 1.
Что касается UUID, я пробовал 2 разных UUID. Первым является тот, который я генерирую в образце приложения, которое я написал в IOS. Приложение ios рекламирует себя как маяк. Я вижу это в другом приложении, которое использует обычную функцию обнаружения. Но onEnterRegion не запускается.
Я также попробовал UUID с устройства iBeacon, которое я использую регулярно в течение многих лет. Все еще без кубиков.
Когда я пытаюсь использовать собственный android ble сканер, я использую это:
ScanSettings settings = (new ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)).setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES).build();
List<ScanFilter> filters = new ArrayList<>(); // Make a scan filter matching the beacons I care about
filters.add(new ScanFilter.Builder()/*.setServiceUuid(ParcelUuid.fromString("E2C56DB5-DFFB-48D2-B060-D0F5A71096E0"))*/.build());
bluetoothAdapter.getBluetoothLeScanner().startScan(filters, settings, getPendingIntent(context));
и:
private PendingIntent getPendingIntent(Context context) {
return PendingIntent.getBroadcast(context, 0, new Intent(context, BTDiscoveryBroadcast.class), PendingIntent.FLAG_UPDATE_CURRENT);
}
Я попытался передать ноль как Фильтры, я пробовал пустой список массивов, и я пробовал реальный фильтр с тем же UUID.
Все еще ничего не работает.
То, что я случайно увидел в logcat, это сообщение об ошибке:
E/NearbyDirect: Could not start scan. [CONTEXT service_id=49 ]
java.lang.IllegalStateException: Receiver com.google.location.nearby.direct.bluetooth.state.FastPairScanner$4@535d6ea registered with differing handler (was Handler (adxv) {8fab16a} now Handler (android.app.ActivityThread$H) {e4e0078})
Я думаю, что это происходит и при использовании библиотеки AltBeacon. Я могу только предположить, что это связано с моей проблемой.
РЕДАКТИРОВАТЬ 2: Я попробовал это:
ScanSettings settings = (new ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)).setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES).build();
List<ScanFilter> filters = new ArrayList<>(); // Make a scan filter matching the beacons I care about
byte[] manufacturerData = new byte[] {
// iBeacon identifier prefix
0x02, 0x15,
// Your Proximity UUID
(byte) 0xE2, (byte) 0xC5, 0x6D, (byte) 0xB5, (byte) 0xDF, (byte) 0xFB, 0x48, (byte) 0xD2, (byte) 0xB0, 0x60, (byte) 0xD0, (byte) 0xF5, (byte) 0xA7, 0x10, (byte) 0x96, (byte) 0xE0,
0x3, 0x20, 0x3, 0x20, (byte) 0xC5
};
int manufacturerId = 0x004c; // Apple
filters.add(new ScanFilter.Builder().setManufacturerData(manufacturerId, manufacturerData).build());
bluetoothAdapter.getBluetoothLeScanner().startScan(filters, settings, getPendingIntent(context));
Данные байтов, которые я получил после выполнения обычного .startDiscovery сканировать, найти мое устройство BT и извлечь из ScanResult данных. Просто чтобы убедиться, что он точно такой же.
Все равно не запускает трансляцию: (