Proximity alert is an alert which is triggered by Android LocationManager when the device enters a region specified by its center coordinate (latitude, longitude) and radius.
In this article, we will develop an Android application which demonstrates how to add and remove a proximity alert in Google Map Android API V2. The center of the region is specified by clicking (tap) a location in the Google Map. The radius of the region is hard-coded as 20 meters.
On clicking a location in the Google Map, proximity alert is added and on long clicking on the Google Map, the proximity alert is removed.
An extension to this application is available in the article titled “Adding and removing multiple proximity alerts in Google Maps Android API V2“, where, as the title of the article indicates, multiple proximity alerts can be defined in Google Maps Android API V2.
This application is developed in Eclipse (4.2.1) with ADT plugin (21.1.0) and Android SDK (21.1.0) and tested in a real Android device (Android 2.3.6 - GingerBread).
1. Create a new Android application project namely “ProximityMapV2″
2. Configure the project
3. Design application launcher icon
4. Create a blank activity
5. Enter MainActivity details
6. Download and configure Google Play Services Library in Eclipse
Google Map for Android is now integrated with Google Play Services. So we need to set up Google Play Service Library for developing Google Map application in Android.
Please follow the given below link to setup Google Play Service library in Eclipse.
http://developer.android.com/google/play-services/setup.html
7. Add Google Play Services Library to this project
8. Get the API key for Google Maps Android API V2
We need to get an API key from Google to use Google Maps in Android application.
Please follow the given below link to get the API key for Google Maps Android API v2.
https://developers.google.com/maps/documentation/android/start
9. Add Android Support library to this project
By default, Android support library (android-support-v4.jar ) is added to this project by Eclipse IDE to the directory libs. If it is not added, we can do it manually by doing the following steps :
- Open Project Explorer by Clicking “Window -> Show View -> Project Explorer”
- Right click this project
- Then from popup menu, Click “Android Tools -> Add Support Library “
10. Update the layout file res/layout/activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" > <fragment android:id="@+id/map" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout>
11. Create a layout file res/layout/notification.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/tv_notification" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout>
12. Create the class “NotificationView” in the file src/in/wptrafficanalyzer/proximitymapv2/NotificationView.java
package in.wptrafficanalyzer.proximitymapv2; import android.app.Activity; import android.os.Bundle; import android.widget.TextView; public class NotificationView extends Activity { public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.notification); TextView tv = (TextView) findViewById(R.id.tv_notification); Bundle data = getIntent().getExtras(); tv.setText(data.getString("content")); } }
13. Create the class “ProximityActivity” in the file src/in/wptrafficanalyzer/proximitymapv2/ProximityActivity.java
package in.wptrafficanalyzer.proximitymapv2; import android.app.Activity; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.location.LocationManager; import android.net.Uri; import android.os.Bundle; import android.support.v4.app.NotificationCompat; import android.widget.Toast; public class ProximityActivity extends Activity { String notificationTitle; String notificationContent; String tickerMessage; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); boolean proximity_entering = getIntent().getBooleanExtra(LocationManager.KEY_PROXIMITY_ENTERING, true); if(proximity_entering){ Toast.makeText(getBaseContext(),"Entering the region" ,Toast.LENGTH_LONG).show(); notificationTitle="Proximity - Entry"; notificationContent="Entered the region"; tickerMessage = "Entered the region"; }else{ Toast.makeText(getBaseContext(),"Exiting the region" ,Toast.LENGTH_LONG).show(); notificationTitle="Proximity - Exit"; notificationContent="Exited the region"; tickerMessage = "Exited the region"; } Intent notificationIntent = new Intent(getApplicationContext(),NotificationView.class); notificationIntent.putExtra("content", notificationContent ); /** This is needed to make this intent different from its previous intents */ notificationIntent.setData(Uri.parse("tel:/"+ (int)System.currentTimeMillis())); /** Creating different tasks for each notification. See the flag Intent.FLAG_ACTIVITY_NEW_TASK */ PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, notificationIntent, Intent.FLAG_ACTIVITY_NEW_TASK); /** Getting the System service NotificationManager */ NotificationManager nManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE); /** Configuring notification builder to create a notification */ NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(getApplicationContext()) .setWhen(System.currentTimeMillis()) .setContentText(notificationContent) .setContentTitle(notificationTitle) .setSmallIcon(R.drawable.ic_launcher) .setAutoCancel(true) .setTicker(tickerMessage) .setContentIntent(pendingIntent); /** Creating a notification from the notification builder */ Notification notification = notificationBuilder.build(); /** Sending the notification to system. * The first argument ensures that each notification is having a unique id * If two notifications share same notification id, then the last notification replaces the first notification * */ nManager.notify((int)System.currentTimeMillis(), notification); /** Finishes the execution of this activity */ finish(); } }
14. Update the class “MainActivity” in the file src/in/wptrafficanalyzer/proximitymapv2/MainActivity.java
package in.wptrafficanalyzer.proximitymapv2; import android.app.Dialog; import android.app.PendingIntent; import android.content.Intent; import android.content.SharedPreferences; import android.graphics.Color; import android.location.LocationManager; import android.os.Bundle; import android.support.v4.app.FragmentActivity; import android.view.Menu; import android.widget.Toast; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GooglePlayServicesUtil; import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.GoogleMap.OnMapClickListener; import com.google.android.gms.maps.GoogleMap.OnMapLongClickListener; import com.google.android.gms.maps.SupportMapFragment; import com.google.android.gms.maps.model.CircleOptions; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.MarkerOptions; public class MainActivity extends FragmentActivity { GoogleMap googleMap; LocationManager locationManager; PendingIntent pendingIntent; SharedPreferences sharedPreferences; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Getting Google Play availability status int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getBaseContext()); // Showing status if(status!=ConnectionResult.SUCCESS){ // Google Play Services are not available int requestCode = 10; Dialog dialog = GooglePlayServicesUtil.getErrorDialog(status, this, requestCode); dialog.show(); }else { // Google Play Services are available // Getting reference to the SupportMapFragment of activity_main.xml SupportMapFragment fm = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map); // Getting GoogleMap object from the fragment googleMap = fm.getMap(); // Enabling MyLocation Layer of Google Map googleMap.setMyLocationEnabled(true); // Getting LocationManager object from System Service LOCATION_SERVICE locationManager = (LocationManager) getSystemService(LOCATION_SERVICE); // Opening the sharedPreferences object sharedPreferences = getSharedPreferences("location", 0); // Getting stored latitude if exists else return 0 String lat = sharedPreferences.getString("lat", "0"); // Getting stored longitude if exists else return 0 String lng = sharedPreferences.getString("lng", "0"); // Getting stored zoom level if exists else return 0 String zoom = sharedPreferences.getString("zoom", "0"); // If coordinates are stored earlier if(!lat.equals("0")){ // Drawing circle on the map drawCircle(new LatLng(Double.parseDouble(lat), Double.parseDouble(lng))); // Drawing marker on the map drawMarker(new LatLng(Double.parseDouble(lat), Double.parseDouble(lng))); // Moving CameraPosition to previously clicked position googleMap.moveCamera(CameraUpdateFactory.newLatLng(new LatLng(Double.parseDouble(lat), Double.parseDouble(lng)))); // Setting the zoom level in the map googleMap.animateCamera(CameraUpdateFactory.zoomTo(Float.parseFloat(zoom))); } googleMap.setOnMapClickListener(new OnMapClickListener() { @Override public void onMapClick(LatLng point) { // Removes the existing marker from the Google Map googleMap.clear(); // Drawing marker on the map drawMarker(point); // Drawing circle on the map drawCircle(point); // This intent will call the activity ProximityActivity Intent proximityIntent = new Intent("in.wptrafficanalyzer.activity.proximity"); // Creating a pending intent which will be invoked by LocationManager when the specified region is // entered or exited pendingIntent = PendingIntent.getActivity(getBaseContext(), 0, proximityIntent,Intent.FLAG_ACTIVITY_NEW_TASK); // Setting proximity alert // The pending intent will be invoked when the device enters or exits the region 20 meters // away from the marked point // The -1 indicates that, the monitor will not be expired locationManager.addProximityAlert(point.latitude, point.longitude, 20, -1, pendingIntent); /** Opening the editor object to write data to sharedPreferences */ SharedPreferences.Editor editor = sharedPreferences.edit(); /** Storing the latitude of the current location to the shared preferences */ editor.putString("lat", Double.toString(point.latitude)); /** Storing the longitude of the current location to the shared preferences */ editor.putString("lng", Double.toString(point.longitude)); /** Storing the zoom level to the shared preferences */ editor.putString("zoom", Float.toString(googleMap.getCameraPosition().zoom)); /** Saving the values stored in the shared preferences */ editor.commit(); Toast.makeText(getBaseContext(), "Proximity Alert is added", Toast.LENGTH_SHORT).show(); } }); googleMap.setOnMapLongClickListener(new OnMapLongClickListener() { @Override public void onMapLongClick(LatLng point) { Intent proximityIntent = new Intent("in.wptrafficanalyzer.activity.proximity"); pendingIntent = PendingIntent.getActivity(getBaseContext(), 0, proximityIntent,Intent.FLAG_ACTIVITY_NEW_TASK); // Removing the proximity alert locationManager.removeProximityAlert(pendingIntent); // Removing the marker and circle from the Google Map googleMap.clear(); // Opening the editor object to delete data from sharedPreferences SharedPreferences.Editor editor = sharedPreferences.edit(); // Clearing the editor editor.clear(); // Committing the changes editor.commit(); Toast.makeText(getBaseContext(), "Proximity Alert is removed", Toast.LENGTH_LONG).show(); } }); } } private void drawMarker(LatLng point){ // Creating an instance of MarkerOptions MarkerOptions markerOptions = new MarkerOptions(); // Setting latitude and longitude for the marker markerOptions.position(point); // Adding marker on the Google Map googleMap.addMarker(markerOptions); } private void drawCircle(LatLng point){ // Instantiating CircleOptions to draw a circle around the marker CircleOptions circleOptions = new CircleOptions(); // Specifying the center of the circle circleOptions.center(point); // Radius of the circle circleOptions.radius(20); // Border color of the circle circleOptions.strokeColor(Color.BLACK); // Fill color of the circle circleOptions.fillColor(0x30ff0000); // Border width of the circle circleOptions.strokeWidth(2); // Adding the circle to the GoogleMap googleMap.addCircle(circleOptions); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }
15. Update the file AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="in.wptrafficanalyzer.proximitymapv2" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <permission android:name="in.wptrafficanalyzer.proximitymapv2.permission.MAPS_RECEIVE" android:protectionLevel="signature"/> <uses-permission android:name="in.wptrafficanalyzer.proximitymapv2.permission.MAPS_RECEIVE"/> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-feature android:glEsVersion="0x00020000" android:required="true"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="in.wptrafficanalyzer.proximitymapv2.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".ProximityActivity" android:label="@string/app_name" > <intent-filter > <action android:name="in.wptrafficanalyzer.activity.proximity"/> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> <activity android:name=".NotificationView" android:label="@string/app_name" > <intent-filter > <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> <meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="YOUR_ANDROID_API_KEY"/> </application> </manifest>
Note : Replace “YOUR_ANDROID_API_KEY” at line 60 with the API Key obtained in Step 8.
16. Screenshot of the application
17. Download the source code


I am George Mathew, working as software architect and Android app developer at wptrafficanalyzer.in
You can hire me on hourly basis or on project basis for Android applications development.
For hiring me, please mail your requirements to info@wptrafficanalyzer.in.
My other blogs
store4js.blogspot.com
first i need to thank you for your great work ..but how we can add multiple markers and save it in shared preference can you plz help me
Please see the article titled “Adding multiple marker locations in Google Maps Android API V2 and save it in Shared Preferences“
Thanks George for your quick feedback.As i see you are prof in this work.Cuz i cant find better tutorials about Google Map V2 than yours.Actually i want to do something like this after long click on screen user saves his message with proximity alert then if user enters that area app must show his own message to him which he saved in shared preferences.And it must be enable to add multiple alerts on map.This is my project which i get from university and its too important for me if u can help me with this ill be appreciate.or can we talk from gmail or other social sites so i can explain more.
how to change mylocation is blue arrow
hello i was trying to use this code but i am getting an unusual error
i.e.
the eclipse ide can not find the following import
import com.google.android.gms.maps.model.CircleOptions
but it can recognize the import
import com.google.android.gms.maps.model.LatLng etc.
When I download the work file import in my ADT and tested in my device it worked perfectly. But, when i copy pasted everything (same package name) the app crashes.. why it happens to me??

Good day.
I am a Brazilian student and I have some questions to make my final paper in college. Need to register some points (to display with local marks) in a local database (you posted a similar example), then I would like the user could define a radius 1 mile (for example), then the application queries the database and displays the map only marks that are within 1 mile radius.
How to do it?
PS: I do not speak English, I used google translator
Thanks a lot .. your code solves my problem ..
but i have query on Radius. i don’t know is there any restriction on Radius for addProximityAlert ?.. like minimum or maximum.
when i add locations in proximity it didn’t work.. plz tel me proximity still working when i close my app or when i enter region it show notification or when device near the region.
i want to get an approximity alert when some other user enter or exit the region that i have specified. but i don’t know how to do this.will it be better to use mock location or i need to do some thing else???? i have the locations of other peoples on server.. plz help me i will be very greatful to you.
Gracias, Desde Colombia.. muy agradecido Gracias..
muchos de sus tutoriales lo he seguido.. me parece muy bien lo que hace.. gracias
I want to create a app like this :first register the location and save the lat long in shared preference then check location when device enter in this location if device in geofence area then given button disable otherwise enable and give the attendance.
Finally… :’( brother you saved me!!! Long Live God bless you!! Thanx forever…
hi ur code worked perfectly to me.But intent was not able to fire when the proximity is entering or exiting.please kindly help me
I want to create a same app but using polygons,please help me…
Regards
Process: in.wptrafficanalyzer.proximitymapv2, PID: 12865
java.lang.RuntimeException: Unable to start activity ComponentInfo{in.wptrafficanalyzer.proximitymapv2/in.wptrafficanalyzer.proximitymapv2.MainActivity}: android.view.InflateException: Binary XML file line #7: Error inflating class fragment
i am getting this error while running it on a android device please help
how can we add sound and vibration in it
its works excellent,,, but only thing is last added proximity only working. How to avoid overriding the existing alerts!!!!!!!!!! Pls help… Expecting reply from you….
I cant run the code what’s up.I’m using the latest version please help
hi ur code worked perfectly to me.But intent was not able to fire when the proximity is entering or exiting.please kindly help me
If this codes causes application crashes, simply replace activity_main.xml with:
I have an doubt. when i add one more proximity alert it will over ride first point .how to solve this issue.I am using android studio .So In pending intent ,Intent.FLAG_NEW_TASK shows error itis now depricated.any other value linke PENDINGINTENT_FLAG_UPDATE_CURRENT or something needed.solve this issue