FindYourCoffee 專案的需求 :
經過兩天的奮戰,終於解決顯示自定義視窗的問題。雖然 UI 還醜醜的,後續在修改就好!
今天想要完成在開啟 APP 後會直接顯示我的位置,然後接著顯示我的位置附近的咖啡廳。
先到後台打開 Places API 功能
接著在 gradle 加入 Place library :
// Google Play Service
implementation 'com.google.android.gms:play-services-maps:18.1.0'
implementation 'com.google.android.libraries.places:places:3.2.0'
移動到 MainActivity.kt,在 onCreate()
的地方初始化 PlacesClient
以及 FusedLocationProviderClient
:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// ...
// Construct a PlacesClient
Places.initialize(applicationContext, getString(R.string.maps_api_key))
Places.createClient(this)
// Construct a FusedLocationProviderClient.
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)
}
先到 onMapReady()
加入這兩個方法,稍後會補充 :
// Update the map configuration at runtime.
override fun onMapReady(googleMap: GoogleMap) {
// return early if the map was not initialised properly
map = googleMap
// Turn on the My Location layer and the related control on the map.
updateLocationUI()
// Get the current location of the device and set the position of the map.
getDeviceLocation()
}
@SuppressLint("MissingPermission")
private fun updateLocationUI() {
try {
with(map) {
if (permissionDenied) {
isMyLocationEnabled = false
uiSettings?.isMyLocationButtonEnabled = false
lastKnownLocation = null
requestLocationPermissions()
}
else {
// Set the map type
mapType = com.google.android.gms.maps.GoogleMap.MAP_TYPE_NORMAL
// UI 設定 : 交通 、指南針、縮放按鈕
isTrafficEnabled = true
uiSettings.isCompassEnabled = true
uiSettings.isZoomControlsEnabled = true
// 我的位置
isMyLocationEnabled = true
uiSettings.isMyLocationButtonEnabled = true
setOnMyLocationButtonClickListener(this@MainActivity)
setOnMyLocationClickListener(this@MainActivity)
// 設定自定義資訊視窗
val adapter = MainInfoAdapter(layoutInflater)
map.setInfoWindowAdapter(adapter)
}
}
} catch (e: SecurityException) {
Log.e("Exception: %s", e.message, e)
}
}
如果沒取到裝置位置,將標記預設在台北 :
@SuppressLint("MissingPermission")
private fun getDeviceLocation() {
/*
* Get the best and most recent location of the device, which may be null in rare
* cases when a location is not available.
*/
try {
if (!permissionDenied) {
val DEFAULT_ZOOM = 15f
val locationResult = fusedLocationProviderClient.lastLocation
locationResult.addOnCompleteListener(this) { task ->
if (task.isSuccessful) {
// Set the map's camera position to the current location of the device.
lastKnownLocation = task.result
if (lastKnownLocation != null) {
map.moveCamera(
CameraUpdateFactory.newLatLngZoom(
LatLng(lastKnownLocation!!.latitude, lastKnownLocation!!.longitude),
DEFAULT_ZOOM)
)
}
}
else {
Log.d(TAG, "Current location is null. Using defaults.")
Log.e(TAG, "Exception: %s", task.exception)
// 設置預設標記 - 台北
val defaultLocation = LatLng(25.0329694, 121.5654177)
map.moveCamera(CameraUpdateFactory.newLatLngZoom(defaultLocation, DEFAULT_ZOOM))
map.uiSettings.isMyLocationButtonEnabled = false
}
}
}
} catch (e: SecurityException) {
Log.e("Exception: %s", e.message, e)
}
}
現在一打開 APP 就會直接顯示目前的裝置位置,明天在接著顯示附近咖啡廳~~