20 Oct 2015

Data Binding in Android Marshmallow 6.0

Hello Friends,

There are lots of exiting library come up with new android feature.
One of the new API that caught my eye is the Data Binding Library. In short, it lets you bind data directly into your layouts by having a POJO - variable declaration pair.

Key features:

  • The Data Binding Library offers both flexibility and broad compatibility — it's a support library, so you can use it with all Android platform versions back to Android 2.1 (API level 7+).
  • So far so good, nothing really complicated or hard to comprehend. In a way, this removes a bit of boilerplate code (not having to findViewById() or setText()). My first impression was that this is the aim of this API.

Build Environment :


1) The Data Binding plugin requires Android Plugin for Gradle 1.3.0-beta4 or higher, so update your build dependencies (in the top-level build.gradle file) as needed.

2) Make sure you are using a compatible version of Android Studio. Android Studio 1.3 adds the code-completion and layout-preview support for data binding.

Setting Up Work Environment:

Step 1 :
To set up your application to use data binding, add data binding to the class path of your top-level       build.gradle file, right below "android".

dependencies {
    classpath 'com.android.tools.build:gradle:1.3.0'
    classpath "com.android.databinding:dataBinder:1.0-rc1"
}
Then make sure jcenter is in the repositories list for your projects in the top-level build.gradle file.

Step 2 :
In each module you want to use data binding, apply the plugin right after android plugin

apply plugin: 'com.android.application'
apply plugin: 'com.android.databinding'


Let's take the example  to understand better :


User.java :

public class User {
    public final String firstName;
    public final String lastName;
    public User(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
}

In the layout in which we want to display the user's first and last name. With Data Binding we can directly reference the user's fields in the layout

activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android = "http://schemas.android.com/apk/res/android">
    <data>
        <variable name = "user" type = "com.testapp.User"/>        
    </data>

    <LinearLayout
        android:layout_width = "match_parent"
        android:layout_height = "match_parent"
        android:orientation = "vertical" >

        <TextView android:textColor="@android:color/black"
            android:layout_width = "wrap_content"
            android:layout_height = "wrap_content"
            android:text = "@{user.firstName}"/>

        <TextView
            android:textColor="@android:color/black"
            android:layout_width = "wrap_content"
            android:layout_height = "wrap_content"
            android:text = "@{user.lastName}"/>   
    </LinearLayout>
</layout>

MainActivity.java :

A binding class will be generated based on the name of the layout file (in this case ActivityMainBinding) which you can use in your activity to actually tell the layout which user object to use

 ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);

 user user=new user("Hello"," World !!!");
 binding.setUser(user);

*****Binding Events*****

Events may be bound to handler methods directly, similar to the way android:onClick can be assigned to a method in the Activity.

Step 1: Create MyHandlers.java class 
You can add method to perform action on button click same what we did before like onClickListner

public class MyHandlers
{
    public void onClickButton(View view)
    {
        Toast.makeText(view.getContext(),"Button press",Toast.LENGTH_SHORT).show();
        Log.i(MyHandlers.class.getSimpleName(), "Button press...");
    }
}

Step 2 : Modify activity_main.xml
- Add one more variable inside the <data> tag Eg.
<variable name = "clickHandler" type = "com.testapp.MyHandlers"/> 

 Add button inside the xml file , bind the button with its click even like as below

<Button
    android:layout_width = "wrap_content"
    android:layout_height = "wrap_content"
    android:text = "New Button"
    android:id = "@+id/button"
    android:onClick="@{clickHandler.onClickButton}"/>
We can perform many action using Bind data feature. Please refer following links
Data binding Operation 

I will be happy if you will provide your feedback or follow this blog. Any suggestion and help will be appreciated.
Thank you :)

6 Aug 2015

JSON Parsing Using Gson | gson example Android

JSON is a very common format used in API responses. JSON is very light weight, structured, easy to parse and much human readable. JSON is best alternative to XML when your android app needs to interchange data with your server.

This tutorial will cover how to fetch and parse JSON from a remote server on Android. We will use GSON, a JSON parsing library developed by Google, to quickly parse the JSON into Java objects with very minimal work required.

Gson overview:

Gson is a Java library that can be used to convert Java Objects into their JSON representation. It can also be used to convert a JSON string to an equivalent Java object. Gson is an open-source project hosted at http://code.google.com/p/google-gson.

For more detail, visit Gson User guide

Let’s get started by downloading latest version of Gson .jar & add libs in your project.

Create two classes, SubjectBean and TopicBean. These will be our entity classes that model the data retrieved by the REST calls.You will notice that some fields have the @SerializedName("") annotation. This denotes that the property name does not match the field name in our JSON. If both names do match, there is no need for the annotation.



Steps 1: Create class SubjectBean
import com.google.gson.annotations.SerializedName;

import java.util.ArrayList;

public class SubjectBean
{
    @SerializedName("subject")
    private String subject;

    @SerializedName("price")
    private String price;

    @SerializedName("auther")
    private String auther;

    @SerializedName("topics")
    private ArrayList<TopicBean> beanTopics;

    public String getSubject() {
        return subject;
    }

    public void setSubject(String subject) {

        this.subject = subject;

    }

    public String getPrice() {

        return price;

    }

    public void setPrice(String price) {

        this.price = price;

    }

    public String getAuther() {

        return auther;

    }

    public void setAuther(String auther) {

        this.auther = auther;

    }

    public ArrayList<TopicBean> getBeanTopics() {

        return beanTopics;

    }

    public void setBeanTopics(ArrayList<TopicBean> beanTopics) {

        this.beanTopics = beanTopics;

    }

}

Steps 2: Create class TopicBean

 import com.google.gson.annotations.SerializedName;

public class TopicBean {


    @SerializedName("title")

    private String title;


    public TopicBean(String title) {

        this.title = title;
    }

    public String getTitle() {

        return title;

    }
    public void setTitle(String title) {

        this.title = title;

    }
}

Steps 3: Create class ServiceHandler
 import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.impl.client.DefaultHttpClient;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.List;

public class ServiceHandler {

    public final static int GET = 1;
    public final static int POST = 2;

    static InputStreamReader inputStreamReader = null;

    public ServiceHandler() {}

    /**
     * Making service call
     *
     * @url - url to make request
     * @method - http request method
     * @params - http request params
     */
    public static  InputStreamReader makeServiceCall(String url, int method,List<NameValuePair> params)
    {
        try
        {
            // http client
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpEntity httpEntity = null;
            HttpResponse httpResponse = null;

            if (method == POST)
            {
                HttpPost httpPost = new HttpPost(url);
                if (params != null)
                {
                    httpPost.setEntity(new UrlEncodedFormEntity(params));
                }

                try
                {
                    httpResponse = httpClient.execute(httpPost);
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
            else if (method == GET)
            {
                if (params != null)
                {
                    String paramString = URLEncodedUtils.format(params, "utf-8");
                    url += "?" + paramString;
                }
                HttpGet httpGet = new HttpGet(url);

                httpResponse = httpClient.execute(httpGet);

            }
            StatusLine statusLine = httpResponse.getStatusLine();
            if (statusLine.getStatusCode() == 200)
            {
                HttpEntity entity = httpResponse.getEntity();
                InputStream content = entity.getContent();
                inputStreamReader = new InputStreamReader(content);
            }
        }
        catch (UnsupportedEncodingException e)
        {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return inputStreamReader;
    }
}
Steps 4: Create class MainActivity
  import android.app.ProgressDialog;

import android.os.AsyncTask;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.util.Log;

import android.widget.TextView;

import com.google.gson.GsonBuilder;

import java.io.Reader;

import java.util.ArrayList;



public class MainActivity extends AppCompatActivity
{

    private ProgressDialog progressDialog;

    private SubjectBean beanSubject;

    private ArrayList<TopicBean> topicArrayList =new ArrayList<>();

    private TextView txtSubject,txtPrice,txtAuther,txtTopicsList;



    @Override

    protected void onCreate(Bundle savedInstanceState)
    {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);



        txtSubject= (TextView) findViewById(R.id.txtSubject);

        txtPrice= (TextView) findViewById(R.id.txtPrice);

        txtAuther= (TextView) findViewById(R.id.txtAuther);

        txtTopicsList= (TextView) findViewById(R.id.txtTopicsList);



        new AsyncTaskData().execute();

    }



   class AsyncTaskData extends AsyncTask<Void,Void,Void>

    {

        StringBuffer topicList;

        @Override

        protected void onPreExecute()

        {

            super.onPreExecute();

            progressDialog=new ProgressDialog(MainActivity.this);

            progressDialog.setCancelable(false);

            progressDialog.setMessage("Loading...");

            progressDialog.show();

        }

        @Override

        protected Void doInBackground(Void... voids)

        {

            Reader reader= ServiceHandler.makeServiceCall("http://beta.json-generator.com/api/json/get/OkS85Le",ServiceHandler.GET,null);


            if(reader!=null)
            {

                beanSubject = new GsonBuilder().create().fromJson(reader, SubjectBean.class);



                topicArrayList=beanSubject.getBeanTopics();

                topicList=new StringBuffer();

                for(TopicBean topic: topicArrayList)
                {

                    Log.e("topic title: ",topic.getTitle()+"");
                    topicList.append("->"+topic.getTitle()+"\n");

                }

            }

            return null;

        }

        @Override

        protected void onPostExecute(Void aVoid)

        {

            super.onPostExecute(aVoid);

            progressDialog.dismiss();

            txtSubject.setText("Subject: "+beanSubject.getSubject());

            txtPrice.setText("price: "+beanSubject.getPrice());

            txtAuther.setText("Auther: "+beanSubject.getAuther());

            txtTopicsList.setText("Topics: "+"\n"+topicList);

        }

    }

}
Steps 5: Add permission to AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET" />

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />



I will be happy if you will provide your feedback or follow this blog. Any suggestion and help will be appreciated.
Thank you :)

4 Aug 2015

Customizing info window contents in Google map v2 Android

In this article we will create an Android application that displays a customized info-window in GoogleMap Android API V2 using InfoWindowAdapter interface.

At first, Please follow this Article to implement Google map with your android application.

Once you have implemented Google map and its working fine with android application, let modify code to show custom info window of Google map.




1. Create info_window_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@android:color/white"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center" />

    <TextView
        android:id="@+id/tv_lat"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/tv_lng"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />


</LinearLayout>

2. Modify LoadingGoogleMap Method


Below is the code snippet need to change with previous article.

void LoadingGoogleMap(ArrayList<LatLngBean> arrayList)
       {     
              if (googleMap != null)
              {
                     googleMap.clear();
                     googleMap.getUiSettings().setMyLocationButtonEnabled(true);
                     googleMap.setMyLocationEnabled(true);
                     googleMap.getUiSettings().setZoomControlsEnabled(true);

                     if(arrayList.size()>0)
                     {                                
                           try
                           {                         
                                  listLatLng=new ArrayList<LatLng>();
                                  for (int i = 0; i < arrayList.size(); i++)
                                  {
                                         LatLngBean bean=arrayList.get(i);
                                         if(bean.getLatitude().length()>0 && bean.getLongitude().length()>0)
                                         {
                                                double lat=Double.parseDouble(bean.getLatitude());
                                                double lon=Double.parseDouble(bean.getLongitude());          

                                                Marker marker = googleMap.addMarker(new MarkerOptions()
                                                .position(new LatLng(lat,lon))
                                                .title(bean.getTitle())
                                                .snippet(bean.getSnippet())
                                                .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)));

                                                //Add Marker to Hashmap
                                                hashMapMarker.put(marker,bean);

                                                //Set Zoom Level of Map pin
                                                LatLng object=new LatLng(lat, lon);
                                                listLatLng.add(object);
                                         }                                
                                  }
                                  SetZoomlevel(listLatLng);
                           }
                           catch (NumberFormatException e)
                           {
                                  e.printStackTrace();
                           }                         
                           googleMap.setInfoWindowAdapter(new InfoWindowAdapter()
                           {                                
                                  // Use default InfoWindow frame
                                  @Override
                                  public View getInfoWindow(Marker arg0)
                                  {
                                         return null;
                                  }

                                  // Defines the contents of the InfoWindow
                                  @Override
                                  public View getInfoContents(Marker marker)
                                  {                   
                                         // Getting view from the layout file info_window_layout
                                         View v = getLayoutInflater().inflate(R.layout.info_window_layout, null);

                                         // Getting the position from the marker
                                         LatLngBean bean=hashMapMarker.get(marker);

                                         TextView tv_title = (TextView) v.findViewById(R.id.tv_title);
                                         TextView tvLat = (TextView) v.findViewById(R.id.tv_lat);
                                         TextView tvLng = (TextView) v.findViewById(R.id.tv_lng);

                                         tv_title.setText("Title:" + bean.getTitle());
                                         tvLat.setText("Latitude:" + bean.getLatitude());
                                         tvLng.setText("Longitude:"+ bean.getLongitude());

                                         // Returning the view containing InfoWindow contents
                                         return v;

                                  }
                           });

                           googleMap.setOnInfoWindowClickListener(new OnInfoWindowClickListener() {

                                  @Override
                                  public void onInfoWindowClick(Marker marker)
                                  {
                                         LatLngBean bean=hashMapMarker.get(marker);
                                         Toast.makeText(getApplicationContext(), bean.getTitle(),Toast.LENGTH_SHORT).show();
                                  }
                           });
                     }
              }

              else
              {
                     Toast.makeText(getApplicationContext(),"Sorry! unable to create maps", Toast.LENGTH_SHORT).show();
              }

       }

I will be happy if you will provide your feedback or follow this blog. Any suggestion and help will be appreciated.
Thank you :)

3 Aug 2015

Display multiple markers on map | zoom level to show all the markers | Associate an object with Marker Google MapV2 in Android

This article aims to give knowledge about how to implements newer Google Maps into your applications. If you have already worked with V1, implementing V2 is very easy.

Here are the few implementation for this article.

1) Plot multiple pin on Google map
2) Zoom level to show all the markers within screen
3) Click event on marker associated object item.
4) Customize info window on Google map,Please visit.

Before starting implementation Google map with your application, you need follow few step to create api key for map. follow this link to set up your Google play service and map api key.




Step 1 : Create activity_main.xml

<LinearLayout 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:orientation="vertical" >

    <RelativeLayout
        android:id="@+id/rlMapLayout"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1.2"
        android:orientation="vertical" >

        <fragment
            android:id="@+id/map"
            android:name="com.google.android.gms.maps.SupportMapFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </RelativeLayout>


</LinearLayout>

Step 2 : Create class as LatLngBean

public class LatLngBean
{     
       private String Title="";
       private String Snippet="";
       private String Latitude="";
       private String  Longitude="";
      
       public String getTitle() {
              return Title;
       }
       public void setTitle(String title) {
              Title = title;
       }
       public String getSnippet() {
              return Snippet;
       }
       public void setSnippet(String snippet) {
              Snippet = snippet;
       }
       public String getLatitude() {
              return Latitude;
       }
       public void setLatitude(String latitude) {
              Latitude = latitude;
       }
       public String getLongitude() {
              return Longitude;
       }
       public void setLongitude(String longitude) {
              Longitude = longitude;
       }
      

}

Step 3 : Create class as MainActivity

import java.util.ArrayList;
import java.util.HashMap;
import android.app.Dialog;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.RelativeLayout;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnInfoWindowClickListener;
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.LatLngBounds;
import com.google.android.gms.maps.model.LatLngBounds.Builder;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;

public class MainActivity extends FragmentActivity {

       private GoogleMap googleMap;
       private ArrayList<LatLng>listLatLng;
       private RelativeLayout rlMapLayout;
       HashMap<Marker,LatLngBean> hashMapMarker = new HashMap<Marker,LatLngBean>();
      
       @Override
       protected void onCreate(Bundle savedInstanceState)
       {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main);
             
              rlMapLayout=(RelativeLayout) findViewById(R.id.rlMapLayout);
             
              setUpMapIfNeeded();       
              setData();
             
       }

       private void setData()
       {
              ArrayList<LatLngBean> arrayList=new ArrayList<LatLngBean>();
              LatLngBean bean=new LatLngBean();
              bean.setTitle("Ahmedabad");
              bean.setSnippet("Hello,Ahmedabad");
              bean.setLatitude("23.0300");
              bean.setLongitude("72.5800");
              arrayList.add(bean);
             
              LatLngBean bean1=new LatLngBean();
              bean1.setTitle("Surat");
              bean1.setSnippet("Hello,Surat");
              bean1.setLatitude("21.1700");
              bean1.setLongitude("72.8300");          
              arrayList.add(bean1);
             
              LatLngBean bean2=new LatLngBean();
              bean2.setTitle("Vadodara");
              bean2.setSnippet("Hello,Vadodara");
              bean2.setLatitude("22.3000");
              bean2.setLongitude("73.2000");          
              arrayList.add(bean2);
             
              LoadingGoogleMap(arrayList);
       }

       /**
        * @author Hasmukh Bhadani
        * Set googleMap if require
        */
       private void setUpMapIfNeeded()
       {
              int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getBaseContext());

              // Google Play Services are not available
              if(status!=ConnectionResult.SUCCESS)
              {
                     int requestCode = 10;
                     Dialog dialog = GooglePlayServicesUtil.getErrorDialog(status, this, requestCode);
                     dialog.show();

              }
              else
              {
                     if (googleMap == null)
                     {
                           googleMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
                           if (googleMap != null)
                           {
                                  googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
                                  googleMap.setMyLocationEnabled(true);
                                  googleMap.getUiSettings().setMyLocationButtonEnabled(true);
                                  googleMap.getUiSettings().setZoomControlsEnabled(true);
                           }
                     }
              }
       }

       /**
        * @author Hasmukh Bhadani
        * Loading Data to the GoogleMap
        */
       // -------------------------Google Map
       void LoadingGoogleMap(ArrayList<LatLngBean> arrayList)
       {     
              if (googleMap != null)
              {
                     googleMap.clear();
                     googleMap.getUiSettings().setMyLocationButtonEnabled(true);
                     googleMap.setMyLocationEnabled(true);
                     googleMap.getUiSettings().setZoomControlsEnabled(true);

                     if(arrayList.size()>0)
                     {                                
                           try
                           {                         
                                  listLatLng=new ArrayList<LatLng>();
                                  for (int i = 0; i < arrayList.size(); i++)
                                  {
                                         LatLngBean bean=arrayList.get(i);
                                         if(bean.getLatitude().length()>0 && bean.getLongitude().length()>0)
                                         {
                                                double lat=Double.parseDouble(bean.getLatitude());
                                                double lon=Double.parseDouble(bean.getLongitude());          
                                               
                                                Marker marker = googleMap.addMarker(new MarkerOptions()
                                                .position(new LatLng(lat,lon))
                                                .title(bean.getTitle())
                                                .snippet(bean.getSnippet())
                                                .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)));
                                               
                                                //Add Marker to Hashmap
                                                hashMapMarker.put(marker,bean);

                                                //Set Zoom Level of Map pin
                                                LatLng object=new LatLng(lat, lon);
                                                listLatLng.add(object);
                                         }                                
                                  }
                                  SetZoomlevel(listLatLng);
                           }
                           catch (NumberFormatException e)
                           {
                                  e.printStackTrace();
                           }
                          
                           googleMap.setOnInfoWindowClickListener(new OnInfoWindowClickListener() {
                                 
                                  @Override
                                  public void onInfoWindowClick(Marker position)
                                  {
                                         LatLngBean bean=hashMapMarker.get(position);
                                         Toast.makeText(getApplicationContext(), bean.getTitle(),Toast.LENGTH_SHORT).show();
                                        
                                  }
                           });
                     }
              }

              else
              {
                     Toast.makeText(getApplicationContext(),"Sorry! unable to create maps", Toast.LENGTH_SHORT).show();
              }
       }
       /**
        * @author Hasmukh Bhadani
        * Set Zoom level all pin withing screen on GoogleMap
        */
       public void  SetZoomlevel(ArrayList<LatLng> listLatLng)
       {
              if (listLatLng != null && listLatLng.size() == 1)
              {
                     googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(listLatLng.get(0), 10));
              }
              else if (listLatLng != null && listLatLng.size() > 1)
              {
                     final Builder builder = LatLngBounds.builder();
                     for (int i = 0; i < listLatLng.size(); i++)
                     {
                           builder.include(listLatLng.get(i));
                     }

                     final ViewTreeObserver treeObserver = rlMapLayout.getViewTreeObserver();
                     treeObserver.addOnGlobalLayoutListener(new OnGlobalLayoutListener()
                     {
                           @SuppressWarnings("deprecation")
                           @Override
                           public void onGlobalLayout()
                           {
                                  if(googleMap != null){
                                         googleMap.moveCamera(CameraUpdateFactory.newLatLngBounds(builder.build(), findViewById(R.id.map)
                                                       .getWidth(), findViewById(R.id.map).getHeight(), 80));
                                         rlMapLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                                  }
                           }
                     });

              }
       }

}

Step 4 : Modify AndroidManifest.xml

 -  you need to modify your AndroidManifest.xml for set few permission for Google map,

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.hb.mapv2"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="21" />
   
     <!-- MAP PERMISSION -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />   

    <permission
        android:name="<YOUR PCAKAGENAME>.permission.MAPS_RECEIVE"
        android:protectionLevel="signature" />

    <uses-permission android:name="<YOUR PCAKAGENAME>.permission.MAPS_RECEIVE" />

  <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=".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>       
          <!-- MAP meta-data -->
        <meta-data
            android:name="com.google.android.maps.v2.API_KEY"
            android:value="<YOUR API KEY HERE...>" />
        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />
       
    </application>
</manifest>

For More reference follow link

Google map operation visit 

I will be happy if you will provide your feedback or follow this blog. Any suggestion and help will be appreciated.
Thank you :)