In this post i will write down how to make use of the google map place api in xamarin android. Before proceeding here go through with Google map integration have written in steps about google map integration.
In Brief: As and when user enter the character, fetch the matching location with that character from the google server.
Step 1)Register in google developer console.
1.1) Login to http://console.developers.google.com
In "APIs & auth" menu select APIs option. From Google Maps APIs enable "Google Places API Web Service"
Enable that API
1.2)Again from "APIs & auth" select "Credential". From "Public API access" select "Create new key"
->Browser key. Leave referer space blank, select "Create".
Step 2.) Create a new project with AutocompleteTextview in layout.
Now on textchange of Autocompletetextview make a webservice request to google server along with input charecter and api key.
https://maps.googleapis.com/maps/api/place/autocomplete/json?input=character&key=API_KEY
here i took only two query string options input and key. you can find out more option from the Google developer place api document.
-> Download the JSON string from the webservice[How to do REST request and JSON response processing].
-> Parse downloaded JSON string to Class "GoogleMapPlaceClass"
you will get the number of online tool to get class from json.
-> Bind the "Prediction" class attribute "description" to Adapter of Autocomplete textview.
This is what i done in the below code,
using System; using Android.App; using Android.Content; using Android.Runtime; using Android.Views; using Android.Widget; using Android.OS; using Android.Gms.Maps; using Android.Gms.Maps.Model; using System.Threading.Tasks; using Newtonsoft.Json; using System.Net; using Android.Views.InputMethods; using System.Text; //enter you google map key in manifestfile namespace GoogleMapPlaceAPI { [Activity ( Label = "GoogleMapPlaceAPI" , MainLauncher = true , Icon = "@drawable/icon" )] public class MainActivity : Activity { const string strAutoCompleteGoogleApi="https://maps.googleapis.com/maps/api/place/autocomplete/json?input="; //browser key for place webservice const string strGoogleApiKey="*****yCaRfEwrLeUvdADPn_R9WQ_WrP3jB*****"; const string strGeoCodingUrl="https://maps.googleapis.com/maps/api/geocode/json"; AutoCompleteTextView txtSearch; MapFragment mapFrag; GoogleMap map; ArrayAdapter adapter=null; GoogleMapPlaceClass objMapClass; GeoCodeJSONClass objGeoCodeJSONClass; string autoCompleteOptions; string[] strPredictiveText; int index = 0; protected override void OnCreate (Bundle savedInstanceState) { base.OnCreate (savedInstanceState); SetContentView ( Resource.Layout.Main ); //Each Tag <,> enclosed with single quote to avoid HTML interpretation,Pl aviod it txtSearch = FindViewById'<'autocompletetextview'>'( Resource.Id.txtTextSearch ); txtSearch.ItemClick += AutoCompleteOption_Click; txtSearch.Hint = "Enter source "; mapFrag = (MapFragment) FragmentManager.FindFragmentById(Resource.Id.map); map = mapFrag.Map; map.MapType = GoogleMap.MapTypeNormal; map.MyLocationEnabled = true; txtSearch.TextChanged += async delegate(object sender, Android.Text.TextChangedEventArgs e) { try { autoCompleteOptions=await fnDownloadString(strAutoCompleteGoogleApi+txtSearch.Text+"&key="+strGoogleApiKey); if ( autoCompleteOptions == "Exception" ) { Toast.MakeText ( this , "Unable to connect to server!!!" , ToastLength.Short ).Show (); return; } objMapClass = JsonConvert.DeserializeObject'<'googlemapplaceclass'>' (autoCompleteOptions); strPredictiveText= new string[objMapClass.predictions.Count]; index = 0; foreach(Prediction objPred in objMapClass.predictions) { strPredictiveText[index] = objPred.description; index++; } adapter = new ArrayAdapter'<'string'>' ( this ,Android.Resource.Layout.SimpleDropDownItem1Line, strPredictiveText ); txtSearch.Adapter = adapter; } catch { Toast.MakeText ( this , "Unable to process at this moment!!!" , ToastLength.Short ).Show (); } }; } async void AutoCompleteOption_Click(object sender,AdapterView.ItemClickEventArgs e) { //to soft keyboard hide InputMethodManager inputManager = (InputMethodManager)this.GetSystemService (Context.InputMethodService); inputManager.HideSoftInputFromWindow (txtSearch.WindowToken, HideSoftInputFlags.NotAlways); map.Clear (); if(txtSearch.Text!=string.Empty) { var sb = new StringBuilder(); sb.Append(strGeoCodingUrl); sb.Append("?address=").Append(txtSearch.Text); string strResult=await fnDownloadString(sb.ToString()); if ( strResult == "Exception" ) { Toast.MakeText ( this , "Unable to connect to server!!!" , ToastLength.Short ).Show (); } //below used single quote to avoid html interpretation objGeoCodeJSONClass= JsonConvert.DeserializeObject'<'geocodejsonclass'>' (strResult); LatLng Position=new LatLng(objGeoCodeJSONClass.results[0].geometry.location.lat,objGeoCodeJSONClass.results[0].geometry.location.lng); updateCameraPosition (Position); MarkOnMap("MyLocation",Position); } } void MarkOnMap(string title,LatLng pos ) { RunOnUiThread ( () => { var marker = new MarkerOptions (); marker.SetTitle ( title ); marker.SetPosition ( pos ); map.AddMarker ( marker ); } ); } void updateCameraPosition(LatLng pos) { CameraPosition.Builder builder = CameraPosition.InvokeBuilder(); builder.Target(pos); builder.Zoom(14); builder.Bearing(45); builder.Tilt(90); CameraPosition cameraPosition = builder.Build(); CameraUpdate cameraUpdate = CameraUpdateFactory.NewCameraPosition(cameraPosition); map.AnimateCamera(cameraUpdate); } async TaskfnDownloadString(string strUri) { WebClient webclient = new WebClient (); string strResultData; try { strResultData= await webclient.DownloadStringTaskAsync (new Uri(strUri)); Console.WriteLine(strResultData); } catch { strResultData = "Exception"; RunOnUiThread ( () => { Toast.MakeText ( this , "Unable to connect to server!!!" , ToastLength.Short ).Show (); } ); } finally { webclient.Dispose (); webclient = null; } return strResultData; } } }
Layout file
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:orientation="vertical">
<autocompletetextview
android:hint="Enter Location"
android:id="@+id/txtTextSearch"
android:imeactionid="@+id/imeisearch"
android:imeoptions="actionSearch"
android:inputtype="text"
android:layout_height="wrap_content"
android:layout_marginleft="5dp"
android:layout_marginright="5dp"
android:layout_width="match_parent"/>
<fragment android:id="@+id/map"
android:layout_below="@+id/first"
android:layout_height="match_parent"
android:layout_width="match_parent"
class="com.google.android.gms.maps.MapFragment"/>
</linearlayout>
On selection of autocompletetextview option i have marked that location in google map. [How to mark on the google map].
On autocompletetextview ItemClick event is used to display the map.
Result Screen:
Result Screen:
Sir when i write in main.xml it gives an error that Linear Layout has invalid child element fragmemnt.
ReplyDeletecan u plz help me with this i have been stuck on this for a really long time
Install Map Services package, then work on it
DeleteI think you should update this content, since the API are getting update last year for android one version. Please kindly check.
ReplyDelete