Jetpack Compose Google Places Show Nearby Places

Setup Google Places.

ViewModel

  • I am using Hilt Dependency Injection to inject application context into ViewModel.
  • I store GOOGLE_PLACES_API_KEY via gradle.
import com.google.android.libraries.places.api.model.Place as GooglePlaceclass SelectPlaceViewModel(@ApplicationContext applicationContext: Context) : ViewModel() {    init {        Places.initialize(context, BuildConfig.GOOGLE_PLACES_API_KEY)    }    private val placesClient by lazy {  Places.createClient(applicationContext) }    private val DEFAULT_PLACE_FIELDS = listOf(        GooglePlace.Field.ID,        GooglePlace.Field.NAME,        GooglePlace.Field.ADDRESS,        // GooglePlace.Field.ADDRESS_COMPONENTS, // not supported in placesClient.findCurrentPlace        GooglePlace.Field.TYPES,        GooglePlace.Field.LAT_LNG,        GooglePlace.Field.VIEWPORT,        GooglePlace.Field.ICON_URL    )    @SuppressWarnings("MissingPermission")    suspend fun findCurrentPlaces(): List<GooglePlace> {        val fields = DEFAULT_PLACE_FIELDS        val request: FindCurrentPlaceRequest = FindCurrentPlaceRequest.newInstance(fields)        val placeResponse: FindCurrentPlaceResponse = placesClient.findCurrentPlace(request).await()        return placeResponse.placeLikelihoods.map { placeLikelihood ->            val place: GooglePlace = placeLikelihood.place            place        }    }}

Composable

@Composablefun SelectPlaceScreen(viewModel: SelectPlaceViewModel = viewModel()) {    val context = LocalContext.current    var gplaces by remember { mutableStateOf<List<GooglePlace>>( emptyList()) }        LaunchedEffect(true) {        gplaces = viewModel.findCurrentPlaces()        // showBusy = false    }    RequireLocationPermission(navigateToSettingsScreen = {        context.startActivity(            Intent(                Settings.ACTION_APPLICATION_DETAILS_SETTINGS,                Uri.fromParts("package", context.packageName, null)            )        )    }) {        LazyColumn() {            items(gplaces) { place ->                Row {                    Icon(                        modifier = Modifier                            .padding(4.dp)                            .size(24.dp),                        // painter = painterResource(icon),                        painter = rememberImagePainter(place.iconUrl!!),                        contentDescription = "")                    Column {                        Text(place.name ?: "NA", style = MaterialTheme.typography.subtitle1)                        CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.medium) {                            Text(place.address ?: "", style = MaterialTheme.typography.body2)                        }                    }                }                Divider(color = MaterialTheme.colors.onSurface.copy(alpha = 0.2f))            }        }    }}

❤️ Is this article helpful?

Buy me a coffee ☕ or support my work via PayPal to keep this space 🖖 and ad-free.

Do send some 💖 to @d_luaz or share this article.

✨ By Desmond Lua

A dream boy who enjoys making apps, travelling and making youtube videos. Follow me on @d_luaz

👶 Apps I built

Travelopy - discover travel places in Malaysia, Singapore, Taiwan, Japan.