I'm writing applications to display geofences, for now without monitoring. It only displays a map without marked geofences.Below I put the code for the application.

MapsActivity:

package com.example.addgeo;

import android.app.PendingIntent;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.Geofence;
import com.google.android.gms.location.GeofencingRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import java.util.ArrayList;
import java.util.Map;

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener, ResultCallback<Status> {

private GoogleMap mMap;
protected ArrayList<Geofence> mGeofenceList;
protected GoogleApiClient mGoogleApiClient;
private Button mAddGeofencesButton;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_maps);

    // Obtain the SupportMapFragment and get notified when the map is ready to be used.
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);
    //mAddGeofencesButton = (Button) findViewById(R.id.add_geofences_button);
    // Empty list for storing geofences.
    mGeofenceList = new ArrayList<Geofence>();

    // Get the geofences used. Geofence data is hard coded in this sample.
    populateGeofenceList();

    // Kick off the request to build GoogleApiClient.
    buildGoogleApiClient();
}

protected synchronized void buildGoogleApiClient() {
    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();
}

public void populateGeofenceList() {
    for (Map.Entry<String, LatLng> entry : Constants.LANDMARKS.entrySet()) {
        mGeofenceList.add(new Geofence.Builder()
                .setRequestId(entry.getKey())
                .setCircularRegion(
                        entry.getValue().latitude,
                        entry.getValue().longitude,
                        Constants.GEOFENCE_RADIUS_IN_METERS
                )
                .setExpirationDuration(Constants.GEOFENCE_EXPIRATION_IN_MILLISECONDS)
                .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER |
                        Geofence.GEOFENCE_TRANSITION_EXIT)
                .build());
    }
}

@Override
protected void onStart() {
    super.onStart();
    if (!mGoogleApiClient.isConnecting() || !mGoogleApiClient.isConnected()) {
        mGoogleApiClient.connect();
    }
}

@Override
protected void onStop() {
    super.onStop();
    if (mGoogleApiClient.isConnecting() || mGoogleApiClient.isConnected()) {
        mGoogleApiClient.disconnect();
    }
}


@Override
public void onConnectionSuspended(int cause) {
    mGoogleApiClient.connect();
}

public void addGeofencesButtonHandler(View view) {
    if (!mGoogleApiClient.isConnected()) {
        Toast.makeText(this, "Google API Client not connected!", Toast.LENGTH_SHORT).show();
        return;
    }

    try {
        LocationServices.GeofencingApi.addGeofences(
                mGoogleApiClient,
                getGeofencingRequest(),
                getGeofencePendingIntent()
        ).setResultCallback(this); // Result processed in onResult().
    } catch (SecurityException securityException) {
        // Catch exception generated if the app does not use ACCESS_FINE_LOCATION permission.
    }
}

private GeofencingRequest getGeofencingRequest() {
    GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
    builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER);
    builder.addGeofences(mGeofenceList);
    return builder.build();
}

private PendingIntent getGeofencePendingIntent() {
    Intent intent = new Intent(this, GeofenceTransitionsIntentService.class);
    // We use FLAG_UPDATE_CURRENT so that we get the
    //same pending intent back when calling addgeoFences()
    return PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}

public void onResult(Status status) {
    if (status.isSuccess()) {
        Toast.makeText(
                this,
                "Geofences Added",
                Toast.LENGTH_SHORT
        ).show();
    } else {
        // Get the status code for the error and log it using a user-friendly message.
        System.out.println("Error");
    }
}

@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;

    // Add a marker in Sydney and move the camera
    LatLng sydney = new LatLng(-34, 151);
    mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
    mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
}

@Override
public void onConnected(@Nullable Bundle bundle) {

}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

}
}

In the Constants class there are points from which he wants to create geofences. Constants:

package com.example.addgeo;
import com.google.android.gms.maps.model.LatLng;
import java.util.HashMap;
public class Constants {

public static final long GEOFENCE_EXPIRATION_IN_MILLISECONDS = 12 * 60 * 60 * 1000;
public static final float GEOFENCE_RADIUS_IN_METERS = 20;

public static final HashMap<String, LatLng> LANDMARKS = new HashMap<String, LatLng>();
static {
    // San Francisco International Airport.
    LANDMARKS.put("Moscone South", new LatLng(37.783888,-122.4009012));

    // Googleplex.
    LANDMARKS.put("Japantown", new LatLng(37.785281,-122.4296384));

    // Test
    LANDMARKS.put("SFO", new LatLng(37.621313,-122.378955));
}
}

Class GeofenceTransitionsIntentService is empty because for now I do not use it, later it will serve me to monitor geofences.

  <?xml version="1.0" encoding="utf-8"?>
  <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.example.addgeo">

<!--
     The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
     Google Maps Android API v2, but you must specify either coarse or fine
     location permissions for the 'MyLocation' functionality.
-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">

    <meta-data
        android:name="com.google.android.geo.API_KEY"
        android:value="@string/google_maps_key" />
    <meta-data
        android:name="com.google.android.gms.version"
        android:value="@integer/google_play_services_version" />
    <activity
        android:name=".MapsActivity"
        android:label="@string/title_activity_maps">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

</manifest>

0 Answers