> For the complete documentation index, see [llms.txt](https://docs.mapbox.com/android/ja/maps/llms.txt)

# User's location on the map

The Mapbox Maps SDK for Android's [location component](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.locationcomponent/) enables your application to observe, respond and display the user's location.

Before you can show the user's location on the map, users must grant your application permission to access their location. See previous section [Permission handling](https://docs.mapbox.com/android/ja/maps/guides/user-location/permissions/) for more details.

## Location component

To visualize the user's location on the map you should enable the location component. There are different ways to enable location:

-   Directly in your `MapView` XML component using the attribute `mapbox_locationComponentEnabled`:

```xml

<com.mapbox.maps.MapView
  android:id="@+id/mapView"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  app:mapbox_locationComponentEnabled="true"
  app:mapbox_locationComponentPuckBearing="heading" />
```

-   Programmatically, by calling [`enabled`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.locationcomponent.generated/-location-component-settings-interface/enabled.html) through the [location component](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.locationcomponent/location.html):

**Android View**

```kotlin

class LocationComponentActivity : AppCompatActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    val mapView = MapView(this)
    setContentView(mapView)
    with(mapView) {
      location.locationPuck = createDefault2DPuck(withBearing = true)
      location.enabled = true
      location.puckBearing = PuckBearing.COURSE
      location.puckBearingEnabled = true
      viewport.transitionTo(
        targetState = viewport.makeFollowPuckViewportState(),
        transition = viewport.makeImmediateViewportTransition()
      )
    }
  }
}
```

**Jetpack Compose**

```kotlin

public class LocationComponentActivity : ComponentActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent {
      val mapViewportState = rememberMapViewportState()
      MapboxMap(
        Modifier.fillMaxSize(),
        mapViewportState = mapViewportState,
      ) {
        MapEffect(Unit) { mapView ->
          mapView.location.updateSettings {
            locationPuck = createDefault2DPuck(withBearing = true)
            enabled = true
            puckBearing = PuckBearing.COURSE
            puckBearingEnabled = true
          }
          mapViewportState.transitionToFollowPuckState()
        }
      }
    }
  }
}
```

The location component makes use of two dedicated layers in the Maps SDK to display either a 2D device location icon (using layer ID [`LOCATION_INDICATOR_LAYER`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.locationcomponent/-location-component-constants/-l-o-c-a-t-i-o-n_-i-n-d-i-c-a-t-o-r_-l-a-y-e-r.html)) or a 3D model (using layer ID [`MODEL_LAYER`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.locationcomponent/-location-component-constants/-m-o-d-e-l_-l-a-y-e-r.html)). These layers are displayed *within* the map rather than on top of the map as an Android view. Layers in Mapbox map styles give you precise control over how you show a device's location on the map.

By default, the Maps SDK for Android provides a two dimensional location puck with a blue dot and white circle.

> **Related content (example): [Show the user's location on the map](https://docs.mapbox.com/android/ja/maps/examples/android-view/location-component/)**
> 
> Show the user's location on a map using the default location puck.

![A screenshot of an Android application displaying the user's location a map.](https://docs.mapbox.com/android/ja/assets/ideal-img/location-component.9c1c6e2.480.png)

### Puck style options

There are several options to customize the appearance of the location puck. You can see the full list at [`LocationComponentSettings`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.locationcomponent.generated/-location-component-settings/).

You can directly use the [`LocationComponentPlugin`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.locationcomponent/-location-component-plugin/) to change the settings. For example, the pulsing effect is disabled by default, but you can enable this effect by passing `true` to the [`pulsingEnabled`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.locationcomponent.generated/-location-component-settings-interface/pulsing-enabled.html) property.

**Android View**

```kotlin

class LocationComponentActivity : AppCompatActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    val mapView = MapView(this)
    setContentView(mapView)
    with(mapView) {
      location.enabled = true
      location.pulsingEnabled = true
    }
  }
}
```

**Jetpack Compose**

```kotlin

public class LocationComponentActivity : ComponentActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent {
      MapboxMap(
        Modifier.fillMaxSize()
      ) {
        MapEffect(Unit) { mapView ->
          mapView.location.updateSettings {
            enabled = true
            location.pulsingEnabled = true
          }
          mapViewportState.transitionToFollowPuckState()
        }
      }
    }
  }
}
```

### Use a custom image

You can further customize the puck by using custom image drawables to display the user's location on a map. Set custom location puck styles in one of two ways: using XML attributes or programmatically using the [`LocationPuck`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin/-location-puck/) class.

Here's an example using style XML attributes to customize the appearance of the location icon:

```xml

<com.mapbox.maps.MapView
    android:id="@+id/mapView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:mapbox_locationComponentEnabled = "true"
    app:mapbox_locationComponentLocationPuck= "location_puck_2_d"
    app:mapbox_locationComponentLocationPuckLocationPuck2DTopImage= "@drawable/custom_user_icon"
    app:mapbox_locationComponentLocationPuckLocationPuck2DBearingImage= "@drawable/custom_user_arrow"
    app:mapbox_locationComponentLocationPuckLocationPuck2DShadowImage= "@drawable/custom_user_puck_icon"
    tools:context=".examples.LocationComponentActivity" />
```

Here's an example using the `LocationPuck` class to programmatically customize the appearance of the location icon. Create a [`LocationPuck2D`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin/-location-puck2-d/) or [`LocationPuck3D`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin/-location-puck3-d/) object and set it through `LocationComponentPlugin#locationPuck` method. The following example also specifies the size of the icon based on the map's zoom level using `scaleExpression`.

**Android View**

```kotlin

class LocationComponentActivity : AppCompatActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    val mapView = MapView(this)
    setContentView(mapView)
    mapView.location.enabled = true
    mapView.location.puckBearingEnabled = true
    mapView.location.locationPuck = LocationPuck2D(
      topImage = ImageHolder.from(R.drawable.mapbox_user_icon), // ImageHolder also accepts Bitmap
      bearingImage = ImageHolder.from(R.drawable.mapbox_user_bearing_icon),
      shadowImage = ImageHolder.from(R.drawable.mapbox_user_stroke_icon),
      scaleExpression = interpolate {
        linear()
        zoom()
        stop {
          literal(0.0)
          literal(0.6)
        }
        stop {
          literal(20.0)
          literal(1.0)
        }
      }.toJson()
    )
  }
}
```

**Jetpack Compose**

```kotlin

public class LocationComponentActivity : ComponentActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent {
      MapboxMap(
        Modifier.fillMaxSize(),
      ) {
        MapEffect(Unit) { mapView ->
          mapView.location.updateSettings {
            enabled = true
            puckBearingEnabled = true
            locationPuck = LocationPuck2D(
              topImage = ImageHolder.from(R.drawable.mapbox_user_icon), // ImageHolder also accepts Bitmap
              bearingImage = ImageHolder.from(R.drawable.mapbox_user_bearing_icon),
              shadowImage = ImageHolder.from(R.drawable.mapbox_user_stroke_icon),
              scaleExpression = interpolate {
                linear()
                zoom()
                stop {
                  literal(0.0)
                  literal(0.6)
                }
                stop {
                  literal(20.0)
                  literal(1.0)
                }
              }.toJson()
            )
          }
        }
      }
    }
  }
}
```

You can revert to the default 2D puck using [`createDefault2DPuck`](https://docs.mapbox.com/android/maps/api/11.0.0/mapbox-maps-android/com.mapbox.maps.plugin.locationcomponent/create-default2-d-puck.html) function.

## Set Puck Bearing Source

The user location can track bearing using the device heading or device course. This option is in [`LocationComponentSettings`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.locationcomponent.generated/-location-component-settings/).

### Example

```kotlin
mapView.location.puckBearing = PuckBearing.HEADING
mapView.location.puckBearing = PuckBearing.COURSE
```

## Location Tracking

To make the camera follow the location puck, you can use [`ViewportPlugin`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.viewport/-viewport-plugin/), which is available at `mapView.viewport`.

`ViewportPlugin` is primarily used to track objects on a map, but it can be extended with custom states and transitions as well.

### Viewport States

[`ViewportState`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.viewport.state/-viewport-state/) produces camera updates based on implementation-specific rules (For example: tracking a dynamic location data source or showing a static overview of a predefined region).

Two `ViewportState` implementations are provided by the SDK, both of which can be instantiated from the `ViewportPlugin`:

-   [`viewport.makeFollowPuckViewportState(options)`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.viewport/-viewport-plugin/make-follow-puck-viewport-state.html): This state syncs the map camera with the location puck.
-   [`viewport.makeOverviewViewportState(options)`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.viewport/-viewport-plugin/make-overview-viewport-state.html): This state makes the camera show a user-provided geometry.

Besides using these built-in implementations, you can also create your own and use them with the `ViewportPlugin`.

### Viewport Transitions

[`ViewportTransition`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.viewport.transition/-viewport-transition/) defines how to transition to a target `ViewportState`.

Two `ViewportTransition` implementations are also provided by the SDK, both of which can be instantiated from the `ViewportPlugin`:

-   [`viewport.makeDefaultViewportTransition(options)`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.viewport/-viewport-plugin/make-default-viewport-transition.html): The default viewport transition uses animations to move the camera to the target state.
-   [`viewport.makeImmediateViewportTransition()`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.viewport/-viewport-plugin/make-immediate-viewport-transition.html): The immediate viewport transition moves the camera to the target state at once without using animations.

Besides using these built-in implementations, you can also create your own and use them with the `ViewportPlugin`.

### Example

**Android View**

```kotlin

class LocationComponentActivity : AppCompatActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    val mapView = MapView(this)
    setContentView(mapView)
    mapView.location.enabled = true
    mapView.location.puckBearingEnabled = true
    val viewportPlugin = mapView.viewport
    // transition to followPuckViewportState with default transition
    val followPuckViewportState: FollowPuckViewportState = viewportPlugin.makeFollowPuckViewportState(
      FollowPuckViewportStateOptions.Builder()
        .bearing(FollowPuckViewportStateBearing.Constant(0.0))
        .padding(EdgeInsets(200.0 * resources.displayMetrics.density, 0.0, 0.0, 0.0))
        .build()
    )
    viewportPlugin.transitionTo(followPuckViewportState) { success ->
      // the transition has been completed with a flag indicating whether the transition succeeded
    }
  }
}
```

**Jetpack Compose**

```kotlin

public class LocationComponentActivity : ComponentActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent {
      val mapViewportState = rememberMapViewportState()
      MapboxMap(
        Modifier.fillMaxSize(),
        mapViewportState = mapViewportState
      ) {
        MapEffect(Unit) { mapView ->
          mapView.location.updateSettings {
            enabled = true
            puckBearingEnabled = true
          }
          // transition to followPuckViewportState with default transition
          mapViewportState.transitionToFollowPuckState(
            followPuckViewportStateOptions = FollowPuckViewportStateOptions.Builder()
              .bearing(FollowPuckViewportStateBearing.Constant(0.0))
              .padding(EdgeInsets(200.0 * resources.displayMetrics.density, 0.0, 0.0, 0.0))
              .build(),
          ) { success ->
            // the transition has been completed with a flag indicating whether the transition succeeded
          }
        }
      }
    }
  }
```

**Android View**

```kotlin

class LocationComponentActivity : AppCompatActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    val mapView = MapView(this)
    setContentView(mapView)
    mapView.location.enabled = true
    mapView.location.puckBearingEnabled = true
    val viewportPlugin = mapView.viewport
    // transition to overviewViewportState with immediate transition
    val overviewViewportState: OverviewViewportState = viewportPlugin.makeOverviewViewportState(
      OverviewViewportStateOptions.Builder()
        .geometry(routePoints)
        .padding(EdgeInsets(100.0, 100.0, 100.0, 100.0))
        .build()
    )
    val immediateTransition = viewportPlugin.makeImmediateViewportTransition()
    viewportPlugin.transitionTo(overviewViewportState, immediateTransition) { success ->
      // the transition has been completed with a flag indicating whether the transition succeeded
    }
  }
}
```

**Jetpack Compose**

```kotlin

public class LocationComponentActivity : ComponentActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent {
      val mapViewportState = rememberMapViewportState()
      MapboxMap(
        Modifier.fillMaxSize(),
        mapViewportState = mapViewportState
      ) {
        MapEffect(Unit) { mapView ->
          mapView.location.updateSettings {
            enabled = true
            puckBearingEnabled = true
          }
          // transition to overviewViewportState with immediate transition
          mapViewportState.transitionToOverviewState(
            overviewViewportStateOptions = OverviewViewportStateOptions.Builder()
              .geometry(routePoints)
              .padding(EdgeInsets(100.0, 100.0, 100.0, 100.0))
              .build(),
            defaultTransitionOptions = DefaultViewportTransitionOptions.Builder().maxDurationMs(0)
              .build()
          ) { success ->
            // the transition has been completed with a flag indicating whether the transition succeeded
          }
        }
      }
    }
  }
}
```

## Location provider

The [`LocationProvider`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.locationcomponent/-location-provider/) is an interface of Mapbox Maps SDK, to provide location updates to the [`LocationComponentPlugin`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.locationcomponent/-location-component-plugin/). The current location provider used in the location component can be accessed by calling [`getLocationProvider()`](https://docs.mapbox.com/android/maps/api/11.0.0/mapbox-maps-android/com.mapbox.maps.plugin.locationcomponent/-location-component-plugin/get-location-provider.html).

You can register your own [`LocationConsumer`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.locationcomponent/-location-consumer/) to process the same locations used for rendering the location puck on the map. If you need access to the raw device's location, see [`Accessing device location`](https://docs.mapbox.com/android/ja/maps/guides/user-location/device-location/).

> **Note: Use Google's Fused Location Provider**
> 
> The Maps SDK also comes pre-compiled with support for the [Google's Fused Location Provider](https://developers.google.com/location-context/fused-location-provider). If your target devices support Google Play Services, add the [Google Play Location Services](https://developers.google.com/android/guides/setup) dependency to your project, and the Maps SDK will use the Google's Fused Location Provider in your application automatically:`implementation("com.google.android.gms:play-services-location:21.0.1")`

### Use a custom location provider

You can also provide your own [`LocationProvider`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.locationcomponent/-location-provider/) to use with `LocationComponentPlugin`. Use the[`setLocationProvider(locationProvider: LocationProvider)`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.locationcomponent/-location-component-plugin/set-location-provider.html) API to replace the default implementation.