Google Maps Custom Info Window

The Google Maps API is one of the most imperative components of any android project. Any app developed for an official or authentic purpose, such as that of a bureau or a firm oblige to utilize a google map API to locate their address and whereabouts.

Previously, embedding a Maps activity in an android project was a bit complex procedure. But with Google introducing Google Maps Android API v2 incorporating inbuilt libraries and dependencies, the task has got much smoother and effortless.

In this context, I created a simple project that displays on the map the town I live in – Rajkot, with a customized marker and its info window.

I developed the custom info window using an XML layout and configured it in my java class.The step-wise procedure to create the project is as follows –

  1. Create a new project in Android Studio: Specify an appropriate title for the project, e.g. MapCustomInfo and select “Google Maps Activity”. This would automatically import the following library/ dependency in its gradle file or download it if it’s not available.
    compile 'com.google.android.gms:play-services:9.6.1'

     

  2. Take permission in the Manifest: We see that permission to Access_Fine_Location is already granted. Add the following two permissions also –
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
     
  3. Generate an API key for the project in Google API Console: This is a very important segment, as we want to utilize Google Map’s API services, we need to register the project and generate a key. To do so, follow the steps below –
    • Go to the following link and log in with your google account-

https://accounts.google.com/ServiceLogin?service=cloudconsole&ltmpl=api&osid=1&passive=true&continue=https://console.developers.google.com/

  • Click Create Project, give a specific project name and then Enable API.From the List of Google Maps API, choose Google Maps Android API and then enable it if it’s disabled.

  • Go to the Credentials tab –>choose to Create Credentials–> API key.You will get an API key created a dialog box with a specific key. Choose Restrict Key option.

  • In the key restriction, choose Android apps radio button and click save. Copy the key and save it for future use.

  • You can also Add Package name and SHA-key to this project which would restrict this API key only for that project. But if you are not providing any such type of restrictions, then you can use this key in any number of projects you like.

  • To obtain the SHA key, go to your project’s google_maps_api.XML file and view the 4th comment line from above. The variables separated by: is your SHA key. This is auto-generated as we create the project.

  1. Paste the API key in the project: Go to your project’s google_maps_api.xml fiXMLand paste the API key in place of YOUR_KEY_HERE.
  2. View and modify the auto-generated code in MapsActivity.java class:  As you see, there are auto-generated codes in MapsActivity.java class. Leave everything as it is, only deletes the codes from onMapReady( ) method.
  3. Create a new xml file named custom_info_window.xml to define the custom window layout: My info window is simple with just an imageview and 2 textviews as title and snippet respectively.
    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <LinearLayout
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_alignParentStart="true"
    android:background="#bff5ed">
    
    <ImageView
    android:layout_width="70dp"
    android:layout_height="70dp"
    android:id="@+id/imageView"
    android:src="@drawable/pic" />
    
    <LinearLayout
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="Rajkot"
    android:id="@+id/textView"
    android:layout_weight="1"
    android:paddingLeft="15dp"
    android:paddingTop="7dp"
    android:textAlignment="center"
    android:textColor="#621616"
    android:textSize="15dp"
    android:textStyle="bold" />
    
    <TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="The most religious city one can wonder about...!"
    android:id="@+id/textView2"
    android:layout_weight="1"
    android:paddingLeft="15dp"
    android:paddingTop="7dp"
    android:textColor="#0e3c0b"
    android:typeface="serif"
    android:textAlignment="center" />
    </LinearLayout>
    </LinearLayout>
    </RelativeLayout>
    
    My info window is simple with just an imageview and 2 textviews as title and snippet respectively.
  4. Code in MapsActivity.java class as follows-
package com.mapinfocustom;

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.View;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, GoogleMap.InfoWindowAdapter 
{
  private GoogleMap mMap;
  private static final LatLng Rajkot = new LatLng(22.3039, 70.8022);
  private Marker mRajkot;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_maps);
  //Obtain the SupportMapFragment and get notified when the map is ready to be used.
  SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                                   .findFragmentById(R.id.map);
  mapFragment.getMapAsync(this);
}

@Override
public void onMapReady(GoogleMap googleMap) {
  mMap = googleMap;
  mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
  mRajkot = mMap.addMarker(new MarkerOptions()
            .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA)));  //sets color
           //.icon(BitmapDescriptorFactory.fromResource(R.drawable.arr)));                        
//sets an icon from drawable as marker
  mRajkot.setTag(0);
  mRajkot.showInfoWindow();                            
//the info window is visible above marker as soon as project runs
 mMap.moveCamera(CameraUpdateFactory.newLatLng(Rajkot));     
//moves camera to this latlang
 mMap.animateCamera(CameraUpdateFactory.zoomTo(4), 1, null);  
 // zooms map to this location by 4, 2nd arg is any int value
  mMap.setInfoWindowAdapter(this);
 }

 @Override
 public View getInfoWindow(Marker marker) {
   return null;
 }

 @Override
  public View getInfoContents(Marker marker) {
  return prepareInfoView(marker);
  }

 private View prepareInfoView(Marker marker)
 {
   View infoView;
   infoView = getLayoutInflater().inflate(R.layout.custom_info_window, null);
   return infoView;
  }
}

Now run the project on a real device and view your favorite location with as much customization as you urge. The final output of the app is as follows –

Let's Think together, Say Something !