Vous êtes sur la page 1sur 16

6/25/2015

AndroidLocationAPIusingGooglePlayServices

Android Location API using Google Play Services

Android GPS, Location Manager, I explained how to get device location (latitude & longitude) using the older android APIs. Now google introduced new way of g
Services.
A newer api called FusedLocationApi was introduced which connects with GoogleApiClient and gives us the best location available.
So lets start this by creating a simple app.

1. Downloading & Importing Google Play Services

As this app needs Google Play Services, we need to setup the play services first. If you have the play services installed already, update them to latest version using An
1. Open Android SDK Manager and install or update the play services under Extras section.

2. In Eclipse goto File Import Android Existing Android Code Into Workspace
3. Click on Browse and select Google Play Services project from your android sdk folder. You can locate play services library project from
android-sdk-windows\extras\google\google_play_services\libproject\google-play-services_lib
4. And check Copy projects into workspace option as shown in the below image, which places a copy of play services in eclipse workspace.

http://www.androidhive.info/2015/02/androidlocationapiusinggoogleplayservices/

1/16

6/25/2015

AndroidLocationAPIusingGooglePlayServices

2. Creating Android Project


Once the play services are downloaded and imported into eclipse workspace, we can start building a simple app with the location services integrated.
1. In Eclipse create a new android project by navigating to File New Android Application Project and fill out all the required details.
I gave my project name as Location API and package name as info.androidhive.locationapi
2. Add the Google Play Services project as a library to our project. Right click on the project and select properties. In the properties window, on left side select
under library section. Click it and select google play services library which we imported previously

http://www.androidhive.info/2015/02/androidlocationapiusinggoogleplayservices/

2/16

6/25/2015

AndroidLocationAPIusingGooglePlayServices

http://www.androidhive.info/2015/02/androidlocationapiusinggoogleplayservices/

3/16

6/25/2015

AndroidLocationAPIusingGooglePlayServices

3. Download this marker.png and paste it in your projects src res drawable-ldpi folder. (Please note that this is a white color png image, it might not be visible

http://www.androidhive.info/2015/02/androidlocationapiusinggoogleplayservices/

4/16

6/25/2015

AndroidLocationAPIusingGooglePlayServices

4. Open strings.xml located under res values and add below string values.

strings.xml
<?xmlversion="1.0"encoding="utf8"?>
<resources>

<stringname="app_name">LocationAPI</string>
<stringname="lbl_you_are_at">YOUAREAT</string>
<stringname="btn_get_location">GETMYLOCATION</string>
<stringname="btn_start_location_updates">STARTLOCATIONUPDATES</string>
<stringname="btn_stop_location_updates">STOPLOCATIONUPDATES</string>

</resources>

5. Open colors.xml located under res values and add below color values. If you dont see colors.xml, create a new file with the name.

colors.xml
<?xmlversion="1.0"encoding="utf8"?>
<resources>

<colorname="view_bg">#b20e0f</color>
<colorname="white">#ffffff</color>
<colorname="btn_bg">#3e4a56</color>

</resources>

6. Open AndroidManifest.xml and add A CC ES S _ F IN E_ L O CA T ION permission. You also need to add below meta-data for google play services version.

<metadata
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version"/>
After doing required changes, your AndroidManifest.xml should look like below.

AndroidManifest.xml
<?xmlversion="1.0"encoding="utf8"?>
<manifestxmlns:android="http://schemas.android.com/apk/res/android"
package="info.androidhive.locationapi"
android:versionCode="1"
android:versionName="1.0">

<usessdk
android:minSdkVersion="8"
android:targetSdkVersion="21"/>

<usespermissionandroid:name="android.permission.ACCESS_FINE_LOCATION"/>

<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<metadata
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version"/>

<activity
android:name="info.androidhive.locationapi.MainActivity"
android:label="@string/app_name"
android:screenOrientation="portrait">
<intentfilter>
<actionandroid:name="android.intent.action.MAIN"/>

<categoryandroid:name="android.intent.category.LAUNCHER"/>
</intentfilter>
</activity>
</application>

</manifest>
http://www.androidhive.info/2015/02/androidlocationapiusinggoogleplayservices/

5/16

6/25/2015

AndroidLocationAPIusingGooglePlayServices

7. Now well quickly create a simple layout for our app. Open the layout file of your main activity (activity_main.xml) and add below code. This layout contains a Tex
(one is to get location and other is to toggle periodic location updates).

activity_main.xml
<LinearLayoutxmlns: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:background="@color/view_bg"
android:gravity="center_horizontal"
android:orientation="vertical">

<ImageView
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_marginTop="60dp"
android:src="@drawable/marker"/>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="25dp"
android:text="@string/lbl_you_are_at"
android:textColor="@color/white"
android:textSize="25dp"
android:textStyle="bold"/>

<TextView
android:id="@+id/lblLocation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:padding="15dp"
android:textColor="@color/white"
android:textSize="16dp"/>

<Button
android:id="@+id/btnShowLocation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:background="@color/btn_bg"
android:paddingLeft="20dp"
android:paddingRight="20dp"
android:text="@string/btn_get_location"
android:textColor="@color/white"/>

<Button
android:id="@+id/btnLocationUpdates"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="60dp"
android:background="@color/btn_bg"
android:paddingLeft="20dp"
android:paddingRight="20dp"
android:text="@string/btn_start_location_updates"
android:textColor="@color/white"/>

</LinearLayout>

8. Now well start adding the code related to location api. Open your main activity MainActivity.java and implement the class from ConnectionCallbacks, OnConn

publicclassMainActivity1extendsActivityimplementsConnectionCallbacks,
OnConnectionFailedListener{

}
In brief, you need to do below changes in your activity to get the users current location.
> First check for availability of Google Play Services by calling checkPlayServices() in onResume()
> Once play services are available on the device, build the Go o g le A piC lie n t by calling buildGoogleApiClient() method.

http://www.androidhive.info/2015/02/androidlocationapiusinggoogleplayservices/

6/16

6/25/2015

AndroidLocationAPIusingGooglePlayServices

> Connect to google api client by calling mGoogleApiClient.connect() in onStart() method. By calling this, onConnectionFailed(), onConnected() and onConnect
upon the connection status.
> Once google api is successfully connected, displayLocation() should be called in onConnected() method to get the current location.
Add the below code to your main activity and run the project. Make sure that the wifi and location is enabled on your device before you test.

MainActivity.java
packageinfo.androidhive.locationapi;

importcom.google.android.gms.common.ConnectionResult;
importcom.google.android.gms.common.GooglePlayServicesUtil;
importcom.google.android.gms.common.api.GoogleApiClient;
importcom.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
importcom.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
importcom.google.android.gms.location.LocationRequest;
importcom.google.android.gms.location.LocationServices;

importandroid.app.Activity;
importandroid.location.Location;
importandroid.os.Bundle;
importandroid.util.Log;
importandroid.view.View;
importandroid.widget.Button;
importandroid.widget.TextView;
importandroid.widget.Toast;

publicclassMainActivity1extendsActivityimplementsConnectionCallbacks,
OnConnectionFailedListener{
//LogCattag
privatestaticfinalStringTAG=MainActivity.class.getSimpleName();

privatefinalstaticintPLAY_SERVICES_RESOLUTION_REQUEST=1000;

privateLocationmLastLocation;

//GoogleclienttointeractwithGoogleAPI
privateGoogleApiClientmGoogleApiClient;

//booleanflagtotoggleperiodiclocationupdates
privatebooleanmRequestingLocationUpdates=false;

privateLocationRequestmLocationRequest;

//Locationupdatesintervalsinsec
privatestaticintUPDATE_INTERVAL=10000;//10sec
privatestaticintFATEST_INTERVAL=5000;//5sec
privatestaticintDISPLACEMENT=10;//10meters

//UIelements
privateTextViewlblLocation;
privateButtonbtnShowLocation,btnStartLocationUpdates;

@Override
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

lblLocation=(TextView)findViewById(R.id.lblLocation);
btnShowLocation=(Button)findViewById(R.id.btnShowLocation);
btnStartLocationUpdates=(Button)findViewById(R.id.btnLocationUpdates);

//Firstweneedtocheckavailabilityofplayservices
if(checkPlayServices()){

//BuildingtheGoogleApiclient
buildGoogleApiClient();
}

//Showlocationbuttonclicklistener
btnShowLocation.setOnClickListener(newView.OnClickListener(){

@Override
publicvoidonClick(Viewv){
displayLocation();
}
});
}

/**
*MethodtodisplaythelocationonUI
**/
http://www.androidhive.info/2015/02/androidlocationapiusinggoogleplayservices/

7/16

6/25/2015

AndroidLocationAPIusingGooglePlayServices

privatevoiddisplayLocation(){

mLastLocation=LocationServices.FusedLocationApi
.getLastLocation(mGoogleApiClient);

if(mLastLocation!=null){
doublelatitude=mLastLocation.getLatitude();
doublelongitude=mLastLocation.getLongitude();

lblLocation.setText(latitude+","+longitude);

}else{

lblLocation
.setText("(Couldn'tgetthelocation.Makesurelocationisenabledonthedevice)");
}
}

/**
*Creatinggoogleapiclientobject
**/
protectedsynchronizedvoidbuildGoogleApiClient(){
mGoogleApiClient=newGoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API).build();
}

/**
*Methodtoverifygoogleplayservicesonthedevice
**/
privatebooleancheckPlayServices(){
intresultCode=GooglePlayServicesUtil
.isGooglePlayServicesAvailable(this);
if(resultCode!=ConnectionResult.SUCCESS){
if(GooglePlayServicesUtil.isUserRecoverableError(resultCode)){
GooglePlayServicesUtil.getErrorDialog(resultCode,this,
PLAY_SERVICES_RESOLUTION_REQUEST).show();
}else{
Toast.makeText(getApplicationContext(),
"Thisdeviceisnotsupported.",Toast.LENGTH_LONG)
.show();
finish();
}
returnfalse;
}
returntrue;
}

@Override
protectedvoidonStart(){
super.onStart();
if(mGoogleApiClient!=null){
mGoogleApiClient.connect();
}
}

@Override
protectedvoidonResume(){
super.onResume();

checkPlayServices();
}

/**
*Googleapicallbackmethods
*/
@Override
publicvoidonConnectionFailed(ConnectionResultresult){
Log.i(TAG,"Connectionfailed:ConnectionResult.getErrorCode()="
+result.getErrorCode());
}

@Override
publicvoidonConnected(Bundlearg0){

//Onceconnectedwithgoogleapi,getthelocation
displayLocation();
}

@Override
publicvoidonConnectionSuspended(intarg0){
mGoogleApiClient.connect();
}
}
http://www.androidhive.info/2015/02/androidlocationapiusinggoogleplayservices/

8/16

6/25/2015

AndroidLocationAPIusingGooglePlayServices

Receiving Location Updates

9. In certain scenarios, your app might needs location updates periodically. Lets say you are building a direction app where user needs to be get updated whenever
request for location updates. Doing the below changes, you will get the new location wherever location is changed.
> Implement the activity from Lo c a t io n L ist e n e r which adds onLocationChanged() method.
> Create L oc a t io n Re qu es t object by calling createLocationRequest() method in onCreate() method upon checking the play services availability.
> Add togglePeriodicLocationUpdates() method which toggles listening to location updates.
> Start the location updates by calling startLocationUpdates() in onConnected() and onResume() methods.
> Stop the location updates by calling stopLocationUpdates() in onStop().

http://www.androidhive.info/2015/02/androidlocationapiusinggoogleplayservices/

9/16

6/25/2015

AndroidLocationAPIusingGooglePlayServices

> startLocationUpdates() and stopLocationUpdates() methods are used to start/stop the location updates.

> onLocationChanged() method will be triggered whenever the location is changed. Calling displayLocation() inside onLocationChanged will display new location d

MainActivity.java
publicclassMainActivityextendsActivityimplementsConnectionCallbacks,
OnConnectionFailedListener,LocationListener{
@Override
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

//Firstweneedtocheckavailabilityofplayservices
if(checkPlayServices()){

createLocationRequest();
}

//Togglingtheperiodiclocationupdates
btnStartLocationUpdates.setOnClickListener(newView.OnClickListener(){

@Override
publicvoidonClick(Viewv){
togglePeriodicLocationUpdates();
}
});

@Override
protectedvoidonResume(){
super.onResume();

//Resumingtheperiodiclocationupdates
if(mGoogleApiClient.isConnected()&&mRequestingLocationUpdates){
startLocationUpdates();
}
}

@Override
protectedvoidonPause(){
super.onPause();
stopLocationUpdates();
}

/**
*Methodtotoggleperiodiclocationupdates
**/
privatevoidtogglePeriodicLocationUpdates(){
if(!mRequestingLocationUpdates){
//Changingthebuttontext
btnStartLocationUpdates
.setText(getString(R.string.btn_stop_location_updates));

mRequestingLocationUpdates=true;

//Startingthelocationupdates
startLocationUpdates();

Log.d(TAG,"Periodiclocationupdatesstarted!");

}else{
//Changingthebuttontext
btnStartLocationUpdates
.setText(getString(R.string.btn_start_location_updates));

mRequestingLocationUpdates=false;

//Stoppingthelocationupdates
stopLocationUpdates();

Log.d(TAG,"Periodiclocationupdatesstopped!");
}
}

/**
*Creatinglocationrequestobject
**/
protectedvoidcreateLocationRequest(){
mLocationRequest=newLocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL);
mLocationRequest.setFastestInterval(FATEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
http://www.androidhive.info/2015/02/androidlocationapiusinggoogleplayservices/

10/16

6/25/2015

AndroidLocationAPIusingGooglePlayServices

mLocationRequest.setSmallestDisplacement(DISPLACEMENT);//10meters
}

/**
*Startingthelocationupdates
**/
protectedvoidstartLocationUpdates(){

LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient,mLocationRequest,this);

/**
*Stoppinglocationupdates
*/
protectedvoidstopLocationUpdates(){
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient,this);
}

@Override
publicvoidonConnected(Bundlearg0){

//Onceconnectedwithgoogleapi,getthelocation
displayLocation();

if(mRequestingLocationUpdates){
startLocationUpdates();
}
}

@Override
publicvoidonLocationChanged(Locationlocation){
//Assignthenewlocation
mLastLocation=location;

Toast.makeText(getApplicationContext(),"Locationchanged!",
Toast.LENGTH_SHORT).show();

//DisplayingthenewlocationonUI
displayLocation();
}

}
After doing all the above changes, run and test the app. If your app is not getting location, follow below steps to debug the app.

http://www.androidhive.info/2015/02/androidlocationapiusinggoogleplayservices/

11/16

6/25/2015

AndroidLocationAPIusingGooglePlayServices

3. Testing the App


Below are the few key points should be kept in mind while testing the app.
> Your device should have internet connection (Wifi or mobile 3G).
> Location service should be enabled. Go to Settings => Location => Turn On.

> When you run the app, if you are not able to get the location even though you have done above two steps, open any of googles location apps (maps) and come ba
UPDATES.

> If you are testing the periodic location updates, go out and take a short walk (few steps). You should see the locationChanged method calling by giving latest locati

Complete Code:
Below is the complete code of MainActivity.java

MainActivity.java
packageinfo.androidhive.locationapi;

importandroid.app.Activity;
importandroid.location.Location;
importandroid.os.Bundle;
importandroid.util.Log;
importandroid.view.View;
http://www.androidhive.info/2015/02/androidlocationapiusinggoogleplayservices/

12/16

6/25/2015

AndroidLocationAPIusingGooglePlayServices

importandroid.widget.Button;
importandroid.widget.TextView;
importandroid.widget.Toast;

importcom.google.android.gms.common.ConnectionResult;
importcom.google.android.gms.common.GooglePlayServicesUtil;
importcom.google.android.gms.common.api.GoogleApiClient;
importcom.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
importcom.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
importcom.google.android.gms.location.LocationListener;
importcom.google.android.gms.location.LocationRequest;
importcom.google.android.gms.location.LocationServices;

publicclassMainActivityextendsActivityimplementsConnectionCallbacks,
OnConnectionFailedListener,LocationListener{

//LogCattag
privatestaticfinalStringTAG=MainActivity.class.getSimpleName();

privatefinalstaticintPLAY_SERVICES_RESOLUTION_REQUEST=1000;

privateLocationmLastLocation;

//GoogleclienttointeractwithGoogleAPI
privateGoogleApiClientmGoogleApiClient;

//booleanflagtotoggleperiodiclocationupdates
privatebooleanmRequestingLocationUpdates=false;

privateLocationRequestmLocationRequest;

//Locationupdatesintervalsinsec
privatestaticintUPDATE_INTERVAL=10000;//10sec
privatestaticintFATEST_INTERVAL=5000;//5sec
privatestaticintDISPLACEMENT=10;//10meters

//UIelements
privateTextViewlblLocation;
privateButtonbtnShowLocation,btnStartLocationUpdates;

@Override
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

lblLocation=(TextView)findViewById(R.id.lblLocation);
btnShowLocation=(Button)findViewById(R.id.btnShowLocation);
btnStartLocationUpdates=(Button)findViewById(R.id.btnLocationUpdates);

//Firstweneedtocheckavailabilityofplayservices
if(checkPlayServices()){

//BuildingtheGoogleApiclient
buildGoogleApiClient();

createLocationRequest();
}

//Showlocationbuttonclicklistener
btnShowLocation.setOnClickListener(newView.OnClickListener(){

@Override
publicvoidonClick(Viewv){
displayLocation();
}
});

//Togglingtheperiodiclocationupdates
btnStartLocationUpdates.setOnClickListener(newView.OnClickListener(){

@Override
publicvoidonClick(Viewv){
togglePeriodicLocationUpdates();
}
});

@Override
protectedvoidonStart(){
super.onStart();
if(mGoogleApiClient!=null){
mGoogleApiClient.connect();
}
}

http://www.androidhive.info/2015/02/androidlocationapiusinggoogleplayservices/

13/16

6/25/2015

AndroidLocationAPIusingGooglePlayServices

@Override
protectedvoidonResume(){
super.onResume();

checkPlayServices();

//Resumingtheperiodiclocationupdates
if(mGoogleApiClient.isConnected()&&mRequestingLocationUpdates){
startLocationUpdates();
}
}

@Override
protectedvoidonStop(){
super.onStop();
if(mGoogleApiClient.isConnected()){
mGoogleApiClient.disconnect();
}
}

@Override
protectedvoidonPause(){
super.onPause();
stopLocationUpdates();
}

/**
*MethodtodisplaythelocationonUI
**/
privatevoiddisplayLocation(){

mLastLocation=LocationServices.FusedLocationApi
.getLastLocation(mGoogleApiClient);

if(mLastLocation!=null){
doublelatitude=mLastLocation.getLatitude();
doublelongitude=mLastLocation.getLongitude();

lblLocation.setText(latitude+","+longitude);

}else{

lblLocation
.setText("(Couldn'tgetthelocation.Makesurelocationisenabledonthedevice)");
}
}

/**
*Methodtotoggleperiodiclocationupdates
**/
privatevoidtogglePeriodicLocationUpdates(){
if(!mRequestingLocationUpdates){
//Changingthebuttontext
btnStartLocationUpdates
.setText(getString(R.string.btn_stop_location_updates));

mRequestingLocationUpdates=true;

//Startingthelocationupdates
startLocationUpdates();

Log.d(TAG,"Periodiclocationupdatesstarted!");

}else{
//Changingthebuttontext
btnStartLocationUpdates
.setText(getString(R.string.btn_start_location_updates));

mRequestingLocationUpdates=false;

//Stoppingthelocationupdates
stopLocationUpdates();

Log.d(TAG,"Periodiclocationupdatesstopped!");
}
}

/**
*Creatinggoogleapiclientobject
**/
protectedsynchronizedvoidbuildGoogleApiClient(){
mGoogleApiClient=newGoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API).build();
}
http://www.androidhive.info/2015/02/androidlocationapiusinggoogleplayservices/

14/16

6/25/2015

AndroidLocationAPIusingGooglePlayServices

/**
*Creatinglocationrequestobject
**/
protectedvoidcreateLocationRequest(){
mLocationRequest=newLocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL);
mLocationRequest.setFastestInterval(FATEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setSmallestDisplacement(DISPLACEMENT);
}

/**
*Methodtoverifygoogleplayservicesonthedevice
**/
privatebooleancheckPlayServices(){
intresultCode=GooglePlayServicesUtil
.isGooglePlayServicesAvailable(this);
if(resultCode!=ConnectionResult.SUCCESS){
if(GooglePlayServicesUtil.isUserRecoverableError(resultCode)){
GooglePlayServicesUtil.getErrorDialog(resultCode,this,
PLAY_SERVICES_RESOLUTION_REQUEST).show();
}else{
Toast.makeText(getApplicationContext(),
"Thisdeviceisnotsupported.",Toast.LENGTH_LONG)
.show();
finish();
}
returnfalse;
}
returntrue;
}

/**
*Startingthelocationupdates
**/
protectedvoidstartLocationUpdates(){

LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient,mLocationRequest,this);

/**
*Stoppinglocationupdates
*/
protectedvoidstopLocationUpdates(){
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient,this);
}

/**
*Googleapicallbackmethods
*/
@Override
publicvoidonConnectionFailed(ConnectionResultresult){
Log.i(TAG,"Connectionfailed:ConnectionResult.getErrorCode()="
+result.getErrorCode());
}

@Override
publicvoidonConnected(Bundlearg0){

//Onceconnectedwithgoogleapi,getthelocation
displayLocation();

if(mRequestingLocationUpdates){
startLocationUpdates();
}
}

@Override
publicvoidonConnectionSuspended(intarg0){
mGoogleApiClient.connect();
}

@Override
publicvoidonLocationChanged(Locationlocation){
//Assignthenewlocation
mLastLocation=location;

Toast.makeText(getApplicationContext(),"Locationchanged!",
Toast.LENGTH_SHORT).show();

//DisplayingthenewlocationonUI
displayLocation();
http://www.androidhive.info/2015/02/androidlocationapiusinggoogleplayservices/

15/16

6/25/2015

AndroidLocationAPIusingGooglePlayServices

http://www.androidhive.info/2015/02/androidlocationapiusinggoogleplayservices/

16/16

Vous aimerez peut-être aussi