From Permissions to Sessions: Rethinking Location Access in Android 17

Image generated using Gemini

In this article, we will learn how to implement the new 📍Location button introduced in Android 17 in Jetpack Compose-based Android applications.

Android 17 adds a system-rendered 📍Location Button that we can drop into the layout via a Jetpack library, and tapping it gives the app precise location for that session only, gated by a new USE_LOCATION_BUTTON permission.

What the feature is

  • Android now exposes a system-owned, standard location button that we can embed in our UI instead of designing a custom control.
  • When the user taps it, the system handles the permission flow, then grants the app precise location for the current session only, rather than long‑lived access.

How it changes permissions

  • Instead of immediately requesting ACCESS_FINE_LOCATION (and maybe ACCESS_COARSE_LOCATION) at runtime, we declare the new USE_LOCATION_BUTTON permission to host the button.
<!-- Standard Coarse and Fine Location Permissions + onlyForLocationButton -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

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

<!-- Required system permission for rendering the LocationButton -->
<uses-permission android:name="android.permission.USE_LOCATION_BUTTON" />

Developer benefits

  • Less custom permission boilerplate: We lean on system UX and the Jetpack library for the hardest parts of location consent.
[versions]

locationbuttonCompose = "1.0.0-alpha01"

[libraries]
androidx-locationbutton-compose = { group = "androidx.core.locationbutton",
name = "locationbutton-compose",
version.ref = "locationbuttonCompose" }
  • Higher trust and clarity for users: the control looks and behaves consistently across apps, and session-only precise access is easier to understand than broader access.

Implementation

  • As we all know, Android development is now Compose-first, so we will implement it using the LocationButton composable provided by the library.
https://android-developers.googleblog.com/2026/05/android-ui-development-is-compose-first.html

Add the dependency

  • Add the following code to the libs.versions.toml
[versions]

locationbuttonCompose = "1.0.0-alpha01"

[libraries]
androidx-locationbutton-compose = { group = "androidx.core.locationbutton",
name = "locationbutton-compose",
version.ref = "locationbuttonCompose" }
  • Add the dependency to the build.gradle.kts
dependencies {
//...

implementation(libs.androidx.locationbutton.compose)

//...
  • Add the permissions to the AndroidManifest.xml
<!-- Standard Coarse and Fine Location Permissions + onlyForLocationButton -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

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

<!-- Required system permission for rendering the LocationButton -->
<uses-permission android:name="android.permission.USE_LOCATION_BUTTON" />

Add the LocationButton to the UI

Android Cinnamon Bun(API 37) and later: Uses remote rendering by the system as the primary method to display the button.

Pre-Cinnamon Bun(≤ api36) (or on failure): Falls back to a local Compose implementation if the platform version is older or if remote rendering fails.

@Composable
fun LocationPermissionScreen(onPermissionGranted: () -> Unit, onPermissionDenied: () -> Unit) {

// Renders the secure system-trusted Location Button composable
LocationButton(
// Callback triggered when the user taps the button and
// makes a decision on the permission dialog
onPermissionResult = { isGranted ->
if (isGranted) {
onPermissionGranted()
} else {
onPermissionDenied()
}
},
)
}
Screenshot — LocationButton composable

Customizing the Location Button UI

  • To match our app’s unique branding, the Location Button offers extensive customization options.

We can modify the following visual styles:

  • Color scheme: Adjust both the background and icon colors.
  • Outline style: Customize border thickness and visibility.
  • Size and shape: Scale the button and alter its corner radius.
@Composable
fun LocationPermissionScreen( //..
LocationButton(
onPermissionResult = { isGranted ->
if (isGranted) {
onPermissionGranted()
} else {
onPermissionDenied()
}
},
backgroundColor = Color(0xFF3D0079),
textColor = Color.White,
iconTint = Color(0xFFF707FF)
)
}
Screenshot — Customized LocationButton

Custom stroke and cornerRadius

@Composable
fun LocationPermissionScreen(onPermissionGranted: () -> Unit, onPermissionDenied: () -> Unit) {

LocationButton(
onPermissionResult = { isGranted ->
if (isGranted) {
onPermissionGranted()
} else {
onPermissionDenied()
}
},

strokeColor = Color(0xFF29004D),
strokeWidth = 2.dp,
cornerRadius = 32.dp,
pressedCornerRadius = 12.dp,
)

}
Demo — custom stroke and radius

Demo

Demo — Full flow!

References


From Permissions to Sessions: Rethinking Location Access in Android 17 was originally published in ProAndroidDev on Medium, where people are continuing the conversation by highlighting and responding to this story.