iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 7
0
Software Development

Kotlin 30 天,通過每天一個小 demo 學習 Android 開發系列 第 7

Kotlin 開發第 7 天 MyLocation (GoogleMap)

MyLocation
這次做一個地圖應用,通過 Google Map 顯示自己的位置以及對應的座標。

功能

  • 在首頁提供一個按鈕,點下去會檢查有沒有使用定位功能的權限。
  • 如果沒有權限,則跳出請求。
  • 如果有權限,則進入 MapsActivity
  • 進入 MapsActivity 取得使用者的 location,將地圖移動並且放大到當前位置。
  • 將使用者的座標顯示在畫面上。

接觸的內容

  • Google Map
  • Location Manager & Permission
  • Intent 跳轉 Activity

通過 IDE 建立 MapActivity

通過在 App 上右鍵的方式建立一個 Activity,點開 Gallery 以後會看到 Google Maps Activity。

IDE 會同時幫我們建立一個 Activity 以及一個對應的 Layout。

https://ithelp.ithome.com.tw/upload/images/20171210/20107329KtIkNLsKw6.png

而 IDE 同時還會建立一個 google_maps_api.xml 文件,這裡面會需要寫上我們的 Google Map 金鑰。

我在 Github 上有看到一些人是將 key 放在 /values/strings/ 底下,又或者在 values 下另外建立文件來使用。

https://ithelp.ithome.com.tw/upload/images/20171210/20107329XlqsD3H1Ga.png

<string name="google_maps_key" templateMergeStrategy="preserve" translatable="false">Your Google API Key</string>

而在 AndroidManifest.xml 文件中,IDE 也幫我們加了一些東西,比如:

        <meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="@string/google_maps_key" />
 
        <activity
            android:name=".MapsActivity"
            android:label="@string/title_activity_maps" />

這裡發現 google_maps_key 又或者 MapsActivity 的 title 都是通過 @string/key 的方式來引用。

<resources>
    <string name="app_name">MyLocation</string>
    <string name="title_activity_maps">Map</string>
    <string name="title_activity_map">Map</string>
</resources>

@string/key 的內容部分是來自下圖中的 strings.xml

https://ithelp.ithome.com.tw/upload/images/20171210/20107329C1nl3sr4Ko.png

通過 Intent 切換 Activity

在 Android 中,可以通過 Intent 來切換 Activity。

val intentMapActivity = Intent(this, MapsActivity::class.java)
startActivity(intentMapActivity)

Permission

這次會用到定位的權限,需要在 AndroidManifest 加入:

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

檢查與請求權限

  • ContextCompat.checkSelfPermission 檢查使用權限。
  • ActivityCompat.requestPermissions - 請求權限。
    在請求使用權限的時候還可以加入一個參數之後用來判斷是哪一種請求。
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
       != PackageManager.PERMISSION_GRANTED){
   ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), MY_PERMISSIONS_REQUEST_LOCATION)
}

請求結果的 Handler

    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray){
        if (requestCode == MY_PERMISSIONS_REQUEST_LOCATION) {

            if (grantResults[0] == PackageManager.PERMISSION_GRANTED){
                showMapsActivity()
            } else {
                Toast.makeText(this, "需要定位功能", Toast.LENGTH_SHORT).show()
            }
        }
    }

LocationManager

我們實例化一個 locationManager 並且嘗試獲取用戶當前位置,並委派一個 locationListener。

        // Create persistent LocationManager reference
        locationManager = getSystemService(LOCATION_SERVICE) as LocationManager?

        try {
            // Request location updates
            locationManager?.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0L, 0f, locationListener)
        } catch(ex: SecurityException) {
            Log.d("myTag", "Security Exception, no location available")
        }

locationListener

在取得座標的時候,將地圖移動到座標所在位置,並且將座標顯示在 locationTextView 上。

    private val locationListener: LocationListener = object : LocationListener {
        override fun onLocationChanged(location: Location) {
            mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(LatLng(location.latitude, location.longitude), 12.0f))
            locationTextView.text = "${location.latitude} - ${location.longitude}"

        }

        override fun onStatusChanged(provider: String, status: Int, extras: Bundle) {}
        override fun onProviderEnabled(provider: String) {}
        override fun onProviderDisabled(provider: String) {}
    }

筆記

  • /src/debug/res/values/google_maps_api.xml 這個文件在 IDE 中,是在哪裡寫了引用?
    以至於 AndroidManifest.xml 可以直接使用?
  • 在 onMapReady() 方法上,IDE建議我加入 @SuppressLint("MissingPermission")
    不知道這個作用是什麼,提示我在 function 中加入權限判斷?

參考


上一篇
Kotlin 開發第 6 天 ImageList (RecyclerView)
下一篇
Kotlin 開發第 8 天 BottomNavigation ( Fragment + Intent)
系列文
Kotlin 30 天,通過每天一個小 demo 學習 Android 開發30

尚未有邦友留言

立即登入留言