The great power of mobile applications software, is that it gives us the opportunity to develop many ideas that use hardware features, in order to complete simple everyday tasks. One idea that is implemented in a very good way in the mobile applications world, is the use of maps and the location based applications, that help us in multiple ways in our every day life. So, the use of maps is very important in various mobile applications.
Google provides a library (Google Play Services) for using Google Maps and many others features in your application. The following description is based on the Google Maps Android API v2 which provides significant improvements to the older API version.
The library provides
MapFragment
and MapView
classes to displaying the map component.In this post, I will present how to "embed" Google Map in your app and find/update our current location when we have moved.
1. Making SHA-1 Fingerprint
keytool -list -v -keystore "%USERPROFILE%\.android\debug.keystore" -alias androiddebugkey -storepass android -keypass android
So we'll have a SHA-1 key:2. Create a Google Maps API key
Step 2: In project Dashboard, On the left sidebar, select API & auth/API. Select Google Map API and Google Place API for Android and enable it.
Step 3: Now, back to Dashboard, select Credentials from left sidebar and click "Create a new key" under Public API access entry. When alert dialog shows, click "Android Key".
Step 4: Paste above SHA-1 key and your project’s package name separated by semicolon(;):
Step 5: After click create, we'll have a new project key:
Okey, we have finished Settings in Google Developer Console, now, we will create an android project to use this API key.
3. Creating Android Project
info.devexchanges.googlelocation
(same as description in Developer Console page). Min-sdk I used is 14.In this, I complete 3 tasks:
- Display a Google Map as a
MapFragment
and put it in an activity.- Find user current location and update it when moved.
- Showing user current address based on the
Location
(longitude and latitude).Declaring an activity layout which contains a
MapFragment
and 2 TextViews
(display location and address):
activity_location.xml
In programmatically code, for update current location, I use <LinearLayout 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"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin">
<fragment
android:id="@+id/map"
class="com.google.android.gms.maps.MapFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.7" />
<TextView
android:id="@+id/location"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.1" />
<TextView
android:id="@+id/address"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.2" />
</LinearLayout>
OnMyLocationChangeListener
interface, make a method with this datatypes to detect current location, adding marker with this place like this:
private GoogleMap.OnMyLocationChangeListener myLocationChangeListener() {
return new GoogleMap.OnMyLocationChangeListener() {
@Override
public void onMyLocationChange(Location location) {
LatLng loc = new LatLng(location.getLatitude(), location.getLongitude());
double longitude = location.getLongitude();
double latitude = location.getLatitude();
Marker marker;
marker = map.addMarker(new MarkerOptions().position(loc));
map.animateCamera(CameraUpdateFactory.newLatLngZoom(loc, 16.0f));
locationText.setText("You are at [" + longitude + " ; " + latitude + " ]");
//get current address by invoke an AsyncTask object
new GetAddressTask(LocationActivity.this).execute(String.valueOf(latitude), String.valueOf(longitude));
}
};
}
GoogleMap
object, we must call map.setOnMyLocationChangeListener(myLocationChangeListener())
to handling location changes event.By getting address components from a [latitude, longitude] pair, we'll use
GeoCoder
class to parsing it by getFromLocation()
method. Our result after this method is a List
of Address
objects (we set this List has max only one element by call geocoder.getFromLocation(latitude, longitude, 1)
).This whole process is placed in an
AsyncTask
. In doInBackground()
, we parse address and return a String
result.In
onPostExcute()
, calling back data to main thread UI to display them later.Full code for this custom
AsyncTask
:
GetAddressTask.java
And code of package info.devexchanges.googlelocation;
import android.location.Address;
import android.location.Geocoder;
import android.os.AsyncTask;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
public class GetAddressTask extends AsyncTask<String, Void, String> {
private LocationActivity activity;
public GetAddressTask(LocationActivity activity) {
super();
this.activity = activity;
}
@Override
protected String doInBackground(String... params) {
Geocoder geocoder;
List<Address> addresses;
geocoder = new Geocoder(activity, Locale.getDefault());
try {
addresses = geocoder.getFromLocation(Double.parseDouble(params[0]), Double.parseDouble(params[1]), 1);
//get current Street name
String address = addresses.get(0).getAddressLine(0);
//get current province/City
String province = addresses.get(0).getAdminArea();
//get country
String country = addresses.get(0).getCountryName();
//get postal code
String postalCode = addresses.get(0).getPostalCode();
//get place Name
String knownName = addresses.get(0).getFeatureName(); // Only if available else return NULL
return "Street: " + address + "\n" + "City/Province: " + province + "\nCountry: " + country
+ "\nPostal CODE: " + postalCode + "\n" + "Place Name: " + knownName;
} catch (IOException ex) {
ex.printStackTrace();
return "IOE EXCEPTION";
} catch (IllegalArgumentException ex) {
ex.printStackTrace();
return "IllegalArgument Exception";
}
}
/**
* When the task finishes, onPostExecute() call back data to Activity UI and displays the address.
* @param address
*/
@Override
protected void onPostExecute(String address) {
// Call back Data and Display the current address in the UI
activity.callBackDataFromAsyncTask(address);
}
}
LocationActivity
:
LocationActivity.java
We must add this dependency in "app/build.gradle" file to use GoogleMap API:
package info.devexchanges.googlelocation;
import android.app.Activity;
import android.location.Address;
import android.location.Criteria;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
public class LocationActivity extends Activity {
private TextView locationText;
private TextView addressText;
private GoogleMap map;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_location);
locationText = (TextView) findViewById(R.id.location);
addressText = (TextView) findViewById(R.id.address);
//replace GOOGLE MAP fragment in this Activity
replaceMapFragment();
}
private void replaceMapFragment() {
map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map))
.getMap();
// Enable Zoom
map.getUiSettings().setZoomGesturesEnabled(true);
//set Map TYPE
map.setMapType(GoogleMap.MAP_TYPE_NORMAL);
//enable Current location Button
map.setMyLocationEnabled(true);
//set "listener" for changing my location
map.setOnMyLocationChangeListener(myLocationChangeListener());
}
private GoogleMap.OnMyLocationChangeListener myLocationChangeListener() {
return new GoogleMap.OnMyLocationChangeListener() {
@Override
public void onMyLocationChange(Location location) {
LatLng loc = new LatLng(location.getLatitude(), location.getLongitude());
double longitude = location.getLongitude();
double latitude = location.getLatitude();
Marker marker;
marker = map.addMarker(new MarkerOptions().position(loc));
map.animateCamera(CameraUpdateFactory.newLatLngZoom(loc, 16.0f));
locationText.setText("You are at [" + longitude + " ; " + latitude + " ]");
//get current address by invoke an AsyncTask object
new GetAddressTask(LocationActivity.this).execute(String.valueOf(latitude), String.valueOf(longitude));
}
};
}
public void callBackDataFromAsyncTask(String address) {
addressText.setText(address);
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.2.0'
compile 'com.google.android.gms:play-services:7.5.0' //add this line to use Google Map API
}
4. Running application
(Sorry for have ads link)