Retain markers on screen rotation in Google Maps Android API V2 using Parcelable LatLng points

May 14, 2013
By

In this article, we will develop an Android application which demonstrates how to persist marker points in Google Maps Android API V2 on screen rotation.



On adding a marker in the Google Maps, corresponding coordinates will be added to an ArrayList as LatLng object. Then on screen rotation the array list will be saved to a Bundle object in the callback method “onSaveInstanceState” and the LatLng objects will be retrieved in the callback method “onCreate“.

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 device (Android 2.3.6  -  GingerBread ).



1. Create a new Android application project namely “LocationParcelable”

Create new Android application project namely "LocationParcelable"

Figure 1 : Create new Android application project namely "LocationParcelable"


2. Configure the project

Configure the project

Figure 2 : Configure the project


3. Design application launcher icon

Design application launcher icon

Figure 3 : Design application launcher icon


4. Create a blank activity

Create a blank activity

Figure 4 : Create a blank activity


5. Enter MainActivity details

Enter MainActivity details

Figure 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

Note : Please ensure that, the latest version of Google Play Service Library is installed


7. Add Google Play Services Library to this project

Adding Google Play Service library to this project

Figure 6 : Adding Google Play Service 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

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="wrap_content"
        android:layout_height="wrap_content" />

</RelativeLayout>


11. Update the class “MainActivity” in the file src/in/wptrafficanalyzer/locationparcelable/MainActivity.java


package in.wptrafficanalyzer.locationparcelable;

import java.util.ArrayList;

import android.app.Dialog;
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.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnMapClickListener;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

public class MainActivity extends FragmentActivity {

    GoogleMap mGoogleMap;

    ArrayList<LatLng> pointList = new ArrayList<LatLng>();

    @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
            mGoogleMap = fm.getMap();

            // Enabling MyLocation Layer of Google Map
            mGoogleMap.setMyLocationEnabled(true);

            mGoogleMap.setOnMapClickListener(new OnMapClickListener(){

                @Override
                public void onMapClick(LatLng point) {

                    // Drawing the currently touched marker on the map
                    drawMarker(point);

                    // Adding the currently created marker position to the arraylist
                    pointList.add(point);

                    Toast.makeText(getBaseContext(), "Marker is added to the Map", Toast.LENGTH_SHORT).show();
                }
            });

            // Restoring the markers on configuration changes
            if(savedInstanceState!=null){
                if(savedInstanceState.containsKey("points")){
                    pointList = savedInstanceState.getParcelableArrayList("points");
                    if(pointList!=null){
                        for(int i=0;i<pointList.size();i++){
                            drawMarker(pointList.get(i));
                        }
                    }
                }
            }
        }
    }

    // Draw a marker at the "point"
    private void drawMarker(LatLng point){
        // Creating an instance of MarkerOptions
        MarkerOptions markerOptions = new MarkerOptions();

        // Setting latitude and longitude for the marker
        markerOptions.position(point);

        // Setting a title for this marker
        markerOptions.title("Lat:"+point.latitude+","+"Lng:"+point.longitude);

        // Adding marker on the Google Map
        mGoogleMap.addMarker(markerOptions);
    }

    // A callback method, which is invoked on configuration is changed
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        // Adding the pointList arraylist to Bundle
        outState.putParcelableArrayList("points", pointList);

        // Saving the bundle
        super.onSaveInstanceState(outState);
    }

    @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;
    }
}


12. 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.locationparcelable"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />

    <permission
        android:name="in.wptrafficanalyzer.locationparcelable.permission.MAPS_RECEIVE"
        android:protectionLevel="signature"/>

    <uses-permission android:name="in.wptrafficanalyzer.locationparcelable.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.locationparcelable.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>

        <meta-data
            android:name="com.google.android.maps.v2.API_KEY"
            android:value="YOUR_ANDROID_API_KEY" />

    </application>

</manifest>

Note : Please update “YOUR_ANDROID_API_KEY” (at line 44)with the Android api key obtained in Step 8


13. Screenshots of the application

Google Maps Android API V2 with Markers

Figure 7 : Google Maps Android API V2 with Markers

Markers are restored after the screen rotation

Figure 8 : Markers are restored after the screen rotation


14. Download Source Code


How to hire me?

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


Android Knowledge Quiz

Ready to test your knowledge in Android? Take this quiz :



Tags: , , , , ,

6 Responses to Retain markers on screen rotation in Google Maps Android API V2 using Parcelable LatLng points

  1. ameni on May 16, 2013 at 12:05 am

    Thank you soo soo much u saved my life !!!!

  2. AlexZhou on July 10, 2013 at 8:47 am

    thanks a lot for your share!There is a good website!

  3. adeel suleman on September 6, 2014 at 4:19 pm

    sir! needs some help about google map !

    if there is two markers in google map and i wants to rotate the direction of 1st marker towards 2nd marker , how this can be done

    give me hint for doing that ??

  4. Avinash on June 26, 2015 at 12:12 pm

    Sir,
    Im having 50000 lat and lng.Since my application runs in background for a long time ,activiy and fragment will be destroyed.In that case i am unable to reterive the markers and polyline i have already drawn .Since im dealing with huge data my application throws anr.

    Is there any alternative way to handle big set of data in android?
    please help

  5. Iznatoraf on July 22, 2015 at 6:27 pm

    There is an easier way to achieve this. Just call setRetainInstance(true) on your SupportMapFragment or your MapFragment and this fragment will not be destroyed on configuration changes. You don’t need to save your markers to a Bundle.

  6. grafix on January 4, 2016 at 7:33 pm

    hello sir, how to save map state when i change the orientation using share preference? i got a hard time in looking some solution. i new in android programming. i can share to you the code to check what is wrong with it.

Leave a Reply to Avinash Cancel reply

Your email address will not be published. Required fields are marked *

Be friend at g+

Subscribe for Lastest Updates

FBFPowered by ®Google Feedburner