Могу ли я прослушивать маяки Eddystone, когда мое приложение не запущено?

С новым стандартом Eddystone от Google они будут обеспечивать поддержку Android в службах Google Play Nearby API. Можем ли мы зарегистрироваться для получения маяков eddystone, чтобы наше приложение получало намерение, даже если оно не запущено?


person Patrick    schedule 14.07.2015    source источник
comment
Сложно сказать — ни обновленного Nearby API, ни какой-либо документации на данный момент нет. Я бы ожидал, что они это реализуют, но это всего лишь предположение.   -  person heypiotr    schedule 15.07.2015


Ответы (3)


Да, именно это можно сделать с помощью Android Beacon Library, в которой есть полный поддержка Eddystone.

Механизм фонового запуска вашего приложения работает в Eddystone так же, как и в других типах маяков, поддерживаемых библиотекой. Вы используете объект RegionBootstrap в пользовательском классе Application. Подробнее о том, как это работает, можно прочитать здесь.

Единственная разница с Eddystone заключается в том, что вам нужно настроить BeaconParser, который декодирует фрейм Eddystone-UID, а затем настроить Region, который будет соответствовать вашему идентификатору пространства имен Eddystone:

public class MyApplicationName extends Application implements BootstrapNotifier {
    private static final String TAG = ".MyApplicationName";
    private RegionBootstrap regionBootstrap;

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "App started up");
        BeaconManager beaconManager = BeaconManager.getInstanceForApplication(this);
        // Detect the main identifier (UID) frame:
        beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("s:0-1=feaa,m:2-2=00,p:3-3:-41,i:4-13,i:14-19"));

        // wake up the app when a beacon matching myEddystoneNamespaceId is seen 
        myEddystoneNamespaceId = Identifier.parse("0x2f234454f4911ba9ffa6");
        Region region = new Region("com.example.myapp.boostrapRegion", myEddystoneNamespaceId, null, null);
        regionBootstrap = new RegionBootstrap(this, region);
    }

    @Override
    public void didDetermineStateForRegion(int arg0, Region arg1) {
        // Don't care
    }

    @Override
    public void didEnterRegion(Region arg0) {
        Log.d(TAG, "Got a didEnterRegion call");
        // This call to disable will make it so the activity below only gets launched the first time a beacon is seen (until the next time the app is launched)
        // if you want the Activity to launch every single time beacons come into view, remove this call.  
        regionBootstrap.disable();
        Intent intent = new Intent(this, MainActivity.class);
        // IMPORTANT: in the AndroidManifest.xml definition of this activity, you must set android:launchMode="singleInstance" or you will get two instances
        // created when a user launches the activity manually and it gets launched from here.
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        this.startActivity(intent);
    }

    @Override
    public void didExitRegion(Region arg0) {
       // Don't care
    }        
}
person davidgyoung    schedule 14.07.2015
comment
Похоже, это все еще требует, чтобы это приложение было запущено, т.е. все еще имело свой процесс. Похоже, что если пользователь принудительно остановит приложение, он не получит обратный вызов, потому что приложение не будет запущено. - person Patrick; 14.07.2015
comment
Да, технически процесс работает в фоновом режиме, по крайней мере, для поиска маяков. Однако он не будет отображаться в списке последних приложений (переключатель задач), пока не появится пользовательский интерфейс. Если пользователь удаляет приложение из списка недавних задач, Android Beacon Library использует сигнал тревоги, чтобы перезапустить себя для поиска маяков в фоновом режиме в течение 5 минут. - person davidgyoung; 14.07.2015
comment
@davidgyoung Почему бы не использовать для этого IntentService (как и для обработки сообщений GCM)? - person JackAW; 16.07.2015
comment
IntentService — это хороший способ получить сообщение от внешней или системной службы, такой как GCM. При использовании Android Beacon Library служба сканирования маяков связана с вашим приложением и работает как внутренняя служба в фоновом режиме. - person davidgyoung; 16.07.2015
comment
Обязательно реализовать BootstrapNotifier только в классе Application, не будет ли это работать так же, если «BootstrapNotifier» реализован в Activity? - person Parag Kadam; 22.12.2015
comment
Нет, это не будет работать с действием, так как увеличение действия не вызывается до тех пор, пока это действие не станет видимым. - person davidgyoung; 22.12.2015
comment
Это то же самое поведение, которое демонстрирует iOS, когда приложение автоматически просыпается в присутствии iBeacon? Похоже, что Android все еще должен все время выполнять сканирование, чтобы обнаружить любой маяк, и у ОС нет механизма, чтобы сделать это и уведомить об обнаружении маяка. - person user2107373; 05.02.2016
comment
Это работает аналогично iOS, да. В случае Android код сканирования связан с приложением, и по крайней мере эта часть приложения должна быть запущена для автоматического запуска остальной его части. - person davidgyoung; 05.02.2016

Итак, это было очень болезненно, но мне наконец удалось обнаружить маяки с помощью API сообщений поблизости.

  1. Сначала создайте проект Google Developer Console.
  2. Включите «API ближайших сообщений» для только что созданного проекта.
  3. Создайте ключ API для этого проекта, как описано здесь, и добавьте это к манифесту
  4. Настройте и зарегистрируйте маяки, как описано здесь; что мне нужно было сделать, так это установить приложение для Android, открыть его, выбрать только что созданный проект, обнаружить маяк и зарегистрировать его в своем приложении.
  5. Вам нужно будет прикрепить сообщение к маяку, чтобы его обнаружили. Я сделал это с помощью Инструментов маяка. app, щелкните зарегистрированный маяк и нажмите "Вложения".
  6. Теперь вы можете следовать примеру кода здесь, и он должен обнаружить ваш маяк

    Nearby.Messages.subscribe(googleApiClient, new MessageListener() {
        @Override
        public void onFound(Message message) {
            Log.i(TAG, "Found : " + message);
        }
    
        @Override
        public void onLost(Message message) {
            Log.i(TAG, "Lost : " + message);
        }
    }, new SubscribeOptions.Builder()
            .setStrategy(Strategy.BLE_ONLY)
            .build());
    
person Ovidiu Latcu    schedule 25.05.2016

Это стало возможным с момента выпуска SDK сервисов Google Play версии 8.4 (декабрь 2015 г.).

Дополнительные сведения см. по следующей ссылке: http://android-developers.blogspot.com/2015/12/google-play-services-84-sdk-is-available_18.html

person TomTaila    schedule 07.03.2016