Initial stuff
Before we begin:
- Sign up for an account at mapbox.com/signup. Find your access token on your account page.
- Create a new Android Studio project.
Add Gradle dependencies
repositories { mavenCentral() }
implementation 'com.mapbox.mapboxsdk:mapbox-sdk-services:4.3.0' implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:6.8.1' implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-places-v7:0.7.0' implementation ('com.mapbox.mapboxsdk:mapbox-android-geocoder:1.0.0@aar'){ transitive=true } implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-annotation-v7:0.4.0' implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-markerview-v7:0.2.0'
AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Initialise Mapbox for your project. Add your access token to res/strings.xml
<string name="mapbox_access_token">MAPBOX_ACCESS_TOKEN</string>
Create an application class to initialize Mapbox for our project. This can be done in your activity class too, but it is better to do it this way if you’re using mapbox in more than one view
public class MyApplication extends Application { private static Context context; public void onCreate() { super.onCreate(); MyApplication.context = getApplicationContext(); Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); } }
in the application tag of your manifest, make sure to add
android:name="your.package.name.MyApplication"
Adding the map
in your activity layout
<?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:mapbox="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <com.mapbox.mapboxsdk.maps.MapView android:id="@+id/mapView" android:layout_width="match_parent" android:layout_height="match_parent" mapbox:mapbox_cameraTargetLat="25.2854" mapbox:mapbox_cameraTargetLng="51.5310" mapbox:mapbox_cameraZoom="14"/> </android.support.design.widget.CoordinatorLayout>
In your activity/fragment class’ onCreate()
private MapView mapView; private MapboxMap mbMap; mapView = findViewById(R.id.mapView); mapView.onCreate(savedInstanceState); mapView.getMapAsync(new com.mapbox.mapboxsdk.maps.OnMapReadyCallback() { @Override public void onMapReady(@NonNull final MapboxMap mapboxMap) { mbMap = mapboxMap; mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() { @Override public void onStyleLoaded(@NonNull Style style) { //create this function & code further stuff there initMapStuff(style); } }); } });
Add lifecycle methods
@Override @SuppressWarnings( {"MissingPermission"}) public void onStart() { super.onStart(); mapView.onStart(); } @Override public void onPause() { super.onPause(); mapView.onPause(); } @Override public void onStop() { super.onStop(); mapView.onStop(); } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); mapView.onSaveInstanceState(outState); } @Override public void onDestroy() { super.onDestroy(); mapView.onDestroy(); } @Override public void onLowMemory() { super.onLowMemory(); mapView.onLowMemory(); }
In case you’re using a fragment, make sure to override onDestroyView()
@Override public void onDestroyView() { super.onDestroyView(); mapView.onDestroy(); }
Enabling user location
if you want to show the blue user location icon, add this function in onStyleLoaded
enableLocationComponent(style);
handle permission, and activate the location component.
@SuppressWarnings( {"MissingPermission"}) private void enableLocationComponent(@NonNull Style loadedMapStyle) { if (PermissionsManager.areLocationPermissionsGranted(activity)) { LocationComponent locationComponent = mbMap.getLocationComponent(); locationComponent.activateLocationComponent(activity, loadedMapStyle); locationComponent.setLocationComponentEnabled(true); locationComponent.setCameraMode(CameraMode.TRACKING); locationComponent.setRenderMode(RenderMode.COMPASS); } else { permissionsManager = new PermissionsManager(new PermissionsListener() { @Override public void onExplanationNeeded(List<String> permissionsToExplain) { Toast.makeText(activity, "location not enabled", Toast.LENGTH_LONG).show(); } @Override public void onPermissionResult(boolean granted) { if (granted) { mbMap.getStyle(new Style.OnStyleLoaded() { @Override public void onStyleLoaded(@NonNull Style style) { initMapStuff(style); } }); } else { Toast.makeText(activity, "Location services not allowed", Toast.LENGTH_LONG).show(); } } }); permissionsManager.requestLocationPermissions(activity); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { permissionsManager.onRequestPermissionsResult(requestCode, permissions, grantResults); }
Adding a geolocate button
Add a button in your layout that will zoom the map to the current location upon click
<?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:mapbox="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <com.mapbox.mapboxsdk.maps.MapView android:id="@+id/mapView" android:layout_width="match_parent" android:layout_height="match_parent" mapbox:mapbox_cameraTargetLat="25.2854" mapbox:mapbox_cameraTargetLng="51.5310" mapbox:mapbox_cameraZoom="14"/> <android.support.design.widget.FloatingActionButton android:id="@+id/myLocationButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="top|right" android:layout_marginTop="8dp" android:layout_marginRight="8dp" android:src="@android:drawable/ic_menu_mylocation" app:borderWidth="0dp" app:elevation="6dp" app:pressedTranslationZ="12dp" app:fabSize="mini" /> </android.support.design.widget.CoordinatorLayout>
add the code inside onStyleLoaded, or if you have implemented the initMapStuff(style) function
FloatingActionButton FAB = (FloatingActionButton) view.findViewById(R.id.myLocationButton); FAB.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(mbMap.getLocationComponent().getLastKnownLocation() != null) { // Check to ensure coordinates aren't null, probably a better way of doing this... mbMap.animateCamera(com.mapbox.mapboxsdk.camera.CameraUpdateFactory.newLatLngZoom(new LatLng(mbMap.getLocationComponent().getLastKnownLocation().getLatitude(),mbMap.getLocationComponent().getLastKnownLocation().getLongitude()), 14)); } } });
Adding markers
Markers are added via symbol layer.
private SymbolManager symbolManager; private List<Symbol> symbols = new ArrayList<>();
Initialise and configure the symbolManager inside onStyleLoaded()
symbolManager = new SymbolManager(mapView, mbMap, style); symbolManager.setIconAllowOverlap(true); //your choice t/f symbolManager.setTextAllowOverlap(false); //your choice t/f
symbolManager.addClickListener(new OnSymbolClickListener() { @Override public void onAnnotationClick(Symbol symbol) { Toast.makeText(activity,"clicked " + symbol.getTextField().toLowerCase().toString(),Toast.LENGTH_SHORT).show(); } });
Custom Marker Image configuration
Choose the image that you want to use as the marker icon, and add it to our Mapbox map style. Write inside onMapLoaded()
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.myimage); mbMap.getStyle().addImage("my-marker",bm);
Creating one marker
symbolManager.create(new SymbolOptions() .withLatLng(new LatLng(s.getStopLat(),s.getStopLon())) .withIconImage("my-marker") //set the below attributes according to your requirements .withIconSize(1.5f) .withIconOffset(new Float[] {0f,-1.5f}) .withZIndex(10) .withTextField(s.getStopName()) .withTextHaloColor("rgba(255, 255, 255, 100)") .withTextHaloWidth(5.0f) .withTextAnchor("top") .withTextOffset(new Float[] {0f, 1.5f}) .setDraggable(false) );
Creating multiple markers
List<SymbolOptions> options = new ArrayList<>(); for (int i = 0; i < 5; i++ { options.add(new SymbolOptions() .withLatLng(getRandomLatLng()) .withIconImage("bus-marker") //set the below attributes according to your requirements .withIconSize(1.5f) .withIconOffset(new Float[] {0f,-1.5f}) .withZIndex(10) .withTextField("test marker") .withTextHaloColor("rgba(255, 255, 255, 100)") .withTextHaloWidth(5.0f) .withTextAnchor("top") .withTextOffset(new Float[] {0f, 1.5f}) .setDraggable(false) ); }
Finally, add the created markers to the map.
symbols = symbolManager.create(options);
to remove markers
symbolManager.delete(symbols);
Don’t forget to add this in your onDestroy() overridden method
symbolManager.onDestroy();
Adding markers: Method 2 (deprecated)
Although it’s deprecated, this way is relatively simpler so you can use this if you have to show a few markers easily.
For adding a single marker
mbMap.addMarker(markerOptions.add(new MarkerOptions().position(new LatLng(25.2854,51.5310)).setTitle("My Marker")));
For multiple markers
List<MarkerOptions> markerOptions = new ArrayList<>(); //add your data markerOptions.add(new MarkerOptions().position(new LatLng(25.2854,51.5310)).setTitle("marker1")); markerOptions.add(new MarkerOptions().position(new LatLng(25.2854,51.5310)).setTitle("marker1")); markerOptions.add(new MarkerOptions().position(new LatLng(25.2854,51.5310)).setTitle("marker1")); markerOptions.add(new MarkerOptions().position(new LatLng(25.2854,51.5310)).setTitle("marker1")); mbMap.addMarkers(markerOptions);
to remove markers
mbMap.clear();
Custom Marker Icon
com.mapbox.mapboxsdk.annotations.Icon myicon; IconFactory iconFactory = IconFactory.getInstance(activitycontext); myicon = iconFactory.fromResource(R.drawable.myiconimage);
or you can customize the icon, for example, resize it
com.mapbox.mapboxsdk.annotations.Icon icon = iconFactory.fromResource(R.drawable.myiconimage); myicon = IconFactory.recreate(icon.getId(), Bitmap.createScaledBitmap(icon.getBitmap(), 35, 35, false));
add it to MarkerOptions
.icon(myicon);
That’s all for now. More to come soon!
Leave A Comment