iT邦幫忙

2023 iThome 鐵人賽

DAY 28
0
Kotlin

喝咖啡要30天?一起用 Kotlin 打造尋找好喝咖啡的 App系列 第 28

Day28 在 Google 地圖上顯示全台咖啡廳資訊 - 6 顯示我的位置附近的咖啡廳(上)

  • 分享至 

  • xImage
  •  

FindYourCoffee 專案的需求 :

  • [x] 點擊地圖標記顯示商家資訊
  • [x] 顯示我的位置
  • [x] 在地圖上顯示咖啡廳標記
  • [x] 點擊地圖標記顯示咖啡廳資訊
  • [ ] 顯示我的位置附近的咖啡廳資訊
  • [ ] 加入篩選功能

經過兩天的奮戰,終於解決顯示自定義視窗的問題。雖然 UI 還醜醜的,後續在修改就好!

今天想要完成在開啟 APP 後會直接顯示我的位置,然後接著顯示我的位置附近的咖啡廳。

啟用 Location API

先到後台打開 Places API 功能

d28_1.png

接著在 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'

初始化 Location

移動到 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()
}

更新地圖畫面 updateLocationUI

@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)
    }
}

取得裝置的目前位置 getDeviceLocation

如果沒取到裝置位置,將標記預設在台北 :

@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)
    }
}

執行結果

d28_2.png

現在一打開 APP 就會直接顯示目前的裝置位置,明天在接著顯示附近咖啡廳~~

今日推推

Yes


上一篇
Day27 在 Google 地圖上顯示全台咖啡廳資訊 - 5 二戰客製化資訊視窗
下一篇
Day29 在 Google 地圖上顯示全台咖啡廳資訊 - 6 顯示我的位置附近的咖啡廳(下)
系列文
喝咖啡要30天?一起用 Kotlin 打造尋找好喝咖啡的 App30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言