3

ios sdk имеет отличные функции мониторинга области. Мне нужно что-то подобное в андроиде, и я думаю, у нас есть две альтернативы. Geofencing и LocationManager.addProximityAlert не работает должным образом

Geofencing имеет действительно аккуратные примеры и ошибки, поэтому я предпочитаю LocationManager. Everyting отлично работает в LocationManager, кроме одного. Если вы добавите свое текущее местоположение как ProximityAlert, оно немедленно запускает «ВВОД», но это мое текущее местоположение, это не значит, что я вошел в этот регион. Из-за этого он запускает «Ввод» каждый раз, когда я запускаю свое приложение, если я в регионе. (Даже если я не перемещаюсь)

Как я могу решить эту проблему и пожароопасность, только если пользователь действительно ВХОДИТ в регион ?

Вот как я добавляю PeddingIntents для своих местоположений.

LocationManager locationManager = (LocationManager)mContext.getSystemService(Context.LOCATION_SERVICE); 

    for(Place p : places) 
    { 
     Log.e("location", p.location); 

     Bundle extras = new Bundle(); 
     extras.putString("name", p.displayName); 
     extras.putString("id", p.id); 
     Intent intent = new Intent(CommandTypes.PROX_ALERT_INTENT); 
     intent.putExtra(CommandTypes.PROX_ALERT_INTENT, extras); 
     PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext,Integer.parseInt(p.id), intent,PendingIntent.FLAG_CANCEL_CURRENT); 
     float radius = 50f; 
     locationManager.addProximityAlert(p.lat, 
       p.lon, radius, 1000000, pendingIntent); 

    }  

Приемник

public class ProximityReceiver extends BroadcastReceiver { 

@Override 
public void onReceive(Context context, Intent intent) { 

    final String key = LocationManager.KEY_PROXIMITY_ENTERING; 
    final Boolean entering = intent.getBooleanExtra(key, false); 

    Bundle b = intent.getBundleExtra(CommandTypes.PROX_ALERT_INTENT); 
    String id = b.getString("id"); 
    Log.e("here" + id, "here"); 

    if (entering) { 
     Log.e(TAG,"entering"); 
    } else { 
     Log.e(TAG,"leaving"); 
    } 
} 

Manifest

<receiver android:name=".ProximityReceiver"> 
     <intent-filter> 
      <action android:name="ACTION_PROXIMITY_ALERT" /> 
     </intent-filter>    
    </receiver> 

Большое спасибо

PS: IOS не имеют этой проблемы, и их документация объясняет это так

Мониторинг географического региона начинается сразу после регистрации для авторизированных приложений. Однако не ожидайте, что вы сразу получите событие. Только пересечения границ генерируют событие. Таким образом, если во время регистрации местоположение пользователя уже находится внутри региона, диспетчер местоположений автоматически не генерирует событие. Вместо этого ваше приложение должно дождаться, когда пользователь пересечет границу региона до того, как событие будет сгенерировано и отправлено делегату. Тем не менее, вы можете использовать метод requestStateForRegion: класса CLLocationManager, чтобы проверить, находится ли пользователь уже на границе области.

+0

Если вы посмотрите на исходный код locationManager.addProximity (..), вы увидите, что этот метод работает с геозонностью. – Harco

ответ

3

EDIT: так как я написал это, там была новая вещь добавлена ​​в геозоны API, 'setInitialTrigger', что allevates это:

https://developers.google.com/android/reference/com/google/android/gms/location/GeofencingRequest.Builder#setInitialTrigger%28int%29

Да, это неприятность, и является одним из основных моментов, на которые, к сожалению, отличается геофенсировка Android и IOS.

Android оповещения, когда вы находитесь в Geofence, если он знает, что вы были снаружи до того, как вы добавили геозонность внутри нее.

Способ, которым я решаю это с «льготным периодом» в моем приемнике вещания. В принципе, когда я создаю Geofence, я сохраняю время его создания в sharedpreferences, и я проверяю это значение в onReceive.

Таким образом, любое «немедленное» попадание будет отфильтровано. Возможно, 3 минуты слишком длинны для кого-то другого, но это работает для меня, основываясь на том, как я работаю с геообъектами в своем приложении.

private static final Long MIN_PROXALERT_INTERVAL = 18000l; // 3 mins in milliseconds 

...

long geofenceCreationTime = session.getPrefs().getCurrentGeofenceCreation(); 
long elapsedSinceCreation = now - geofenceCreationTime; 
if(elapsedSinceCreation < CREATIONTIME_GRACE_PERIOD){ 
     if (ApplicationSession.DEBUG) { 
      Log.d(TAG, "elapsedSinceCreation;"+elapsedSinceCreation+";less than;"+CREATIONTIME_GRACE_PERIOD+";exiting"); 
     } 
     return; 

    } 

Надеюсь, вы понимаете, что я клоню.

Надеюсь, это поможет.

+0

Просто добавьте дополнительную информацию с SystemClock.elapsedRealtime() в ожидающее намерение, а затем сравните с этим при получении трансляции. Не нужно хранить предпочтение. – ballzak

+0

Ну, я думаю, что может быть причина. Если телефон перезагружен, и вы хотите повторно создать геозонность, вам нужно будет отслеживать время создания геозоны, чтобы вы могли установить правильный тайм-аут воссозданного геосферы. Скажите, что вам нужно 12 часов, и телефон перезапускается через 4 часа. Затем вам нужно время оригинального создания, чтобы установить тайм-аут «нового» геосферы на 8 часов. Вот почему я сохранил его в настройках в любом случае. – Mathias