Библиотека Android iBeacon — как связать IBeaconManager со службой в удаленном процессе

Я использую библиотеку iBeacon для Android от RadiusNetworks и хочу, чтобы ранжирование iBeacon выполнялось в фоновом режиме, после чего оно будет передавать информацию о маяке моему приложению. Я пытаюсь связать iBeaconManager со службой, работающей в отдельном процессе, но, похоже, это не работает, поскольку служба никогда не выполняет обратный вызов onIBeaconServiceConnect().

TestService в отдельном процессе:

public class TestService extends Service implements IBeaconConsumer{

public static final String START_SERVICE = "com.example.intent.action.START";
public static final String SEND_PROXID = "com.example.intent.action.PROX";

private String proxID;
private static final String TAG = TestService.class.getSimpleName();
private IBeaconManager iBeaconManager;  
private Region currentRegion;
private boolean checkedRecently = false;

  private Timer timer;
  private TimerTask updateTask = new TimerTask() {
    @Override
    public void run() {
        checkedRecently = false;
         Log.i(TAG, "Resetting checked recently");
    }
  };

  @Override
  public int onStartCommand(Intent intent, int flags, int startId){
     int ret; 
     ret = super.onStartCommand(intent, flags, startId);
     Log.i(TAG, "Got to onStartCommand");
     if(intent.getAction().equals(START_SERVICE)){
         Log.i(TAG, "Service received start intent");
     }
     else if(intent.getAction().equals(SEND_PROXID)){
         Log.i(TAG, "Service received PROXID intent");
         proxID = intent.getStringExtra("prox");
         System.out.println(proxID);
         iBeaconManager = IBeaconManager.getInstanceForApplication(this);
        iBeaconManager.bind(this);
     }
     return ret;
       }

  @Override
  public IBinder onBind(Intent intent) {
      Log.i(TAG, "onBIND called");
    return null;
  }

  @Override
  public void onCreate() {
    super.onCreate();
    Log.i(TAG, "Service creating");

    timer = new Timer("TestTimer");
    timer.schedule(updateTask, 1000L, 20 * 1000L);

  }

  @Override
  public void onDestroy() {
    super.onDestroy();
    Log.i(TAG, "Service destroying");

    timer.cancel();
    timer = null;
    iBeaconManager.unBind(this);
    iBeaconManager = null;
  }

  @Override
    public void onIBeaconServiceConnect() {
      Log.i(TAG, "iBeacon service connect");
        iBeaconManager.setRangeNotifier(new RangeNotifier() {
        @Override 
        public void didRangeBeaconsInRegion(Collection<IBeacon> iBeacons, Region region) {
            if (iBeacons.size() > 0 && !checkedRecently) {
                checkedRecently = true;
                Log.i(TAG, "Service found beacon, sending data");
            Intent i = new Intent();
            i.setAction(ServiceReceiver.DID_ENTER);
            i.putExtra("maj", Integer.toString(iBeacons.iterator().next().getMajor()));
            i.putExtra("min", Integer.toString(iBeacons.iterator().next().getMinor()));
            sendBroadcast(i);
            }
        }
        });

        currentRegion = new Region("myRangingUniqueId", proxID, null, null);
        try {
            iBeaconManager.startMonitoringBeaconsInRegion(currentRegion);
        } catch (RemoteException e) {   }

    }

}

AndroidManifest.xml

<service
        android:name=".TestService"
        android:exported="false"
        android:process=":remote" >
        <intent-filter>
            <action android:name="com.example.intent.action.PROX" />
            <action android:name="com.example.intent.action.START" />
        </intent-filter>
    </service>
<receiver android:name="ServiceReceiver" >
        <intent-filter>
            <action android:name="com.example.intent.action.DIDENTER" >
            </action>
        </intent-filter>
    </receiver>

Я извлекаю соответствующий прокси-идентификатор со своего сервера и отправляю его в службу, и в это время я полагаю, что должен иметь возможность привязаться к нему и начать ранжирование для регионов, которые соответствуют прокси-серверу. Но я не могу заставить его успешно привязаться к службе. Спасибо за помощь, и дайте мне знать, если мне нужно обновить опубликованный код.


person lundhjem    schedule 11.06.2014    source источник


Ответы (1)


Интересно, получает ли ваш AndroidManifest.xml правильные записи, необходимые для AndroidIBeaconLibrary. Библиотека полагается на функцию, называемую объединением манифестов, чтобы получить записи службы библиотеки в ваш манифест. Это должно быть включено в вашем проекте в Eclipse или Android Studio. Проверьте каталог сборки на наличие сгенерированного манифеста и убедитесь, что в нем есть запись для файла AndroidIBeaconService.

Тем не менее, создание собственной фоновой службы может быть излишним. Учтите, что в библиотеке iBeacon для Android уже есть фоновый класс AndroidIBeaconService (как упоминалось выше), поэтому вам не нужно делать свой собственный сервис. Все, что вам нужно сделать, это привязать службу к чему-то с более длительным жизненным циклом, чем Activity (например, к пользовательскому классу Android Application), чтобы служба не останавливалась, когда Activity отвязывается от нее.

Существует Pro версия Android iBeacon Library, в которой все это устанавливается для вас, замедляет сканирование, когда ваше приложение находится в фоновом режиме, для экономии заряда батареи и автоматически запускает ваше приложение в фоновом режиме для поиска iBeacons, даже если пользователь не запускает его вручную. Пример кода, показывающий, как это сделать в версии Pro, находится в разделе «Пример кода фонового запуска» здесь.

Полное раскрытие: я главный инженер Radius Networks и основной автор библиотеки Android iBeacon.

person davidgyoung    schedule 11.06.2014
comment
Спасибо за оперативный ответ Давид! У меня есть manifestmerging как true в свойствах моего проекта, но я не уверен, где находится сгенерированный манифест; диапазон работал отлично, когда я был привязан к активности на переднем плане, но, конечно, останавливался, когда активность останавливалась или приостанавливалась. Я попытался сделать так, чтобы мое приложение-синглтон, которое я использую для глобальных переменных, расширяло приложение и привязывалось к нему, но я всегда получаю одни и те же ошибки. Возможно, вы сможете их понять, я обновлю пост. - person lundhjem; 12.06.2014
comment
Боюсь, я запутался. Вы упомянули, что пытались сделать так, чтобы мое приложение-синглтон, которое я использую для глобальных переменных, расширяло приложение и привязывалось к нему, но я всегда получаю одни и те же ошибки и показываю трассировку стека, которая, по-видимому, предназначена для этой попытки. Но вы не показываете свой код из этого класса приложения, и вопрос по-прежнему показывает использование службы. Я предлагаю вам сохранить этот вопрос, связанный с использованием Сервиса (вам, вероятно, не следует принимать мой ответ, если он не решит вашу проблему) и открыть новый вопрос, чтобы сделать ваш app singleton расширяет Application. Я постараюсь помочь там. - person davidgyoung; 12.06.2014
comment
Для решения на основе службы Eclipse помещает объединенный манифест в bin/AndroidManifest.xml. Убедитесь, что в нем есть служебная запись для com.radiusnetworks.ibeacon.service.IBeaconService. - person davidgyoung; 12.06.2014
comment
Я согласился, потому что ваш первый ответ помог решить проблему. Служба iBeacon не была зарегистрирована в моем манифесте, несмотря на слияние как истинное; Я наверное не правильно настроил. А что касается пользовательского приложения, я, вероятно, не мог связать его по той же причине. Спасибо еще раз! - person lundhjem; 12.06.2014