#3 Setting up the permissions needed to allow the app to use GPS. Okay! Press project on the left toolbar if it doesn t show an overview of the app yet. In this project plane, we will navigate to the manifests folder and double-click on AndroidManifest.xml Now we are going to insert the permissions needed to allow the app to work. You need to add the following code: <uses-permission android:name="android.permission.access_coarse_location"/> <uses-permission android:name="android.permission.access_fine_location" /> <uses-permission android:name="android.permission.vibrate" /> What does it do? When you install the app it will ask you permissions to use certain data. This three lines of code ensure that the app can use GPS for rough location, GPS + WiFi for a finer location, vibrate for the notification. #4 Setting up the layout of your app Navigate in your project plan on your left to the layout resource. You will need to add 2 textboxes and 2 buttons. You can do this by using the following code setup. <EditText android:id="@+id/point_latitude" android:layout_width="fill_parent" android:hint="latitude" android:inputtype="textnosuggestions" android:textcolor="@android:color/black" android:textcolorhint="@android:color/black" android:textsize="16dp" android:layout_alignparenttop="true"
android:layout_alignparentleft="true" android:layout_alignparentstart="true" /> <EditText android:id="@+id/point_longitude" android:layout_width="fill_parent" android:hint="longitude" android:inputtype="textnosuggestions" android:textcolor="@android:color/black" android:textcolorhint="@android:color/black" android:textsize="16dp" android:layout_margintop="31dp" android:layout_below="@+id/point_latitude" android:layout_centerhorizontal="true" /> <Button android:id="@+id/add_alert_button" android:text="add Alert" android:layout_width="wrap_content" android:layout_gravity="center_horizontal" android:layout_below="@+id/find_coordinates_button" android:layout_alignparentleft="true" android:layout_alignparentstart="true" /> <Button android:id="@+id/find_coordinates_button" android:text="find Coordinates" android:layout_width="wrap_content" android:layout_gravity="center_horizontal" android:layout_below="@+id/point_longitude" android:layout_alignparentleft="true" android:layout_alignparentstart="true" android:layout_margintop="31dp" /> EditText The first EditText creates a box for the measured Latitude, the second for the Longtitude. Most of the code is for the layout of the app, however several things are important: android:id="@+id/point_latitude" android:hint="latitude" android:inputtype="textnosuggestions" The android:id set the name to which the Textbox references. In order to show you, the user, what textbox contains what, android:hint can be used. This will temporarily show a string of text that will be replaced as soon as something (in this case our GPS coordinates) is requested by pressing the button. To make sure that you, the user do not insert text in these boxes, you can add android:inputtype command as written as the one above. However this does mean that you cannot set your location manually. Thus, you have physically be at the place of which you want to use your GPS coordinates. Button The buttons allow for the user to start an activity that can lead to adding the GPS coordinates to create a Proximity Alert or retrieving the coordinates of your phone and displaying them.
android:id="@+id/add_alert_button" android:text="add Alert" For the buttons, two main things are important: the reference name (android:id) and displaying the text into the buttons (android:text). #5 Setting up the MainActivity Java Class import libraries. Well that sounds like an very difficult task Maybe, but hopefully with the overview of the code I used and explanation of the important bits of code in between, you ll get the gist of it. In order to use several commands and functions, we have to import several libraries. This can be done at the top part of the code (see import) import android.manifest; import android.content.pm.packagemanager; import android.os.bundle; import android.support.v4.app.activitycompat; import android.view.view; import java.text.decimalformat; import java.text.numberformat; import android.app.activity; import android.app.pendingintent; import android.content.context; import android.content.intent; import android.content.intentfilter; import android.content.sharedpreferences; import android.location.location; import android.location.locationlistener; import android.location.locationmanager; import android.view.view.onclicklistener; import android.widget.button; import android.widget.edittext; import android.widget.toast; With these imports, several things become available to us: we can retrieve the location, display the correct buttons, text and make it possible to capture the location in decimal number format.
Next up, defining the different name we will use and setting a static value for them. private static final long MINIMUM_DISTANCECHANGE_FOR_UPDATE = 1; // in Meters private static final long MINIMUM_TIME_BETWEEN_UPDATE = 1000; // in Milliseconds private static final long POINT_RADIUS = 3; // in Meters private static final long PROX_ALERT_EXPIRATION = -1; private static final String POINT_LATITUDE_KEY = "POINT_LATITUDE_KEY"; private static final String POINT_LONGITUDE_KEY = "POINT_LONGITUDE_KEY"; private static final String PROX_ALERT_INTENT = "com.javacodegeeks.android.lbs.proximityalert"; private static final NumberFormat nf = new DecimalFormat("##.########"); private LocationManager locationmanager; private EditText latitudeedittext; private EditText longitudeedittext; private Button findcoordinatesbutton; private Button savepointbutton; If you want to adjust the update speed, you can replace the first static name by changing the 1 and in the second static name the 1000. When you want the app to send a proximityalert later or earlier, it is important to chance the point_radius. #6 Setting up the public Class in MainActivity Java Class Let s continue with the needed code. @Override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.mainactivity); locationmanager = (LocationManager) getsystemservice(context.location_service); locationmanager.requestlocationupdates( LocationManager.GPS_PROVIDER, MINIMUM_TIME_BETWEEN_UPDATE, MINIMUM_DISTANCECHANGE_FOR_UPDATE, new MyLocationListener() ); latitudeedittext = (EditText) findviewbyid(r.id.point_latitude); longitudeedittext = (EditText) findviewbyid(r.id.point_longitude); findcoordinatesbutton = (Button) findviewbyid(r.id.find_coordinates_button); savepointbutton = (Button) findviewbyid(r.id.add_alert_button); findcoordinatesbutton.setonclicklistener(new OnClickListener() { @Override public void onclick(view v) { populatecoordinatesfromlastknownlocation(); ); savepointbutton.setonclicklistener(new OnClickListener() { @Override
); public void onclick(view v) { saveproximityalertpoint(); private void saveproximityalertpoint() { Location location = locationmanager.getlastknownlocation(locationmanager.gps_provider); if (location == null) { Toast.makeText(this, "No last known location. Aborting...", Toast.LENGTH_LONG).show(); savecoordinatesinpreferences((float) location.getlatitude(), (float) location.getlongitude()); addproximityalert(location.getlatitude(), location.getlongitude()); 0); private void addproximityalert(double latitude, double longitude) { Intent intent = new Intent(PROX_ALERT_INTENT); PendingIntent proximityintent = PendingIntent.getBroadcast(this, 0, intent, locationmanager.addproximityalert( latitude, // the latitude longitude, // the longitude POINT_RADIUS, // the radius in meters PROX_ALERT_EXPIRATION, // time for this proximity alert proximityintent // will be used to generate an Intent to fire ); IntentFilter filter = new IntentFilter(PROX_ALERT_INTENT); registerreceiver(new ProximityIntentReceiver(), filter); private void populatecoordinatesfromlastknownlocation() { Location location = locationmanager.getlastknownlocation(locationmanager.gps_provider); if (location!=null) { latitudeedittext.settext(nf.format(location.getlatitude())); longitudeedittext.settext(nf.format(location.getlongitude())); private void savecoordinatesinpreferences(float latitude, float longitude) { SharedPreferences prefs = this.getsharedpreferences(getclass().getsimplename(), Context.MODE_PRIVATE);
SharedPreferences.Editor prefseditor = prefs.edit(); prefseditor.putfloat(point_latitude_key, latitude); prefseditor.putfloat(point_longitude_key, longitude); prefseditor.commit(); private Location retrievelocationfrompreferences() { SharedPreferences prefs = this.getsharedpreferences(getclass().getsimplename(), Context.MODE_PRIVATE); Location location = new Location("POINT_LOCATION"); location.setlatitude(prefs.getfloat(point_latitude_key, 0)); location.setlongitude(prefs.getfloat(point_longitude_key, 0)); return location; public class MyLocationListener implements LocationListener { public void onlocationchanged(location location) { Location pointlocation = retrievelocationfrompreferences(); float distance = location.distanceto(pointlocation); Toast.makeText(ProxAlertActivity.this, "Distance from Point:"+distance, Toast.LENGTH_LONG).show(); public void onstatuschanged(string s, int i, Bundle b) { public void onproviderdisabled(string s) { public void onproviderenabled(string s) { In this huge part of code, the main things are: We set the layout of the app in combination with the code written, we initialize the locationmanager to allow the system to make use of the permissions we set earlier to gain access the location of the phone. The permissions required is checked to make sure that we indeed have permission. Also, we enable the app to react when buttons are pressed: To overwrite the text in the textboxes in the layout, we replace it with the retrieved longitude and latitude coordinates. And we allow the app to save these coordinates. A failsafe is installed as well. If the location cannot be retrieved, the app will display an error stating: "No last known location. Aborting...". As a result the app will not freeze. Another interesting step is displaying the distance from the saved point to your current location. This is done in the last Class of the code overview. A reference is made to a new Java Class: ProximityIntentReceiver, which will be discussed in the next step. #7 Last Java Class: ProximityIntentReceiver In this class, the notification is build. Main points of this code are the following: Imports: import android.annotation.targetapi; import android.app.notification; import android.app.notificationmanager;
import android.content.broadcastreceiver; import android.content.context; import android.content.intent; import android.content.res.resources; import android.graphics.bitmap; import android.graphics.bitmapfactory; import android.location.locationmanager; import android.os.build; import android.support.v4.app.notificationcompat; import android.util.log; Most important parts of coding the main notification: public static void notify(final Context context) { final Resources res = context.getresources(); final Bitmap picture = BitmapFactory.decodeResource(res, R.drawable.ic_place_24dp); final String title = "Proximity Alert!"; final String text = "You are near Industrial Design"; final NotificationCompat.Builder builder = new NotificationCompat.Builder(context).setDefaults(Notification.DEFAULT_ALL).setContentTitle(title).setContentText(text).setPriority(NotificationCompat.PRIORITY_DEFAULT).setAutoCancel(true); notify(context, builder.build()); This notification can be changed into whatever you would like to display. The title of the notification is stated in the final String title and the text explaining the notification is defined at the final String text.