Cómo hacer que la alerta de Geo Fencing sea más precisa en Android

Hola, estoy intentando agregar la característica de Geo Fence en Android. Estoy utilizando http://developer.android.com/training/location/geofencing.html para crear y supervisar las cercas geográficas. Estoy usando el IntentService para la alerta (entrado / salido) pero para mí no está trabajando.

Pero cuando me fui y volví a la región para probarlo, entonces no funcionó para mí. He encendido el GPS del dispositivo, pero el dispositivo no está conectado con Internet.

Cualquier persona puede por favor ayudarme a hacerlo más exacto y perfectamente sin ningún problema.

 public class MainActivity extends Activity implements GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServicesClient.OnConnectionFailedListener, LocationClient.OnAddGeofencesResultListener { private LocationClient locationClient; private String TAG = "MainActivity"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); int resp = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this); if (resp == ConnectionResult.SUCCESS) { locationClient = new LocationClient(this, this, this); locationClient.connect(); } } @Override public void onConnected(Bundle bundle) { ArrayList<Store> storeList = getStoreList(); if (null != storeList && storeList.size() > 0) { ArrayList<Geofence> geofenceList = new ArrayList<Geofence>(); for (Store store : storeList) { float radius = (float) store.radius; Geofence geofence = new Geofence.Builder() .setRequestId(store.id) .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT) .setCircularRegion(store.latitude, store.longitude, radius) .setExpirationDuration(Geofence.NEVER_EXPIRE) .build(); geofenceList.add(geofence); } PendingIntent geoFencePendingIntent = PendingIntent.getService(this, 0, new Intent(this, GeofenceIntentService.class), PendingIntent.FLAG_UPDATE_CURRENT); locationClient.addGeofences(geofenceList, geoFencePendingIntent, this); } } @Override public void onDisconnected() { Log.e(TAG, "Disconnected !"); } @Override public void onAddGeofencesResult(int i, String[] strings) { if (LocationStatusCodes.SUCCESS == i) { //todo check geofence status } else { } } @Override public void onConnectionFailed(ConnectionResult connectionResult) { Log.e(TAG, connectionResult.getErrorCode() + ""); } private ArrayList<Store> getStoreList() { ArrayList<Store> storeList = new ArrayList<Store>(); for (int i = 0; i < 1; i++) { Store store = new Store(); store.id = String.valueOf(i); store.address = "India"; store.latitude = 26.7802187; store.longitude = 75.860322; store.radius = 100.0; storeList.add(store); } return storeList; } public class Store { String id; String address; double latitude; double longitude; double radius; } @Override protected void onDestroy() { super.onDestroy(); if (null != locationClient) { locationClient.disconnect(); } } } 

GeofenceIntentService.java

 public static final String TRANSITION_INTENT_SERVICE = "ReceiveTransitionsIntentService"; public GeofenceIntentService() { super(TRANSITION_INTENT_SERVICE); } @Override protected void onHandleIntent(Intent intent) { if (LocationClient.hasError(intent)) { //todo error process } else { int transitionType = LocationClient.getGeofenceTransition(intent); if (transitionType == Geofence.GEOFENCE_TRANSITION_ENTER || transitionType == Geofence.GEOFENCE_TRANSITION_EXIT) { List<Geofence> triggerList = LocationClient.getTriggeringGeofences(intent); for (Geofence geofence : triggerList) { generateNotification(geofence.getRequestId(), "address you defined"); } } } } private void generateNotification(String locationId, String address) { long when = System.currentTimeMillis(); Intent notifyIntent = new Intent(this, MainActivity.class); notifyIntent.putExtra("id", locationId); notifyIntent.putExtra("address", address); notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT); NotificationCompat.Builder builder = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.dac_logo) .setContentTitle(locationId) .setContentText(address) .setContentIntent(pendingIntent) .setAutoCancel(true) .setDefaults(Notification.DEFAULT_SOUND) .setWhen(when); NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.notify((int) when, builder.build()); } } 

AndroidManifest.xml

  <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.demo" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" /> <application android:allowBackup="true" android:icon="@drawable/dac_logo" android:label="@string/app_name" > <activity android:name=".MainActivity" android:excludeFromRecents="true" android:label="@string/app_name" android:launchMode="singleTask" android:taskAffinity="" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name=".GeofenceIntentService" android:exported="false" /> <receiver android:name="com.location.demo.receivers.BootCompleteReceiver" > <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> </intent-filter> </receiver> <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" /> </application> 

He descubierto que el GeoFencing nunca recupera inteligentemente las ubicaciones del hardware GPS. La API de GeoFence observará la ubicación más precisa disponible desde el sistema operativo o, si no hay una lectura de ubicación reciente disponible, hará que se calcule una ubicación desde Wifi / Cellular. (Lo que es una mierda porque celular es tremendamente impreciso y wifi a menudo no está disponible)

Así que para obtener todos los resultados correctos o sensibles de la Geofencing API tiene que configurar sus Geofences y luego hacer una encuesta en el hardware GPS en un intervalo, ni siquiera hacer nada con el resultado recibido, por lo que bajo la superficie que están proporcionando datos útiles Al sistema operativo.

Esto es probablemente el núcleo de por qué sus resultados son inexactos. La salida de geofence no se disparará hasta que el sistema operativo esté seguro de que está 100% fuera de la valla, por lo que si la lectura de la ubicación tiene una precisión de 500 metros (no es improbable cuando se usa geolocalización de celda) D tienen que ser por lo menos 550m de su punto de la cerca para producir un acontecimiento de la salida.

TLDR; Encuesta el hardware GPS en un intervalo sin hacer nada con el resultado y comenzará a obtener geofences más preciso.

La geofenificación nativa de Android es sorprendentemente incorrecta y requiere mucha batería. Le sugiero que utilice una herramienta de terceros como el SDK de punto de Bluedot (exacto a 10m / 30 pies) o SDK de Gimbal (exacto a 50m / 165 pies), que son mucho más confiables con menos drenaje de la batería.

Divulgación completa: Trabajo para Bluedot.

También tuve problemas con el sistema de geofence saltando dentro y fuera de mis geofences y luego leí esto (Cita de documentos oficiales):

No hay conectividad de red confiable dentro de su geofence. Si no hay una conexión de datos fiable, es posible que no se generen alertas. Esto se debe a que el servicio geofence depende del proveedor de ubicación de red, que a su vez requiere una conexión de datos.

De la documentación oficial de geofence

Si el dispositivo che no está conectado a Internet, los servicios de google play (como geofence o activityrecognition) no funcionan.

  • ¿Qué tan seguro es GoogleAuthUtils.getToken () si la aplicación se descompila
  • La compilación del proyecto Android se ejecutó correctamente pero se ejecutó con error: java.util.zip.ZipException: entrada duplicada
  • Error de ejecución para la tarea ': app: processReleaseGoogleServices'. > Ningún cliente coincidente encontrado para el nombre del paquete
  • ¿Cómo obtener el token de acceso después de que el usuario haya iniciado sesión desde Gmail en Android?
  • Google App invita a las invitaciones que no se envían
  • Appcompat-v7: 21.0.0 no funciona con el servicio de Google Play 6.1+
  • Clase LocationClient no encontrada en los servicios de Google Play rev 22
  • Error al agregar geofences en Android (código de estado 1000)
  • Aidl.exe Error al crear directorios: argumento no válido
  • Google Play Services 9.2.0 clases perdidas
  • Se pierde memoria con GoogleApiClient detectado por Android Studio
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.