Getting Started with Android
Note
Bing Maps SDK for Android and iOS retirement
Bing Maps SDK for Android and iOS is deprecated and will be retired. Free (Basic) account customers can continue to use Bing Maps SDK for Android and iOS until June 30th, 2025. Enterprise account customers can continue to use Bing Maps SDK for Android and iOS until June 30th, 2028. To avoid service disruptions, all implementations using Bing Maps SDK for Android and iOS will need to be updated to use Azure Maps Web SDK by the retirement date that applies to your Bing Maps for Enterprise account type.
Azure Maps is Microsoft's next-generation maps and geospatial services for developers. Azure Maps has many of the same features as Bing Maps for Enterprise, and more. To get started with Azure Maps, create a free Azure subscription and an Azure Maps account. For more information about azure Maps, see Azure Maps Documentation. For migration guidance, see Bing Maps Migration Overview.
This tutorial goes through creating an Android app with a Bing Maps Native Control step-by-step.
Prerequisites
- Bing Maps Key. Must be obtained to use the Bing Maps SDK. The Bing Maps Key will need to be specified through the API to use the Bing Maps native control and to make API requests to Bing Maps services. Visit the Bing Maps Dev Center Help page for detailed steps on obtaining one.
- Android Studio. This example is built using Android Studio. You can download it here.
Creating a project
After Android Studio is installed, create a new project in it.
Launch Android Studio and choose File > New > New Project
Select Phone and Tablet tab, choose Empty Activity, and press Next
Select API 19 as your Minimum API level, choose a name, package, location for your project, and and press Finish
When it comes to language, this tutorial is in Java, though feel free to use Kotlin if that's your preference.
Including Bing Maps Native Control in your project
In your project's app
folder, create a file named secrets.gradle
and put there your Bing Maps Key like shown:
ext.credentialsKey = "ENTER YOUR KEY HERE"
In your project/build.gradle
file, inside allprojects
, insert the following block in repositories
:
repositories { jcenter() maven { url 'https://microsoftmaps.jfrog.io/artifactory/Maven/' } }
In your app/build.gradle
file, apply this line at the top to import the external variables from newly created file:
apply from: 'secrets.gradle'
Next, in the same file, inside buildTypes
block, insert following block next to release
block to add a build config field with your Bing Maps key in order to be able to use it from Java code:
buildTypes.each { it.buildConfigField "String", "CREDENTIALS_KEY", "\"$credentialsKey\"" }
And finally, inside dependencies
block, add the following lines and build your project:
implementation 'com.microsoft.maps:maps-sdk:1.2.0'
Adding a map view to your activity
Add following markup to your activity layout (app/res/layout/{your_layout_file}.xml
). This will be the map view:
<FrameLayout android:id="@+id/map_view" android:layout_width="match_parent" android:layout_height="match_parent" />
Add these imports to your source file:
import com.microsoft.maps.MapRenderMode; import com.microsoft.maps.MapView;
At the top of your activity class, declare a MapView:
private MapView mMapView;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.{your_layout_file}); mMapView = new MapView(this, MapRenderMode.VECTOR); // or use MapRenderMode.RASTER for 2D map mMapView.setCredentialsKey(BuildConfig.CREDENTIALS_KEY); ((FrameLayout)findViewById(R.id.map_view)).addView(mMapView); mMapView.onCreate(savedInstanceState); }
Handling life cycle events
Override Activity and Fragment life cycle methods, onCreate
, onStart
, onResume
, onPause
, onSaveInstanceState
, onStop
, onDestroy
, and onLowMemory
to call respective MapView methods from the callbacks as follow:
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.{your_layout_file}); // Code to create your MapView mMapView.onCreate(savedInstanceState); }
@Override protected void onStart() { super.onStart(); mMapView.onStart(); }
@Override protected void onResume() { super.onResume(); mMapView.onResume(); }
@Override protected void onPause() { super.onPause(); mMapView.onPause(); }
@Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); mMapView.onSaveInstanceState(outState); }
@Override protected void onStop() { super.onStop(); mMapView.onStop(); }
@Override protected void onDestroy() { super.onDestroy(); mMapView.onDestroy(); }
@Override public void onLowMemory() { super.onLowMemory(); mMapView.onLowMemory(); }
Ready to run!
Further customization
Scenes
Let's go through a common scenario to set map scene to a specific location on startup.
First, add following imports:
import com.microsoft.maps.Geopoint; import com.microsoft.maps.MapAnimationKind; import com.microsoft.maps.MapScene;
Next step is declaring the location. Say, we want to show Seattle and Bellevue and choose Lake Washington in between:
private static final Geopoint LAKE_WASHINGTON = new Geopoint(47.609466, -122.265185);
Then override your activity's onStart
method with a setScene
call:
@Override protected void onStart() { super.onStart(); mMapView.setScene( MapScene.createFromLocationAndZoomLevel(LAKE_WASHINGTON, 10), MapAnimationKind.NONE); }
Pins
You can attach pins to locations on the map using custom element layer populated with MapImage
elements. Here's an example:
First, you'll need these imports:
import com.microsoft.maps.Geopoint; import com.microsoft.maps.MapElementLayer; import com.microsoft.maps.MapIcon; import com.microsoft.maps.MapImage;
Then, declare the element layer as class member:
private MapElementLayer mPinLayer;
Next step, initialize and add it to map view's layers in your onCreate
method:
mPinLayer = new MapElementLayer(); mMapView.getLayers().add(mPinLayer);
Use the following snippet to add pins:
Geopoint location = ... // your pin lat-long coordinates String title = ... // title to be shown next to the pin Bitmap pinBitmap = ... // your pin graphic (optional) MapIcon pushpin = new MapIcon(); pushpin.setLocation(location); pushpin.setTitle(title); pushpin.setImage(new MapImage(pinBitmap)); mPinLayer.getElements().add(pushpin);
Note: if pins in your scenario use the same graphic, it is recommended to reuse the associated MapImage
object. Rather than creating a new one for each pin, consider declaring and initializing it similarly to your MapElementLayer
instance.
To clear existing pins, just call clear()
on Elements
member of the associated layer:
mPinLayer.getElements().clear();
Styling
There's a set of predefined styles exposed by MapStyleSheets class:
empty
: renders nothing. Useful if you want to display a custom set of tiles with no underlying map data.roadLight
: symbolic map, light color scheme. Default look.roadDark
: symbolic map, dark color scheme.roadCanvasLight
: symbolic map, light low-contrast color scheme.roadHighContrastLight
: symbolic map, light high-contrast color scheme.roadHighContrastDark
: symbolic map, dark high-contrast color scheme.aerial
: photorealistic map.aerialWithOverlay
: hybrid map, photorealistic tiles with symbolic entities rendered on top.
Example setting aerialWithOverlay
map style:
import com.microsoft.maps.MapStyleSheets; ... mMapView.setMapStyleSheet(MapStyleSheets.aerialWithOverlay());
Bing Maps Native Control also supports custom styling via JSON, using the same format as desktop and iOS controls. Here's an example applying your own style:
import com.microsoft.maps.MapStyleSheet; ... MapStyleSheet style = MapStyleSheet.fromJson(yourCustomStyleJsonString); if (style != null) { mMapView.setMapStyleSheet(style); } else { // Custom style JSON is invalid }
Map projection
Bing Maps Native Control runs on a 3D engine and it supports switching map projection between Web Mercator and Globe on demand and in real time. Here's an example:
import com.microsoft.maps.MapProjection; ... mMapView.setMapProjection(MapProjection.GLOBE); mMapView.setMapProjection(MapProjection.WEB_MERCATOR);