Руководство Google Maps Android API

1- Установка Google Map API

Для начала нужно удостовериться, что в  Android Studio установлены  Google API и  Google Play Service. Нужно проверить и по необходимости установить.
Проверить установлен ли  Google API.
Пакеты  "Google *** System Image" тоже должны быть установлены.
Далее вам нужно прокрутить вниз и проверить установлен ли  Google Play Service.

2- Использовать Google System Image для эмулятора

После установки пакетов библиотек выше, при запуске  Google Map на эмуляторе вам нужно настроить и использовать  Google System Image.

3- Регистрация Google Map API

Ваше приложение имеет компоненты карты, данные карты находятся в центре базы данных Google, поэтому ваше приложение постоянно имеет доступ к данным карты через сервис.
Не смотря на то, что данные карты Google предоставлены бесплатно вы не сможете извлечь данные произвольно, вам нужен  API Key, похоже креденшиал (Credentials) для доступа данных карты.
Вам нужно зарегистрировать  Google Map API Key, и это совершенно бесплатно. Смотрите по ссылке:

4- Пример с Google Map

Android Studio помогает вам создать project с  Google Map легко и быстро:
Но здесь я создам project с самого начала и перетащу Google Map на экран, может будет лучше если вы хотите в деталях понять все проблемы. OK, на  Android Studio создаем новый project с названием  MyGoogleMap.
Создан пустой project:

MapFragment & SupportMapFragment:

MapFragment & SupportMapFragment это фрагменты (fragments) имеющиеся заранее, включая  GoogleMap, вам нужно перетащить из 2-х фрагментов в экран дизайна  SupportMapFragment имеет больше функций.
Если в окне Fragments не имеется  MapFragment и  SupportMapFragment. Вам нужно настроить файл  build.gradle (Module:app):
Вам нужно настроить файл для  build.gradle (Module:app):
Добавить библиотеки:
compile 'com.google.android.gms:play-services:8.1.0'
Заметка: Несмотря на то, что  Google Play Services имеет версию 8.3.0 не факт что вы сможете ее запустить по некоторым причинам, поэтому вы можете использовать версию 8.1.0, используйте данную версию для теста перед тем, как использовать новую версию.
После объявления зависимой библиотеки, вам нужно полностью перевести project.
Возвращаемся к экрану дизайна. У вас есть 2 варианта использования  MapFragment или  SupportMapFragment. Оба фрагмента содержат  GoogleMap. При этом,  SupportMapFragment Имеет больше функций. Выбрать  SupportMapFragment.
Перетащите фрагмент чтобы заполнил весь экран.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<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"
    tools:context="org.o7planning.mygooglemap.MainActivity">

    <fragment
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:id="@+id/fragment"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentBottom="true" />

</RelativeLayout>
MainActivity.java
package org.o7planning.mygooglemap;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    
}

Google Map API Key

GoogleMap на Android использует услуги чтобы извлечь данные из Google и изображает их. Выше, вы уже зарегистрировали  Google Map API Key, вам нужно объявить этот Key в AndroidManifest.xml.
<meta-data
    android:name="com.google.android.maps.v2.API_KEY"
    android:value="Your API KEY" />
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="org.o7planning.mygooglemap">


    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <!-- Enter your GoogleMap Android API Key -->
        <meta-data
            android:name="com.google.android.maps.v2.API_KEY"
            android:value="Your ANDROID API Key" />


        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
Теперь можете запустить приложение:

5- Кастомизировать Google MAP

Продолжаем с примером выше. Вам нужен код, чтобы получить ваше текущее местоположение и использовать  Marker (Маркер), чтобы отметить местоположение на карте.
Вам нужны некоторые конфигурации на  AndroidManifest.xml позволяющие показывать ваше местоположение, доступ, доступ к интернету. Добавить  AndroidManifest.xml следующее:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="org.o7planning.mygooglemap">

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <!-- Enter your GoogleMap Android API Key -->
        <meta-data
            android:name="com.google.android.maps.v2.API_KEY"
            android:value="Your Android API Key" />


        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
MainActivity.java
package org.o7planning.mygooglemap;

import android.Manifest;
import android.app.ProgressDialog;
import android.content.pm.PackageManager;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.Toast;

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.CameraPosition;
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 MainActivity extends AppCompatActivity implements LocationListener {

    private GoogleMap myMap;
    private ProgressDialog myProgress;

    private static final String MYTAG = "MYTAG";

    // Request Code to ask the user for permission to view their current location (***).
    // Value 8bit (value <256)
    public static final int REQUEST_ID_ACCESS_COURSE_FINE_LOCATION = 100;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Create Progress Bar.
        myProgress = new ProgressDialog(this);
        myProgress.setTitle("Map Loading ...");
        myProgress.setMessage("Please wait...");
        myProgress.setCancelable(true);
        // Display Progress Bar.
        myProgress.show();


        SupportMapFragment mapFragment
                = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.fragment);

        // Set callback listener, on Google Map ready.
        mapFragment.getMapAsync(new OnMapReadyCallback() {

            @Override
            public void onMapReady(GoogleMap googleMap) {
                onMyMapReady(googleMap);
            }
        });

    }

    private void onMyMapReady(GoogleMap googleMap) {
        // Get Google Map from Fragment.
        myMap = googleMap;
        // Sét OnMapLoadedCallback Listener.
        myMap.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() {

            @Override
            public void onMapLoaded() {
                // Map loaded. Dismiss this dialog, removing it from the screen.
                myProgress.dismiss();

                askPermissionsAndShowMyLocation();
            }
        });
        myMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
        myMap.getUiSettings().setZoomControlsEnabled(true);
        myMap.setMyLocationEnabled(true);
    }


    private void askPermissionsAndShowMyLocation() {

        // With API> = 23, you have to ask the user for permission to view their location.
        if (Build.VERSION.SDK_INT >= 23) {
            int accessCoarsePermission
                    = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION);
            int accessFinePermission
                    = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);


            if (accessCoarsePermission != PackageManager.PERMISSION_GRANTED
                    || accessFinePermission != PackageManager.PERMISSION_GRANTED) {
                // The Permissions to ask user.
                String[] permissions = new String[]{Manifest.permission.ACCESS_COARSE_LOCATION,
                        Manifest.permission.ACCESS_FINE_LOCATION};
                // Show a dialog asking the user to allow the above permissions.
                ActivityCompat.requestPermissions(this, permissions,
                        REQUEST_ID_ACCESS_COURSE_FINE_LOCATION);

                return;
            }
        }

        // Show current location on Map.
        this.showMyLocation();
    }

    // When you have the request results.
    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           String permissions[], int[] grantResults) {

        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        //
        switch (requestCode) {
            case REQUEST_ID_ACCESS_COURSE_FINE_LOCATION: {

                // Note: If request is cancelled, the result arrays are empty.
                // Permissions granted (read/write).
                if (grantResults.length > 1
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED
                        && grantResults[1] == PackageManager.PERMISSION_GRANTED) {

                    Toast.makeText(this, "Permission granted!", Toast.LENGTH_LONG).show();

                    // Show current location on Map.
                    this.showMyLocation();
                }
                // Cancelled or denied.
                else {
                    Toast.makeText(this, "Permission denied!", Toast.LENGTH_LONG).show();
                }
                break;
            }
        }
    }

    // Find Location provider is openning.
    private String getEnabledLocationProvider() {
        LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);

        // Criteria to find location provider.
        Criteria criteria = new Criteria();

        // Returns the name of the provider that best meets the given criteria.
        // ==> "gps", "network",...
        String bestProvider = locationManager.getBestProvider(criteria, true);

        boolean enabled = locationManager.isProviderEnabled(bestProvider);

        if (!enabled) {
            Toast.makeText(this, "No location provider enabled!", Toast.LENGTH_LONG).show();
            Log.i(MYTAG, "No location provider enabled!");
            return null;
        }
        return bestProvider;
    }

    // Call this method only when you have the permissions to view a user's location.
    private void showMyLocation() {

        LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);

        String locationProvider = this.getEnabledLocationProvider();

        if (locationProvider == null) {
            return;
        }

        // Millisecond
        final long MIN_TIME_BW_UPDATES = 1000;
        // Met
        final float MIN_DISTANCE_CHANGE_FOR_UPDATES = 1;

        Location myLocation = null;
        try {
            // This code need permissions (Asked above ***)
            locationManager.requestLocationUpdates(
                    locationProvider,
                    MIN_TIME_BW_UPDATES,
                    MIN_DISTANCE_CHANGE_FOR_UPDATES, (LocationListener) this);
            // Getting Location.
            // Lấy ra vị trí.
            myLocation = locationManager
                    .getLastKnownLocation(locationProvider);
        }
        // With Android API >= 23, need to catch SecurityException.
        catch (SecurityException e) {
            Toast.makeText(this, "Show My Location Error: " + e.getMessage(), Toast.LENGTH_LONG).show();
            Log.e(MYTAG, "Show My Location Error:" + e.getMessage());
            e.printStackTrace();
            return;
        }

        if (myLocation != null) {

            LatLng latLng = new LatLng(myLocation.getLatitude(), myLocation.getLongitude());
            myMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 13));

            CameraPosition cameraPosition = new CameraPosition.Builder()
                    .target(latLng)             // Sets the center of the map to location user
                    .zoom(15)                   // Sets the zoom
                    .bearing(90)                // Sets the orientation of the camera to east
                    .tilt(40)                   // Sets the tilt of the camera to 30 degrees
                    .build();                   // Creates a CameraPosition from the builder
            myMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));


            // Add Marker to Map
            MarkerOptions option = new MarkerOptions();
            option.title("My Location");
            option.snippet("....");
            option.position(latLng);
            Marker currentMarker = myMap.addMarker(option);
            currentMarker.showInfoWindow();
        } else {
            Toast.makeText(this, "Location not found!", Toast.LENGTH_LONG).show();
            Log.i(MYTAG, "Location not found");
        }


    }


    @Override
    public void onLocationChanged(Location location) {

    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onProviderDisabled(String provider) {

    }

}
 
Запустить приложение:
Если вы запускаете приложение  GoogleMap на стимуляторе и  locationManager.getLastKnownLocation всегда возвращает null. Вам нужно поправить эту ошибку, посмотрите инструкцию в приложении, в конце данной статьи.
-
Если пользователь разрешил доступ к приложению, в следующий раз после запуска приложения  Android не потребует больше разрешения доступа. Вы можете настроить чтобы убрать разрешенный доступ к приложению. Смотрите инструкцию по ссылке:

6- Аппедикс: Исправить ошибку, когда не находится местоположение

В некоторых случая приложение не сможет найти ваше местоположение при работе с стимулятором, возможно причиной является ошибки  telnet, вам нужно исправить эту ошибку.

Шаг 1:

Убедиться  "Telnet Client" уже открыт.

Шаг 2:

Запустить приложение  Google Map на стимуляторе.

Шаг 3:

5554 это порт стимулятора. На  CMD дать команду:
telnet localhost 5554
Далее введите:
geo fix 12 45
Не закрывая окно стимулятора, закройте приложение карты ( MyGoogleMap), и откройте данное приложение на стимуляторе телефона.