--

Monday, 28 November 2016

Accurate Geofencing optimization using Broadcast receiver

          Geofencing API triggers alert to the user when entering or exiting specified radius of certain latitude and longitude at any location. However, the existing Geofence API is often unstable when a user moves around the places by car or train ( i.e. users move fast while driving).

We should make sure the possible scenarios failed to trigger when the device enters a geofence,

⦁         If your geofence is too small or failed to fetch location inside premises. For best results, the minimum radius of the geofence should be set between 100 - 150 meters. When Wi-Fi is available location accuracy is usually between 20 - 50 meters.
⦁        If the device is not connected to the internet either WiFi or cellular data.
⦁        Alerts can be slow or delay to trigger.
⦁        Adding multiple fences inside the fence.
⦁        The maximum active geofences are 100 per device user.

  If we implement the following suggestions to achieve better-optimized Geofencing feature,

⦁        Instead of receiving the transitions using a Service, we should go for a BroadcastReceiver. If not you will not/might not get it if your app gets killed/turned off.
⦁        It is recommended to go for a boot-broadcast receiver. When you recreate your geofences after the device is rebooted.
⦁        We always get a trigger immediately for a newly created geofence, if the device discovers that you're inside the geofence when creating it.

Better battery optimization technique:

⦁        Create and connect locationclient.
⦁        In connect-callback, do adding/removing of geofence(s)
⦁        In geofence-result callback, disconnect locationclient.

Every time this happens, my location client is only connected a few seconds in total. The operating system will still produce geofence alerts and call my BroadcastReceiver whenever they happen.

         I have attached the workflow video for better understanding of this feature.


                                    
                          
This video shows that a user adds their desired latitude and longitude with the suitable title. Geofencing API triggers notification once the user enters or exits the fence.

I elucidate the following optimization approaches to trigger notification efficiently,

Step 1 :
Eradicate the Service implementation, and integrate BroadcastReceiver solution to boost the results.

<receiver
    android:name=".GeofecneBroadcastReceiver"
    android:enabled="true"
    android:exported="false" >
    <intent-filter >
        <action android:name="com.truedreamz.geofence.ACTION_RECEIVE_GEOFENCE"/>
    </intent-filter>
</receiver>

add receiver inside application tag in manifest.

Step 2:
Handling enter or exit transition in onReceive() method of BroadcastReceiver. We have to transfer data to activity for triggering the geofencing location added as pending intent.


    // Get the type of transition (entry or exit)
    int geofenceTransition = geofencingEvent.getGeofenceTransition();
    // Test that a valid transition was reported
    if ((geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER)
            || (geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT)) {
        // Get the geofences that were triggered. A single event can trigger multiple geofences.
        List<Geofence> triggeringGeofences = geofencingEvent.getTriggeringGeofences();
        for (Geofence geofence : triggeringGeofences) {
            String geofenceTransitionString = getTransitionString(geofenceTransition);
            String geofenceText=geofenceTransitionString+" : "+geofence.getRequestId();
            Log.i(TAG, "Geofence Transition:" + geofenceText);
            sendEventDetailNotificatonIntent(geofenceText);
            // Create an Intent to broadcast to the app
            broadcastIntent.setAction(GEOFENCE_ACTION)
                    .putExtra("EXTRA_GEOFENCE_ID", geofence.getRequestId())
                    .putExtra("EXTRA_GEOFENCE_TRANSITION_TYPE", geofenceTransitionString);
            LocalBroadcastManager.getInstance(context).sendBroadcast(broadcastIntent);
        }
    } else {
        // Always log as an error
        Log.e(TAG,
                context.getString(R.string.geofence_transition_invalid_type,
                       geofenceTransition));
    }

Step 3:

Before receiving the broadcast, we should add geofence as pending intent when the user clicks 'Add Landmark' from this project.

    String GEOFENCE_ACTION="com.truedreamz.geofence.ACTION_RECEIVE_GEOFENCE";
    if (null != mGeofencePendingIntent) {
        // Return the existing intent
        return mGeofencePendingIntent;
        // If no PendingIntent exists
    } else {
        // Create an Intent pointing to the IntentService
        Intent intent = new Intent(GEOFENCE_ACTION);
        return PendingIntent.getBroadcast(
                getApplicationContext(),
                0,
                intent,
                PendingIntent.FLAG_UPDATE_CURRENT);
    }

Need of pending intent:

       A pending intent that that is reused when calling removeGeofences(). This pending intent is used to generate an intent when a matched geofence transition is observed.

I have attached the following screenshots for reference,

The user enters place name & description for adding landmark.



















   





The map activity shows when user tap on location icon from home screen.










The user has to enter the address that filter out based on places API and Auto-complete API.










When the user enters or exit fence, API triggers the notification.












Herewith I have shared the full working source code for Accurate Geofencing App in Github,
https://github.com/JayaprakashR-Zealot/AccurateGeofencing

Kindly raise your queries in the comment section.

Happy Coding !!!
Thanks...

6 comments:

  1. This comment has been removed by a blog administrator.

    ReplyDelete
  2. This comment has been removed by a blog administrator.

    ReplyDelete
  3. That's interesting! Can you please share more about it? Thank you.


    Fencing Services in Tamil Nadu

    ReplyDelete
  4. I implemented this,but it still fails to work on few phones like oneplus,etc,Do you have solution for this ,based on your experiments

    ReplyDelete
  5. This comment has been removed by the author.

    ReplyDelete