Location Services
In this page you'll dive deeper into functionality like using GPS signals to get the user's location or monitor their visits to regions and proximity to BTLE devices. These services will bring a new level of contextuality to your app, allowing you to create geo-triggers to send notifications or categorize users based on their location behaviour.
As mentioned in the Implementation page, if you are going to use location services, you must include the following permissions in your AndroidManifest.xml:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
Requesting Permission
Additionally to these manifest permissions, since Android 6 (a.k.a Marshmallow), applications will need to request the user permission to use location. These permissions need to be requested from an activity in your app, after which you can safely enable location updates. To make sure the location updates aren't started before the library is ready to be used, you should wait until it is safe to do so, by listening to the OnNotificareReady event.
Let your activity implement the OnNotificareReadyListener interface:
public class MyMainActivity extends ActionBarBaseActivity implements Notificare.OnNotificareReadyListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...more code
Notificare.shared().addNotificareReadyListener(this);
}
@Override
public void onNotificareReady(NotificareApplicationInfo info) {
if (!Notificare.shared().hasLocationPermissionGranted()) {
Log.i(TAG, "permission not granted");
if (Notificare.shared().didRequestLocationPermission()) {
if (Notificare.shared().shouldShowRequestPermissionRationale(this)) {
// Here we should show a dialog explaining location updates
new AlertDialog.Builder()
.setMessage(R.string.alert_location_permission_rationale)
.setTitle(R.string.app_name)
.setCancelable(true)
.setPositiveButton(R.string.button_ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Notificare.shared().requestLocationPermission(MyMainActivity.this, LOCATION_PERMISSION_REQUEST_CODE);
}
})
.create()
.show();
}
} else {
Notificare.shared().requestLocationPermission(this, LOCATION_PERMISSION_REQUEST_CODE);
}
}
}
@Override
protected void onDestroy() {
super.onDestroy();
...more code
Notificare.shared().removeNotificareReadyListener(this);
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case LOCATION_PERMISSION_REQUEST_CODE:
if (Notificare.shared().checkRequestLocationPermissionResult(permissions, grantResults)) {
Log.i(TAG, "permission granted");
Notificare.shared().enableLocationUpdates();
}
break;
}
}
}
Once you have implemented the code above, if permission is granted, our library will automatically collect the user location and start monitoring for regions you've created via the dashboard or API.
Accessing the user location is as easy as invoking the following method:
Notificare.shared().getCurrentLocation();
If authorized, you will also want to start using GPS data whenever your app is launched, you simply have to add the following in your Intent Receiver:
public class MyIntentReceiver extends DefaultIntentReceiver {
@Override
public void onReady() {
...more code
if (Notificare.shared().isLocationUpdatesEnabled()) {
Notificare.shared().enableLocationUpdates();
}
...more code
}
...more code
}
Using Bluetooth Low-Energy beacons
Once you've implemented GPS location in your app, you can also listen to Bluetooth signals from BTLE beacons in your app. Our library will require you to also include the AltBeacon library in your app. Simply add the following to your /app/build.gradle file:
dependencies {
compile 're.notifica:notificare-push-lib-android:1.10.0'
compile 'com.google.firebase:firebase-messaging:11.2.2'
compile 'org.altbeacon:android-beacon-library:2.12.2' // Include this line
}
After that you can enable beacons signals by simply invoking the following method, right after a user has granted permission for tracking location:
public class MyMainActivity extends ActionBarBaseActivity implements Notificare.OnNotificareReadyListener {
..more code
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case LOCATION_PERMISSION_REQUEST_CODE:
if (Notificare.shared().checkRequestLocationPermissionResult(permissions, grantResults)) {
Log.i(TAG, "permission granted");
Notificare.shared().enableLocationUpdates();
Notificare.shared().enableBeacons();
}
break;
}
}
...more code
}
You will also want to enable beacons from your Intent Receiver pretty much the same way you do with location:
public class MyIntentReceiver extends DefaultIntentReceiver {
@Override
public void onReady() {
...more code
if (Notificare.shared().isLocationUpdatesEnabled()) {
Notificare.shared().enableLocationUpdates();
Notificare.shared().enableBeacons();
...more code
}
...more code
}
By doing this, you app will start monitoring for any beacons you inserted via the dashboard or API, in any of your regions.
By default, the app will scan at least every 5 minutes in the background. If you want your app to be more responsive, e.g. once per minute, you can set the interval yourself. Be aware, though, that a shorter interval will mean more power consumption.
Notificare.shared().enableBeacons(60000)
Additionally, if you wish to get information about the beacons in the vicinity, when your app is in the foreground, here's an example of how you would go about in order to create a list of beacons in a fragment:
public class BeaconsFragment extends Fragment implements BeaconRangingListener {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
...more code
if (Notificare.shared().getBeaconClient() != null) {
Notificare.shared().getBeaconClient().addRangingListener(this);
}
...more code
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (Notificare.shared().getBeaconClient() != null) {
Notificare.shared().getBeaconClient().addRangingListener(this);
}
Notificare.shared().setForeground(true);
}
@Override
public void onDetach() {
super.onDetach();
if (Notificare.shared().getBeaconClient() != null) {
Notificare.shared().getBeaconClient().removeRangingListener(this);
}
Notificare.shared().setForeground(false);
}
@Override
public void onRangingBeacons(final List<NotificareBeacon> notificareBeacons) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
beaconListAdapter.clear();
for (NotificareBeacon beacon : notificareBeacons) {
beaconListAdapter.add(beacon);
}
}
}
...more code
}
This is not a mandatory step in order to use beacons, as geo-triggers created in the dashboard will trigger notifications whenever you are in the vicinity of a beacon, even when you app is not being used.
Disable Location
Pretty much the same way you enable location, you can also stop tracking the user location by invoking the following method:
Notificare.shared().disableLocationUpdates();
Disable Beacons
Although beacons will not work without using location, you can also stop listening to beacon advertising signals by invoking the following method:
Notificare.shared().disableBeacons();