Skip to content

Commit

Permalink
feat: implement modal to select location and save map state
Browse files Browse the repository at this point in the history
  • Loading branch information
johnshea committed Feb 6, 2024
1 parent e4a1890 commit a17c4fa
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ import android.Manifest
import android.Manifest.permission.ACCESS_COARSE_LOCATION
import android.Manifest.permission.ACCESS_FINE_LOCATION
import android.annotation.SuppressLint
import android.content.DialogInterface
import android.content.pm.PackageManager
import android.os.Bundle
import android.text.method.ScrollingMovementMethod
import android.util.Log
import android.view.View
import android.widget.Button
import android.widget.FrameLayout
import android.widget.TextView
import androidx.annotation.RequiresPermission
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
Expand All @@ -38,7 +38,6 @@ import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.OnMapReadyCallback
import com.google.android.gms.maps.SupportMapFragment
import com.google.android.gms.maps.model.LatLng
import com.google.android.gms.maps.model.Marker
import com.google.android.gms.maps.model.MarkerOptions
import com.google.android.libraries.places.api.Places
import com.google.android.libraries.places.api.model.Place
Expand All @@ -58,10 +57,21 @@ class CurrentPlaceActivity : AppCompatActivity(), OnMapReadyCallback {
private var map: GoogleMap? = null
private val defaultLocation = LatLng(-33.8523341, 151.2106085)

private var likelyPlaceNames = mutableListOf<String>()
private var likelyPlaceAddresses = mutableListOf<String>()
private var likelyPlaceAttributions = mutableListOf<MutableList<String?>?>()
private var likelyPlaceLatLngs = mutableListOf<LatLng>()

private var lastKnownLocation: LatLng? = null

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_current)

if (savedInstanceState != null) {
lastKnownLocation = savedInstanceState.getParcelable(KEY_LOCATION)
}

val apiKey = BuildConfig.PLACES_API_KEY

// Log an error if apiKey is not set.
Expand All @@ -87,6 +97,14 @@ class CurrentPlaceActivity : AppCompatActivity(), OnMapReadyCallback {

}

/**
* Saves the state of the map when the activity is paused.
*/
override fun onSaveInstanceState(outState: Bundle) {
outState.putParcelable(KEY_LOCATION, lastKnownLocation)
super.onSaveInstanceState(outState)
}

/**
* Checks that the user has granted permission for fine or coarse location.
* If granted, finds current Place.
Expand Down Expand Up @@ -171,12 +189,25 @@ class CurrentPlaceActivity : AppCompatActivity(), OnMapReadyCallback {
// Retrieve likely places based on the device's current location
lifecycleScope.launch {
val response = placesClient.awaitFindCurrentPlace(placeFields)
val place = if (!response.placeLikelihoods.isEmpty()) {
response.placeLikelihoods[0].place
} else {
null

val locations = response
.placeLikelihoods
.take(M_MAX_ENTRIES)

likelyPlaceNames.clear()
likelyPlaceAddresses.clear()
likelyPlaceAttributions.clear()
likelyPlaceLatLngs.clear()

for (location in locations) {
likelyPlaceNames.add(location.place.name)
likelyPlaceAddresses.add(location.place.address)
likelyPlaceAttributions.add(location.place.attributions)
likelyPlaceLatLngs.add(location.place.latLng)
}
setPlaceOnMap(place)

openPlacesDialog()

responseView.text = response.prettyPrint()

// Enable scrolling on the long list of likely places
Expand All @@ -190,11 +221,54 @@ class CurrentPlaceActivity : AppCompatActivity(), OnMapReadyCallback {
}
}

/**
* Displays a form allowing the user to select a place from a list of likely places.
*/
private fun openPlacesDialog() {
// Ask the user to choose the place where they are now.
val listener =
DialogInterface.OnClickListener { _, which -> // The "which" argument contains the position of the selected item.
val markerLatLng: LatLng = likelyPlaceLatLngs.get(which)
var markerSnippet: String = likelyPlaceAddresses.get(which)
if (likelyPlaceAttributions.get(which) != null) {
markerSnippet = """
$markerSnippet
${likelyPlaceAttributions.get(which)}
""".trimIndent()
}

lastKnownLocation = markerLatLng

var place = Place.builder().apply {
name = likelyPlaceNames.get(which)
latLng = markerLatLng
}.build()

map!!.clear()

setPlaceOnMap(place, markerSnippet)
}

// Display the dialog.
AlertDialog.Builder(this)
.setTitle(R.string.pick_place)
.setItems(likelyPlaceNames.toTypedArray(), listener)
.show()
}

override fun onMapReady(map: GoogleMap) {
this.map = map
if (lastKnownLocation != null) {
map.moveCamera(
CameraUpdateFactory.newLatLngZoom(
lastKnownLocation!!,
DEFAULT_ZOOM
)
)
}
}

private fun setPlaceOnMap(place: Place?) {
private fun setPlaceOnMap(place: Place?, markerSnippet: String?) {
val latLng = place?.latLng ?: defaultLocation
map?.moveCamera(
CameraUpdateFactory.newLatLngZoom(
Expand All @@ -206,13 +280,20 @@ class CurrentPlaceActivity : AppCompatActivity(), OnMapReadyCallback {
MarkerOptions()
.position(latLng)
.title(place?.name)
.snippet(markerSnippet)
)
}

companion object {
private val TAG = "CurrentPlaceActivity"
private const val PERMISSION_REQUEST_CODE = 9
private const val DEFAULT_ZOOM = 15f

// Key for storing activity state.
private const val KEY_LOCATION = "location"

private const val M_MAX_ENTRIES = 5

}
}

Expand Down
1 change: 1 addition & 0 deletions solution/app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@
<string name="details_input_default">ChIJ-fIL2vnvTxkRaNUY32NGBYs</string>
<string name="current_button">Get Current Place</string>
<string name="showing_most_likely_place">Showing most likely place</string>
<string name="pick_place">Choose a place</string>
</resources>

0 comments on commit a17c4fa

Please sign in to comment.