Location

This documentation explains how to use the Location module of the Bazaarvoice Mobile SDK for Android to know when your shoppers are entering and exiting your physical retail locations.

Introduction

The Location module of the Bazaarvoice Mobile SDK provides a very valuable opportunity to present a shopper with your location aware content. Perhaps you have a simple greeting or coupon? Aside from the value you add within your mobile experience, Bazaarvoice can use this location context to enhance our existing products. Rating and Reviews filtered down to the city level, recommended products for nearby people like you, and more are all possible by using the Location module.

Installation

📘

You must have Bazaarvoice Location enabled to use the Location module. Contact Bazaarvoice to set up Location and to get your apiKeyLocation.

With Gradle

Include the Maven Central repository and add the appropriate Bazaarvoice Mobile SDK modules to your dependencies:

dependencies {  
    compile 'com.bazaarvoice.bvandroidsdk:location:{BV_SDK_VERSION}.+'  
    compile 'com.google.android.gms:play-services-ads:9.{YOUR_PLAY_SERVICES_VERSION}'  
    compile 'com.android.support:recyclerview-v7:25.{YOUR_SUPPORT_LIBRARY_VERSION}'  
    compile 'com.android.support:support-v4:25.{YOUR_SUPPORT_LIBRARY_VERSION}'  
    compile 'com.android.support:appcompat-v7:25.{YOUR_SUPPORT_LIBRARY_VERSION}'  
}  
repositories {  
    mavenCentral()  
}

Replace the {tokens}, including brackets, with the appropriate values. Refer to the Installation guide for {BV_SDK_VERSION}.

Extending the application

Create a class that extends android.app.Application, and initialize the Mobile SDK using its builder.

You can find a full list of build options in BVSDK.java.

in the following example, YOUR_CLIENT_ID represents your client name, such as "bazaarvoice". If you are unsure about your client ID or API key values, contact Bazaarvoice Support or your implementation team.

public class MyApplication extends Application {

  @Override  
  public void onCreate() {  
    super.onCreate();  
    BVSDK.builder(application, BazaarEnvironment.PRODUCTION)  
      .logLevel(BVLogLevel.VERBOSE) // Optional: Set the log level. Default level is ERROR.  
      .dryRunAnalytics(false)       // Optional: Set analytics to log only, not make a network request. Default is false.  
      .okHttpClient(okHttpClient)   // Optional: Use you own okHttpClient instance  
      .build();  
  }  
}

App manifest file

Add the following to your AndroidManifest.xml file.

<application
    android:name=".MyApplication">  
</application>

Usage

Requesting user location permission

You will need to obtain fine location permission. The Location module cannot function without this. This permission is included in the Location module's manifest, but please note that your app might need to support Runtime Permissions for obtaining fine location.

Please follow best practices when requesting permission at Runtime. Request it at a time when it's contexually relevant such as when trying to use a "Store Finder." Ask via your own dialog first then present the actual system prompt if they accepted your prompt. This way you can provide the detailed benefits they'd receive if they grant the permission. There are many online resources you refer to when making you permission request decisions.

TODO - We should provide a few links to resources

Listening for location events in the background

Once location permissions have been accepted you can now begin listening for geofence notifications. In order to do be listening even when the app has been backgrounded and/or killed you should implement your own Service which then sets up location listeners with the BVLocationManager.

Add the new Service to your Manifest:

<manifest>
      <application>
          <service
            android:name="com.mycompany.myapp.DemoLocationService"
            android:exported="false" />
      </application>
  </manifest>

Implement a basic listening service:

public class DemoLocationService extends Service {
    @Override
    public void onCreate() {
        super.onCreate();
        BVLocationManager.getInstance().startMonitoringLocation();
    }
 
    @Override
    public void onDestroy() {
        BVLocationManager.getInstance().stopMonitoringLocation();
        super.onDestroy();
    }
 
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

Listening for when your users enter/exit your locations

In order to be notified when a user enter/exits a store you should add a BVLocationManager.BVLocationListener to your service.

public class DemoLocationService extends Service {
    public static final String ACTION_VISIT_START = "com.mycompany.myapp.action.VISIT_START";
    public static final String ACTION_VISIT_END = "com.mycompany.myapp.action.VISIT_END";
 
    public static final String EXTRA_STORE_ID = "extra_store_id";
 
    private BVLocationManager.BVLocationListener bvLocationListener = new BVLocationManager.BVLocationListener() {
        @Override
        public void didBeginVisit(BVVisit visit) {
            Intent intent = new Intent(ACTION_VISIT_START);
            intent.putExtra(EXTRA_STORE_ID, visit.getStoreId());
            sendBroadcast(intent);
        }
 
        @Override
        public void didEndVisit(BVVisit visit) {
            Intent intent = new Intent(ACTION_VISIT_END);
            intent.putExtra(EXTRA_STORE_ID, visit.getStoreId());
            sendBroadcast(intent);
        }
    };
 
    @Override
    public void onCreate() {
        super.onCreate();
        BVLocationManager.getInstance().addLocationVisitListener(bvLocationListener);
        BVLocationManager.getInstance().startMonitoringLocation();
    }
 
    @Override
    public void onDestroy() {
        BVLocationManager.getInstance().stopMonitoringLocation();
        BVLocationManager.getInstance().removeLocationVisitListener(bvLocationListener);
        super.onDestroy();
    }
 
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
 
}

Once you have setup your service, you are now ready to begin listening for the broadcasts that you send from it. Below is an example of an Activity which has it's own inner BroadcastReceiver which is listening for the custom events we made above. You could implement your own standalone BroadcastReceiver as well that is registered in the AndroidManifest.xml if you wished to have your app always listening for your custom broadcasts.

public class DemoLocationActivity extends AppCompatActivity {
    private BroadcastReceiver demoLocationReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction() != null) {
                switch (intent.getAction()) {
                    case DemoLocationService.ACTION_VISIT_START: {
                        String storeId = intent.getStringExtra(DemoLocationService.EXTRA_STORE_ID);
                        updateLastLocEvent("visit start for " + storeId);
                        break;
                    }
                    case DemoLocationService.ACTION_VISIT_END: {
                        String storeId = intent.getStringExtra(DemoLocationService.EXTRA_STORE_ID);
                        updateLastLocEvent("visit end for " + storeId);
                        break;
                    }
                }
            }
        }
    };
 
    private void updateLasLocEvent(String lastLocEvent) {
        // ...
    }
}

Listening for when your user taps review notification

In order to be notified when a user has tapped a notification, asking to review a product, you should add a BVLocationManager.BVRateStoreListener to your service.

public class DemoLocationService extends Service {
    public static final String ACTION_RATE_STORE = "com.bazaarvoice.bvsdkdemoandroid.action.RATE_STORE";
 
    public static final String EXTRA_STORE_ID = "extra_store_id";
 
    private BVLocationManager.BVRateStoreListener rateStoreListener = new BVLocationManager.BVRateStoreListener() {
        @Override
        public void onRateStoreClicked(String storeId) {
            Intent intent = new Intent(ACTION_RATE_STORE);
            intent.putExtra(EXTRA_STORE_ID, storeId);
            sendBroadcast(intent);
        }
    };
 
    @Override
    public void onCreate() {
        super.onCreate();
        BVLocationManager.getInstance().addRateStoreListener(rateStoreListener);
        BVLocationManager.getInstance().startMonitoringLocation();
    }
 
    @Override
    public void onDestroy() {
        BVLocationManager.getInstance().stopMonitoringLocation();
        BVLocationManager.getInstance().removeRateStoreListener(rateStoreListener);
        super.onDestroy();
    }
 
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
 
}

Once you have setup your service, you are now ready to begin listening for the broadcasts that you send from it. Below is an example of an Activity which has it's own inner BroadcastReceiver which is listening for the custom events we made above. You could implement your own standalone BroadcastReceiver as well that is registered in the AndroidManifest.xml if you wished to have your app always listening for your custom broadcasts.

public class DemoLocationActivity extends AppCompatActivity {
    private BroadcastReceiver demoLocationReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction() != null) {
                switch (intent.getAction()) {
                    case DemoLocationService.ACTION_RATE_STORE: {
                        String storeId = intent.getStringExtra(DemoLocationService.EXTRA_STORE_ID);
                        updateLastLocEvent("user tapped rate store for " + storeId);
                        break;
                    }
                }
            }
        }
    };
 
    private void updateLasLocEvent(String lastLocEvent) {
        // ...
    }
}