Skip to main content

Places

Not compatible with the Maps SDK v10
This plugin is not compatible with the Maps SDK v10 or higher. To add search functionality to an application using the Maps SDK v10 and higher, see the Search SDK for Android documentation.

The Places Plugin for Android lets users search for a destination, explore what's nearby, or find their favorite restaurants, coffee shops, or stores. Built on top of the Mapbox Geocoding API, the plugin offers UI components that you can integrated inside your app with a few lines of code.

Search options

Mapbox provides two options for adding location search into your Android application:

Each option provides a different set of features:

FeatureJava SDKPlaces Plugin
Foward geocodingcheckcheck
Reverse geocodingcheckcheck
Access to raw Geocoding API responsecheck
Drop-in search bar UIcheck
Built-in dropdown list of search resultscheck
Place pickercheck
View results in a separate activity or fragmentcheck
Forward and reverse geocoding
Both the Java SDK and the Places Plugin enable you to make forward and reverse geocoding queries to the Mapbox Geocoding API, but the two differ in their flexibility and the query methods. As a reminder, a forward geocoding query converts a text query into geographic coordinates. Reverse geocoding turns geographic coordinates into geographical information (for example, address, place name, place category, and geometry type).

Install the Places Plugin

To start developing an application using the Places Plugin, you'll need to add the appropriate dependencies inside your build.gradle file. This dependency includes the Maps SDK for Android and the Mapbox Java SDK's Geocoding API. You can find all dependencies given below on MavenCentral.

Android's 64K method count limit
If your application is over the 64K method limit, you can shrink, obfuscate, and optimize your code with R8 or ProGuard. If those steps do not lower your method count below 64K, you can also enable multidex.

Add the dependency

  1. Open Android Studio.

  2. Open up your application's build.gradle.

  3. Make sure that your project's minSdkVersion is API 14 or higher.

  4. Under dependencies, add a new build rule for the latest mapbox-android-plugin-places-v9.

    repositories {
    mavenCentral()
    }

    dependencies {
    implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-places-v9:0.12.0'
    }
  5. Declare Java 8 support in the android { } block of the application's build.gradle file

    android {
    // Configure only for each module that uses Java 8
    // language features (either in its source code or
    // through dependencies).
    compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
    }
    // For Kotlin projects
    kotlinOptions {
    jvmTarget = "1.8"
    }
    }
  6. Click the Sync Project with Gradle Files link near in the upper right hand corner of Android Studio.

Add Autocomplete

The Autocomplete UI component offers users the ability to search addresses or places and receive information including the latitude and longitude, phone number, categories, and plenty of other information. As the user types, place predictions display at once to the user along with any searched places.

There are two ways to use the Autocomplete service:

  • Launch as an activity for result
  • Display as a fragment

Launch as an activity for result

If a separate search activity makes sense in your application, you can use the PlaceAutocomplete class to build your intent and then launch the included search activity using startActivityForResult. Using this intent builder, you pass in the required access token along with a placeOptions object.


Intent intent = new PlaceAutocomplete.IntentBuilder()
.accessToken(MAPBOX_ACCESS_TOKEN)
.placeOptions(placeOptions)
.build(this);
startActivityForResult(intent, REQUEST_CODE_AUTOCOMPLETE);

When the user finishes selecting a place inside the autocomplete activity, finish() will be called. To receive the CarmenFeature which describes the place the user selected, override the onActivityResult method, check that the request and result codes are correct, and use the PlaceAutocomplete static method getPlace passing in the intent.


@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CODE_AUTOCOMPLETE) {
CarmenFeature feature = PlaceAutocomplete.getPlace(data);
Toast.makeText(this, feature.text(), Toast.LENGTH_LONG).show();
}
}

Display as a fragment

If you need more control over the UI and would like to place the Autocomplete component inside an activity container, you can use the provided PlaceAutocompleteFragment to include the search UI. This class extends the Support Library Fragment implementation, which means the SupportFragmentManager should be used. In the code snippet provided below, it checks to make sure no more than one autocompleteFragment instance is always being used. If there isn't an instance of autocompleteFragment, it creates a new one and adds it to the container. If there is, it displays the autocompleteFragment to the user using the TAG.


PlaceAutocompleteFragment autocompleteFragment;

if (savedInstanceState == null) {
autocompleteFragment = PlaceAutocompleteFragment.newInstance("<access_token>");

final FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.add(R.id.fragment_container, autocompleteFragment,TAG);
transaction.commit();

} else {
autocompleteFragment = (PlaceAutocompleteFragment)
getSupportFragmentManager().findFragmentByTag(TAG);
}

To listen for when the user selects a place or cancels out of the autocompleteFragment, you can set a PlaceSelectionListener on the fragment and the callback will be invoked when the event occurs.


autocompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
@Override
public void onPlaceSelected(CarmenFeature carmenFeature) {
Toast.makeText(AutocompleteFragmentActivity.this,
carmenFeature.text(), Toast.LENGTH_LONG).show();
finish();
}

@Override
public void onCancel() {
finish();
}
});

Customize Autocomplete results

Create a PlaceOptions object to customize the Autocomplete search results and the UI component.

Once your PlaceOptions object's created you'll need to pass it in either by using the PlaceAutocompleteFragment.newInstance(<access token>, placeOptions); if you are using the fragment or new PlaceAutocomplete.IntentBuilder().placeOptions(placeOptions) otherwise.

Customize search results

You can narrow the search results based on the following parameters:

APIDescription
proximityBias local results based on a provided GeoJSON Point. This oftentimes increases accuracy in the returned results.
limitLimit the number of results returned. The default is 10.
bboxLimit results to a bounding box.
geocodingTypesOptional, use to filter the results returned inside the suggestions.
countryLimit results to one or more countries.
injectedPlacesOptionally inject Carmen Features into the suggestion view so users can access points of interest quickly without typing a single character. Typical places include, the users home, work, or favorite POI.

Customize the UI component

There are two modes to further change the Autocomplete component UI to fit your app better:

  • Full screen mode: will place all the search history, results, and injected places into a view which has a width equal to the app width.
  • Card view mode: the place search history, results, and injected places in an Android Support Library CardView.
APIDescription
backgroundColorSet the autocomplete's layout background color.
toolbarColorThe autocomplete's layout toolbar color. This only applies if the mode is full screen.

Add suggestions

When users are searching for places inside your app, oftentimes, they have a few places that are visited often and thus searched. Make things simpler for them by adding specific place suggestions such as their home, work, or favorite restaurant. This feature can also be used to insert store locations, or popular places your app is advertising.

To get started, you'll need to first get or create the CarmenFeature which describes this place. See an example of creating a CarmenFeature below which only includes the necessary information for your app, neglecting the large amount of additional information you could provide to describe the location.


CarmenFeature work = CarmenFeature.builder().text("Directions to Work")
.geometry(Point.fromLngLat(1.0, 2.0))
.placeName("300 Massachusetts Ave NW")
.id("directions-work")
.properties(new JsonObject())
.build();

Once complete, you will need to pass this feature into the PlaceOptions object using either the addInjectedFeature() or injectedPlaces() methods.

Clear search history

Typically found inside any application which offers search history like the places plugin does by default, they will also need to occasionally clear the search history. It's recommended to add a setting in your apps preferences to do this. If the user request clearing of the search history, you can use the static method provided inside the PlaceAutocomplete class called clearRecentHistory() which will clear all the data from the saved database at once.


PlaceAutocomplete.clearRecentHistory(this);

Place Picker

The Autocomplete UI component described above, searches for a place based on an address or name. The Place Picker UI component retrieves information about a selected map location. With the Place Picker, you can launch an activity for result and provide your users with a way to pick a visual location on the map. The result returned is a CarmenFeature, which can be used to get information such as the coordinate, place name, address, phone number, and more.

To begin, create the Place Picker IntentBuilder, which builds an intent ready to be launched by the startActivityForResult method.


private static final int PLACE_SELECTION_REQUEST_CODE = 56789

...

Intent intent = new PlacePicker.IntentBuilder()
.accessToken(Mapbox.getAccessToken())
.placeOptions(
PlacePickerOptions.builder()
.statingCameraPosition(
new CameraPosition.Builder()
.target(new LatLng(40.7544, -73.9862))
.zoom(16)
.build())
.build())
.build(this);
startActivityForResult(intent, PLACE_SELECTION_REQUEST_CODE);

Override the onActivityResult() method and extract information from the CarmenFeature:


@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data);

if (requestCode == REQUEST_CODE && resultCode == RESULT_OK){

// Retrieve the information from the selected location's CarmenFeature

CarmenFeature carmenFeature = PlacePicker.getPlace(data);
}
}

If you'd like to show the Place Picker UI without any geocoding information, use the PlacePickerOptions class' includeReverseGeocode() method. This method takes a boolean parameter and if false is passed through, makes no geocoding call. The selected location's coordinates will be returned in the onActivityResult callback, rather than a geocoding result's CarmenFeature.

You might want an app user to choose a precise location. For example, the user needs to choose a place on the map to share with friends. But, as an app developer, you don't care about the geocoding metadata associated with those coordinates. Your app needs a way for a user to pick the place so that the coordinates can be used. A new geocoding call happens every time the map is moved with the Place Picker Plugin. These constant geocoding calls are billed to your Mapbox account. Using includeReverseGeocode(false) would provide the UI that you truly need and save you money.

PlaceOptions for Place Picker

Besides some of the options listed in the PlaceOptions documentation above, the Place Picker includes options for setting the initial map camera position. This is useful when you want the map location to start at the user's current location.

Was this page helpful?