January 23rd, 2016

About Me

January 23rd, 2016

Valentine Paramonov

Software Developer @ 4financeIT

Experienced in Java/Spring based Back-end Development (not Android)

Interested in Clean Coding, JS-based web frameworks, Functional Programming

1/32

What's Good About Maps

January 23rd, 2016

Maps give clear context on thing like:

Distances

Maps help build immersive apps for improved User Experience (UX)

'' A picture is worth a thousand words

Locations

Directions

2/32

What's Good About Google Maps

January 23rd, 2016

More than 12 years of development

Users feel right at home

Android API is available since 2008

Gestures, markers, camera operations out of the box

Easily integratable with other Google APIs (Directions, Locations, etc.)

API is free for starters

3/32

The Old Google Maps API

January 23rd, 2016

The old Google Maps API for Android was pain to develop for. It suffered from one big design flaw - the map was implemented as a subclass of Activity class. This brought to limitation of having only one map at a time.

4/32

Google Maps API v2

January 23rd, 2016

Google released the redesigned version of Google Maps API for Android in late 2012. It no longer had the limitation of having one map at at time and brought many other useful features.

5/32

Google Play Services (GMS)

January 23rd, 2016

Maps API is now part of GMS

6/32

Advantages of GMS

January 23rd, 2016

GMS give you the advantage of automatic updates. That means instant availability of new features. No need to upgrade and redeploy.

Also, missing APKs can be installed through Google Play store.

7/32

Power of GMS

January 23rd, 2016

There are some really useful features available through GMS that you might want to use inside your app:

8/32

Fused Location Provider

Geofencing

Activity Recognition

Fused Location Provider

January 23rd, 2016

Fused Location is a location determined with the use of GPS, Wifi, Cell signal and Sensors.

9/32

Geofencing

January 23rd, 2016

A geofence is a virtual barrier. Basically, you set up an area on the map so every time the device enters or leaves the area, your app receives a callback.

10/32

Activity Recognition

January 23rd, 2016

The service allows to determine whether the user is:

11/32

Still

Walking

Running

Cycling

Driving

New Features of Maps API v2

January 23rd, 2016

12/32

As many maps as you want

Everything is Parcelable

No need to swap markers to change icons

Gestures are enabled by default

Indoor maps

Better sensor integration

Getting Started

January 23rd, 2016

First things first - you need a key. You can get yours through the Google Developers Console.

The key is free. You can use it with any of your applications that call the Google Maps Android API, and it supports an unlimited number of users.

Then, declare the key inside your app's manifest.

13/32

Getting the Key

January 23rd, 2016

The Google API key is generated based on the SHA1 of the key you sign your app with.

14/32

$ keytool -genkey -v -keystore gdgmaps.keystore -alias gdgmaps -keyalg RSA 
-keysize 2048 -validity 10000

$ keytool -list -v -keystore gdgmaps.keystore

Then, you register the SHA1 and the project package in the Google Developers Console.

Signing the App

January 23rd, 2016

Even the debug version of the app has to be signed. Configure the keystore containing the key through signingConfigs.

15/32

android {
    signingConfigs {
        debug {
            storeFile file("$projectDir/gdgmaps.keystore")
            storePassword 'gdgmaps'
            keyAlias 'gdgmaps'
            keyPassword 'gdgmaps'
        }
    }
}

Adding the Key

January 23rd, 2016

16/32

<meta-data
    android:name="com.google.android.geo.API_KEY"
    android:value="OuzaSyDci9tB6JMNqAR6sKuVxvL6JKJO0hgu7eg"/>

The key you get from Google has to be stored inside the app's manifest file with the name com.google.android.geo.API_KEY.

Adding Google Play Services

January 23rd, 2016

Next step is adding the dependency to GMS inside app/build.gradle

17/32

dependencies {
    compile 'com.google.android.gms:play-services:8.4.0'
}

and adding the GMS version to the app's manifest

<meta-data
     android:name="com.google.android.gms.version"
     android:value="@integer/google_play_services_version"/>

Declaring Permissions

January 23rd, 2016

For MyLocation feature

18/32

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

For caching

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

For the advantage of hardware acceleration

<uses-feature
    android:glEsVersion="0x00020000"
    android:required="true"/>

Adding Map Fragment

January 23rd, 2016

Through XML

19/32

<fragment android:id="@+id/map"
          android:name="com.google.android.gms.maps.SupportMapFragment"
          xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:map="http://schemas.android.com/apk/res-auto"
          xmlns:tools="http://schemas.android.com/tools"
          tools:context="test.gdgriga.lv.mapstest.MapsActivity"/>
getFragmentManager().beginTransaction()
                    .add(R.id.map_container, new MapFragment())
                    .commit();

Programmatically

Adding a Map

January 23rd, 2016

20/32

public class MyLovelyMap extends MapFragment {
    OnMapReadyCallback onMapReady = new OnMapReadyCallback() {
        @Override
        public void onMapReady(GoogleMap map) {
            LatLng riga = new LatLng(56.948889, 24.106389);
            map.addMarker(new MarkerOptions().position(riga)
                .title("Place where it all began..."));
            map.moveCamera(CameraUpdateFactory.newLatLng(riga));
        }
    };

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        getMapAsync(onMapReady);
    }
}

Switching Between Terrain Types

January 23rd, 2016

21/32

public class MyLovelyMap extends MapFragment {
    OnMapReadyCallback onMapReady = new OnMapReadyCallback() {
        @Override
        public void onMapReady(GoogleMap map) {
            LatLng riga = new LatLng(56.948889, 24.106389);
            map.moveCamera(
                CameraUpdateFactory.newLatLngZoom(riga, 12));
            /* Could be MAP_TYPE_NORMAL, MAP_TYPE_TERRAIN, 
               MAP_TYPE_HYBRID or MAP_TYPE_NONE */
            map.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
        }
    };

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        getMapAsync(onMapReady);
    }
}

Indoor Maps

January 23rd, 2016

22/32

public class MyLovelyMap extends MapFragment {
    OnMapReadyCallback onMapReady = new OnMapReadyCallback() {
        @Override
        public void onMapReady(GoogleMap map) {
            map.setIndoorEnabled(true); // enabled by default
            LatLng whiteHouse = 
                new LatLng(38.8976611,-77.0367171);
            map.moveCamera(CameraUpdateFactory.newLatLngZoom(
                whiteHouse, 20));
        }
    };

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        getMapAsync(onMapReady);
    }
}

Custom Markers

January 23rd, 2016

23/32

public class MyLovelyMap extends MapFragment {
    OnMapReadyCallback onMapReady = new OnMapReadyCallback() {
        @Override
        public void onMapReady(GoogleMap map) {
            LatLng techHub = new LatLng(56.9485686, 24.1088373);
            map.moveCamera(
                CameraUpdateFactory.newLatLngZoom(techHub, 16));
            map.addMarker(new MarkerOptions()
                .icon(BitmapDescriptorFactory.fromResource(
                    R.drawable.techhub))
                // Anchors the marker on the bottom middle
                .anchor(0.5f, 1f)
                .position(techHub));
        }
    };

    ...
}

Flat Markers

January 23rd, 2016

24/32


OnMapReadyCallback onMapReady = new OnMapReadyCallback() {
    @Override
    public void onMapReady(GoogleMap map) {
        LatLng techHub = new LatLng(56.9485686, 24.1088373);
        map.moveCamera(
            CameraUpdateFactory.newLatLngZoom(techHub, 14));
        map.addMarker(new MarkerOptions()
            .icon(BitmapDescriptorFactory.fromResource(
                R.drawable.techhub))
            .position(techHub).anchor(0.5f, 1f).flat(true));
        CameraPosition position = CameraPosition.builder()
            .target(techHub).zoom(14).bearing(90).build();
        map.animateCamera(
            CameraUpdateFactory.newCameraPosition(position), 
            2000, null);
    }
};

Circles and Polys

January 23rd, 2016

25/32


OnMapReadyCallback onMapReady = new OnMapReadyCallback() {
    @Override
    public void onMapReady(GoogleMap map) {
             LatLng riga = new LatLng(56.948889, 24.106389);
            map.moveCamera(
                CameraUpdateFactory.newLatLngZoom(riga, 15));
            map.addCircle(new CircleOptions().center(riga)
                .radius(300).strokeWidth(10)
                .strokeColor(Color.BLUE));
            map.addPolyline(new PolylineOptions()
                .geodesic(true).width(8).color(Color.RED)
                .add(new LatLng(56.9505, 24.106389))
                .add(riga)
                .add(new LatLng(56.9485, 24.11)));
    }
};

Maps Utils

January 23rd, 2016

https://github.com/googlemaps/android-maps-utils

26/32

There's a utility library available on GitHub.

Marker clustering, Heat maps, IconGenerator, Poly decoding and encoding, Spherical geometry and more.

What We'll Build

January 23rd, 2016

An app that shows your photos on the map and allows to add location tags to them.

Please clone

https://github.com/gdgriga/GDGMaps

and follow the instruction in the README.

27/32

Read On

January 23rd, 2016

Google APIs for Android

    https://developers.google.com/android/guides/overview
Google Maps Android API

    https://developers.google.com/maps/documentation/android-api
Google Maps Android API - Getting Started

    https://developers.google.com/maps/documentation/android-api/start
When Android Meets Maps

    https://www.youtube.com/watch?v=_oZiK_NJuG8
Maps Shortcuts: Android Maps Utility Library

    https://www.youtube.com/watch?v=nb2X9IjjZpM
 

28/32

Read On.

January 23rd, 2016

Google Maps Android API utility library

    http://googlemaps.github.io/android-maps-utils
Beyond the Blue Dot (Activity recognition)

    https://www.youtube.com/watch?v=Bte_GHuxUGc
Getting around with Google Maps Android API v2 by Cyril Mottier

    https://speakerdeck.com/cyrilmottier/getting-around-with-google-maps-android-api-v2
Maps on Android

    https://docs.google.com/presentation/d/1G8U7LsGpWTeO4gsYetLK6Co6aNeUZADiNRXy7MeFxDY/present

29/32

Read On..

January 23rd, 2016

What's wrong with Google Maps development on Android

    http://www.cannonade.net/blog.php?id=1505
What's right with Google Maps Android V2

    http://www.cannonade.net/blog.php?id=1582
Google Maps Android API Release Notes

    https://developers.google.com/maps/documentation/android-api/releases
Property Animation Framework

    http://developer.android.com/guide/topics/graphics/prop-animation.html
Google Places API for Android

    https://developers.google.com/places/android-api

30/32

Read On...

January 23rd, 2016

Google Maps Directions API

    https://developers.google.com/maps/documentation/directions
Google Maps APIs Pricing and Plans

    https://developers.google.com/maps/pricing-and-plans
Thinking About Design with Geofences

    https://civic.mit.edu/blog/erhardt/thinking-about-design-with-geo-fences
Activity Recognition

    https://www.youtube.com/watch?v=S8sugXgUVEI

31/32

January 23rd, 2016

32/32

THANK YOU!

Working with Google Maps on Android

By Valentine Paramonov

Working with Google Maps on Android

  • 83