Приложение для геозоны с дополнительными функциями

#android #google-play-services #android-geofence

#Android #google-play-сервисы #android-геозона

Вопрос:

Вот в чем проблема:

Сервис, добавляющий геозоны:

 public class GeofenceService extends Service implements GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServicesClient.OnConnectionFailedListener, LocationClient.OnAddGeofencesResultListener, LocationClient.OnRemoveGeofencesResultListener {
     ...

            @Override
                public void onConnected(Bundle bundle) {
                    Log.d(TAG, "onConnected");
                    switch (action){
                        case ADD:
                            Log.d(TAG, "onConnected ADD");
                            locationClient.addGeofences(geofencesToAdd, getPendingIntent(), this);
                            break;
                        case REMOVE:
                            Log.d(TAG, "onConnected REMOVE");
                            locationClient.removeGeofences(geofencesToRemove, this);
                            break;
                    }
                }

                private PendingIntent getPendingIntent(){
                    Intent intent = new Intent().setClass(this, TransitionsIntentService.class);
                    intent.putExtra(EXTRA_DEALS, deals);
                    return PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
                }
    ...
}
  

Как вы можете видеть, есть намерение, которое передает некоторые данные и запускает TransitionIntentService :

 public class TransitionsIntentService extends IntentService {

   ... 
@Override
protected void onHandleIntent(Intent intent) {
        deals = (ArrayList<Deal>) intent.getSerializableExtra(GeofenceService.EXTRA_DEALS); //THIS CAN BE NULL

        int transitionType = LocationClient.getGeofenceTransition(intent);

        List<Geofence> triggeredGeofences = LocationClient.getTriggeringGeofences(intent); //THIS CAN BE NULL
        List<String> triggeredIds = new ArrayList<String>();

        for (Geofence geofence : triggeredGeofences) {
            Log.d("GEO", "onHandle:"   geofence.getRequestId());
            processGeofence(geofence, transitionType);
            triggeredIds.add(geofence.getRequestId());
        }

    ...
}
  

Если я попытаюсь поместить Extra (…, deals) в getPendingIntent метод, который у меня есть List<Geofence> triggeredGeofences = LocationClient.getTriggeringGeofences(intent) == NULL .

Если я не передам дополнительные функции, все будет работать нормально.

Как я могу передать свои дополнительные функции и при этом получить дополнительные от LocationClient ?

Комментарии:

1. Является только triggeredGeofences нулевым или deals слишком onHandleIntent ?

2. Если я передаю объекты Deal как дополнительные, то сделки не равны нулю. Если я этого не сделаю, то triggeredGeofences не будет нулевым. Кроме того, я могу передать String object как дополнительный, и все будет в порядке. Проблема возникает, когда я пытаюсь передать свой собственный сериализуемый объект Deal

3. даже у меня есть эта проблема, вы случайно ее не решили?

Ответ №1:

Я знаю, что это старый вопрос, но я столкнулся с точно такими же симптомами и проблемами. В принципе, кажется, что GeofenceEvent не может сосуществовать с Serializable дополнительным в намерении. Единственное решение, которое я нашел, состояло в том, чтобы сгладить сериализуемый объект и использовать вместо него отдельный дополнительный объект с простым типом данных для каждого поля, как в этом простом примере:

Объект для передачи через intent:

 public class MyObject {
  public String stringfield;
  public int intField;

  public MyObject fromIntent(Intent intent) {
    stringField = intent.getStringExtra("stringField");
    intField = intent.getIntExtra("intField", -1);
    return this;
  }

  public MyObject toIntent(Intent intent) {
    intent.putExtra("stringField", stringField);
    intent.putExtra("intField", intField);
    return this;
  }
}
  

Создание и заполнение намерения:

 MyObject obj = ...;
Intent intent = ...;
myObject.toIntent(intent);
  

Извлечение данных из полученного намерения:

 Intent intent = ...;
MyObject obj = new MyObject().fromIntent(intent);
  

Это немного громоздко, но это единственный способ заставить это работать. Теперь я могу извлекать как данные GeofenceEvent, так и мои пользовательские данные из одного и того же намерения.

Ответ №2:

Кажется, GeofenceEvent не может сосуществовать с Serializable дополнительным в намерении.

Решение, которое я нашел, состояло в том, чтобы сделать передаваемый объект статичным. В IntentService классе получите прямой доступ к статическому объекту.

Например,

GeofenceService.java

 public class GeofenceService extends Service implements GooglePlayServicesClient.ConnectionCallbacks, ...

{

     ...

     public static ArrayList<Deal> extraDeals;

     ...

}
  

TransitionsIntentService.java

 public class TransitionsIntentService extends IntentService {

    ... 

    @Override
    protected void onHandleIntent(Intent intent) {
        ...

        deals = GeofenceService.extraDeals;

        ...
    }

    ...

}
  

Ответ №3:

Я не эксперт, но это может вам помочь

в вашем коде

 return PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
  

замените этим

 return PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
  

Для тех, кто смотрит на это и у кого есть методы .putExtra перед подключением к PendingIntent, PendingIntent.FLAG_UPDATE_CURRENT важно, поэтому попробуйте это, прежде чем переходить к другому решению.