บทนำ
ตัวอย่างนี้แสดงวิธีใช้ FusedLocationProviderClient (Google Play Services Location API) เพื่อดึงตำแหน่งปัจจุบันและแสดงบน Google Maps
ขั้นตอนที่ 1: สร้างโปรเจกต์
สร้างโปรเจกต์ Android ใหม่ เลือก Template "Google Maps Activity" หรือเพิ่ม Dependencies เอง
ขั้นตอนที่ 2: Dependencies (build.gradle)
dependencies {
implementation 'com.google.android.gms:play-services-maps:18.2.0'
implementation 'com.google.android.gms:play-services-location:21.0.1'
}
ขั้นตอนที่ 3: Layout (activity_maps.xml)
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:tools="https://schemas.android.com/tools"
android:id="@+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MapsActivity" />
ขั้นตอนที่ 4: MapsActivity.kt
import android.Manifest
import android.content.pm.PackageManager
import android.location.Location
import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import com.google.android.gms.location.FusedLocationProviderClient
import com.google.android.gms.location.LocationServices
import com.google.android.gms.location.Priority
import com.google.android.gms.maps.CameraUpdateFactory
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.MarkerOptions
import com.google.android.gms.tasks.CancellationTokenSource
class MapsActivity : AppCompatActivity(), OnMapReadyCallback {
private lateinit var mMap: GoogleMap
private lateinit var fusedLocationClient: FusedLocationProviderClient
private val permissionRequestCode = 1001
private val cancellationTokenSource = CancellationTokenSource()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_maps)
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
val mapFragment = supportFragmentManager
.findFragmentById(R.id.map) as SupportMapFragment
mapFragment.getMapAsync(this)
}
override fun onMapReady(googleMap: GoogleMap) {
mMap = googleMap
mMap.uiSettings.isMyLocationButtonEnabled = true
mMap.uiSettings.isCompassEnabled = true
enableMyLocation()
}
private fun enableMyLocation() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), permissionRequestCode)
return
}
mMap.isMyLocationEnabled = true
getCurrentLocation()
}
private fun getCurrentLocation() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) return
// ใช้ getCurrentLocation() แทน lastLocation (Deprecated ใน API ใหม่)
fusedLocationClient.getCurrentLocation(Priority.PRIORITY_HIGH_ACCURACY, cancellationTokenSource.token)
.addOnSuccessListener { location: Location? ->
location?.let {
val currentLatLng = LatLng(it.latitude, it.longitude)
mMap.addMarker(MarkerOptions()
.position(currentLatLng)
.title("My Current Location")
.snippet("Lat: ${it.latitude}, Lng: ${it.longitude}"))
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(currentLatLng, 15f))
Toast.makeText(this, "Location found!", Toast.LENGTH_SHORT).show()
} ?: run {
Toast.makeText(this, "Location unavailable", Toast.LENGTH_SHORT).show()
}
}
.addOnFailureListener { e ->
Toast.makeText(this, "Error: ${e.message}", Toast.LENGTH_SHORT).show()
}
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == permissionRequestCode && grantResults.isNotEmpty()
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
enableMyLocation()
} else {
Toast.makeText(this, "Location permission required", Toast.LENGTH_LONG).show()
}
}
override fun onDestroy() {
super.onDestroy()
cancellationTokenSource.cancel()
}
}
ขั้นตอนที่ 5: ขอ Google Maps API Key
- เข้า Google Cloud Console
- เปิดใช้งาน Maps SDK for Android และ Places API (ถ้าต้องการ)
- สร้าง API Key → จำกัดด้วย Package name + SHA-1
ขั้นตอนที่ 6: Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="com.example.locationdemo">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="YOUR_API_KEY_HERE" />
<activity android:name=".MapsActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Location Priority Options
| Priority | ความแม่นยำ | การใช้พลังงาน | เหมาะสำหรับ |
|---|---|---|---|
PRIORITY_HIGH_ACCURACY | ~10 เมตร (GPS) | สูง | Navigation, Tracking |
PRIORITY_BALANCED_POWER_ACCURACY | ~100 เมตร (WiFi/Cell) | ปานกลาง | General use |
PRIORITY_LOW_POWER | ~10 กม. (Cell tower) | ต่ำ | Weather, Regional info |
PRIORITY_NO_POWER | Passive (รับจากแอปอื่น) | ไม่ใช้เพิ่ม | Background monitoring |
Location Updates แบบต่อเนื่อง (Real-time Tracking)
val locationRequest = LocationRequest.create().apply {
interval = 5000 // 5 วินาที
fastestInterval = 2000
priority = Priority.PRIORITY_HIGH_ACCURACY
}
val locationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult) {
locationResult.lastLocation?.let { location ->
// อัปเดต Marker, Camera
val latLng = LatLng(location.latitude, location.longitude)
// ...
}
}
}
fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper())
// หยุดเมื่อไม่ใช้
fusedLocationClient.removeLocationUpdates(locationCallback)