In this article, we will develop an Android application that stores user touched locations of Google Maps in a remote MySQL server. Since this application is developed using SupportMapFragment, it can support Android API version 8 and above.
In order to send latitude and longitude from the application to the web server, we are using HTTPUrlConnection api in “POST” request method.
Screenshot of this application is available towards the end of this article.
This application is developed in Eclipse ( 4.2.0 ) with Android SDK ( 22.2.1 ) and ADT plugin ( 22.2.1 ) and is tested in Android API Level 2.3.6 and 4.1.2.
1. Create new Android application with the given below details
Application Name : LocationMarkerMySQL
Project Name : LocationMarkerMySQL
Package Name : in.wptrafficanalyzer.locationmarkermysql
Minimum Required SDK : API 8: Android 2.2 ( Froyo )
Target SDK : API 18: Android 4.3
Compile With: API 18: Android 4.3
Theme : Holo Light with Dark Action Bar
2. Download and configure Google Play Services Library in Eclipse
Please follow the given below link to setup Google Play Service library in Eclipse.
http://developer.android.com/google/play-services/setup.html
3. Referencing the Google Play Services library in this project
Please follow the given below link to reference the Google Play Service library into this project
http://developer.android.com/tools/projects/projects-eclipse.html#ReferencingLibraryProject
4. 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
5. Add Android Support Library ( V4 ) 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 “
6. Update the 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" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" ools:context=".MainActivity" > <fragment android:id="@+id/map" android:layout_width="fill_parent" android:layout_height="fill_parent" class="com.google.android.gms.maps.SupportMapFragment" /> </RelativeLayout>
7. Create a parser class namely MarkerJSONParser in the file src/in/wptrafficanalyzer/locationmarkermysql/MarkerJSONParser.java
package in.wptrafficanalyzer.locationmarkermysql; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; public class MarkerJSONParser { /** Receives a JSONObject and returns a list */ public List<HashMap<String,String>> parse(JSONObject jObject){ JSONArray jMarkers = null; try { /** Retrieves all the elements in the 'markers' array */ jMarkers = jObject.getJSONArray("markers"); } catch (JSONException e) { e.printStackTrace(); } /** Invoking getMarkers with the array of json object * where each json object represent a marker */ return getMarkers(jMarkers); } private List<HashMap<String, String>> getMarkers(JSONArray jMarkers){ int markersCount = jMarkers.length(); List<HashMap<String, String>> markersList = new ArrayList<HashMap<String,String>>(); HashMap<String, String> marker = null; /** Taking each marker, parses and adds to list object */ for(int i=0; i<markersCount;i++){ try { /** Call getMarker with marker JSON object to parse the marker */ marker = getMarker((JSONObject)jMarkers.get(i)); markersList.add(marker); }catch (JSONException e){ e.printStackTrace(); } } return markersList; } /** Parsing the Marker JSON object */ private HashMap<String, String> getMarker(JSONObject jMarker){ HashMap<String, String> marker = new HashMap<String, String>(); String lat = "-NA-"; String lng ="-NA-"; try { // Extracting latitude, if available if(!jMarker.isNull("lat")){ lat = jMarker.getString("lat"); } // Extracting longitude, if available if(!jMarker.isNull("lng")){ lng = jMarker.getString("lng"); } marker.put("lat", lat); marker.put("lng", lng); } catch (JSONException e) { e.printStackTrace(); } return marker; } }
8. Update the class “MainActivity” in the file src/in/wptrafficanalyzer/locationmarkermysql/MainActivity.java
package in.wptrafficanalyzer.locationmarkermysql; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.util.HashMap; import java.util.List; import org.json.JSONException; import org.json.JSONObject; import android.os.AsyncTask; import android.os.Bundle; import android.support.v4.app.FragmentActivity; import android.view.Menu; 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; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Getting reference to SupportMapFragment SupportMapFragment fragment = (SupportMapFragment) getSupportFragmentManager() .findFragmentById(R.id.map); // Creating GoogleMap from SupportMapFragment mGoogleMap = fragment.getMap(); // Enabling MyLocation button for the Google Map mGoogleMap.setMyLocationEnabled(true); // Setting OnClickEvent listener for the GoogleMap mGoogleMap.setOnMapClickListener(new OnMapClickListener() { @Override public void onMapClick(LatLng latlng) { addMarker(latlng); sendToServer(latlng); } }); // Starting locations retrieve task new RetrieveTask().execute(); } // Adding marker on the GoogleMaps private void addMarker(LatLng latlng) { MarkerOptions markerOptions = new MarkerOptions(); markerOptions.position(latlng); markerOptions.title(latlng.latitude + "," + latlng.longitude); mGoogleMap.addMarker(markerOptions); } // Invoking background thread to store the touched location in Remove MySQL server private void sendToServer(LatLng latlng) { new SaveTask().execute(latlng); } // Background thread to save the location in remove MySQL server private class SaveTask extends AsyncTask<LatLng, Void, Void> { @Override protected Void doInBackground(LatLng... params) { String lat = Double.toString(params[0].latitude); String lng = Double.toString(params[0].longitude); String strUrl = "http://192.168.1.3/location_marker_mysql/save.php"; URL url = null; try { url = new URL(strUrl); HttpURLConnection connection = (HttpURLConnection) url .openConnection(); connection.setRequestMethod("POST"); connection.setDoOutput(true); OutputStreamWriter outputStreamWriter = new OutputStreamWriter( connection.getOutputStream()); outputStreamWriter.write("lat=" + lat + "&lng="+lng); outputStreamWriter.flush(); outputStreamWriter.close(); InputStream iStream = connection.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(iStream)); StringBuffer sb = new StringBuffer(); String line = ""; while( (line = reader.readLine()) != null){ sb.append(line); } reader.close(); iStream.close(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } } // Background task to retrieve locations from remote mysql server private class RetrieveTask extends AsyncTask<Void, Void, String>{ @Override protected String doInBackground(Void... params) { String strUrl = "http://192.168.1.3/location_marker_mysql/retrieve.php"; URL url = null; StringBuffer sb = new StringBuffer(); try { url = new URL(strUrl); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.connect(); InputStream iStream = connection.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(iStream)); String line = ""; while( (line = reader.readLine()) != null){ sb.append(line); } reader.close(); iStream.close(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return sb.toString(); } @Override protected void onPostExecute(String result) { super.onPostExecute(result); new ParserTask().execute(result); } } // Background thread to parse the JSON data retrieved from MySQL server private class ParserTask extends AsyncTask<String, Void, List<HashMap<String, String>>>{ @Override protected List<HashMap<String,String>> doInBackground(String... params) { MarkerJSONParser markerParser = new MarkerJSONParser(); JSONObject json = null; try { json = new JSONObject(params[0]); } catch (JSONException e) { e.printStackTrace(); } List<HashMap<String, String>> markersList = markerParser.parse(json); return markersList; } @Override protected void onPostExecute(List<HashMap<String, String>> result) { for(int i=0; i<result.size();i++){ HashMap<String, String> marker = result.get(i); LatLng latlng = new LatLng(Double.parseDouble(marker.get("lat")), Double.parseDouble(marker.get("lng"))); addMarker(latlng); } } } @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; } }
9. 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.locationmarkermysql" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="18" /> <!-- Protect the map component of the application using application signature --> <permission android:name="in.wptrafficanalyzer.locationmarkermysql.permission.MAPS_RECEIVE" android:protectionLevel="signature" /> <!-- Allows to receive map --> <uses-permission android:name="in.wptrafficanalyzer.locationmarkermysql.permission.MAPS_RECEIVE" /> <!-- Used by the Google Maps Android API V2 to download map tiles from Google Maps servers --> <uses-permission android:name="android.permission.INTERNET" /> <!-- Allows the Google Maps Android API V2 to cache map tile data in the device's external storage area --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- Allows the Google Maps Android API V2 to use WiFi or mobile cell data (or both) to determine the device's location --> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <!-- Allows the Google Maps Android API V2 to use the Global Positioning System (GPS) to determine the device's location to within a very small area --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- Allows to contact Google Serves --> <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" /> <!-- Google Maps Android API V2 requires OpenGL ES version 2 --> <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.locationmarkermysql.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> <!-- Specifies the Android API Key, which is obtained from Google API Console --> <meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="YOUR_ANDROID_API_KEY" /> </application> </manifest>
10. Screenshot of the application
11. Source code of the php script file used in this demo application to store and retrieve locations from MySQL server

12. Source code of this Android Application


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
Nice tutorials i like it…..Can you please do some .net webservices calling in android. thanks
Hello, How I can repeat AsyncTask to update the marker created manually in the database? thank you.
Really this was very helpful and thank you very much.
I have a question that I want to change the “title” and “snippet” of the marker other than the latitude and longitude.
any answer replay me on my email.
please follow the answer me,about how change the tittle.
thanks you
Hello, very nice tuto but I have this error on my log cat :
02-01 11:59:08.611: E/AndroidRuntime(13615): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.myapp/com.example.myapp.HappyMap}: android.view.InflateException: Binary XML file line #11: Error inflating class fragment
AndroidRuntime(13615): java.lang.RuntimeException: Unable to start activity ComponentInfo
can you help tutorial google play services import for android API 19 4.4?
hello, first thanks for your tutorial.
it works on my device, but it only show the map with the blue dot that show my current position.
i inserted data to database, i run the retrieve.php on browser and it works, it show data. but on my device, it didn’t show any marker at all. i change the URL also, but still didn’t show.
can you help me? thanks before
nice tutorial but i want to get current location and send it to server by pressing button not by adding marker like in this good tutorials u mention please give me any idea to do this…….
Sir really your tutorail is good for bigginer as well as for advance android programmin learning
………………THANKS…………………….
How to put data(lat & lng) from android to google datastore via PHP
Plz help me
can you help me?? this application forse closed
)
thanks before master
Hi sir,
How are you & your family?I am ashwin. i already spoke to you regarding USB camera.but i have a small doubt in grid view.
that is,
i want to get the position of the item in multiple selection using grid view.
Actually i use “getselectedItemPostion” method but its not working.
so i need a sample app for gridview with multipleselection and also while clicking item,just display the item positon of the selected item.
if it is possible send it to me sir.
thank you …
thats a cool coding…. this important to my study…. tq alot master….
i try and this running well
once more… tq alot master
Hi, this is a great tutorial and so helpful, but i would like display the name of the place instead of the lat and lng.. how do i do that help me out.. THANKS
can you help me?? this application forse closed
)
thanks before master
how could give the market a different title , I can bring it by post to the database
I was trying to do the same thing, you were able to do that?? Please, e-mail-me.
I am trying to do the same, how could you give me the market a different title? Thanks for your help!
Hi! Check out this forum: stackoverflow.com/a/29725056/3304275
GREAT TUTORIAL!!! Thank you ever so much for sharing.
I just wanted to know how to put names instead of latitude and longitude, I mean, if I want to put a new marker, should appears the name like: “Church”.
Thank in advanced
Code is working fine but not storing & retrieving values to/from mySql
Hi George, could you please help me if i want to show infowindow showing the address and phone number retrieved from mysql database?Your help are really appreciated!
I was really really helpful, Thank you very much from Paraguay.
PLEASE CAN ANY ONE TELL ME HOW TO DISPLAY DYNAMIC LATITUDE AND LONGITUDE FROM MYSQL DATABASE TO GOOGLE MAP ON SERVER SIDE ON PHP…