2024. 5. 2. 18:10, ๐ฑAndroid Study
๋ฐ์ํ
1) ์์น ์ ๊ทผ ๊ถํ
์ฌ์ฉ์์ ์์น๋ฅผ ์ถ์ ํ๊ธฐ ์ํ 3๊ฐ์ง ๊ถํ
- android.permission.ACCESS_COARSE_LOCATION
- ์์ดํ์ด๋ ๋ชจ๋ฐ์ผ ๋ฐ์ดํฐ(๋๋ ๋ ๋ค)๋ฅผ ์ฌ์ฉํด ๊ธฐ๊ธฐ์ ์์น์ ์ ๊ทผํ๋ ๊ถํ
- ๋์์์ 1๋ธ๋ก ์ ๋์ ์ค์ฐจ ์์ค - android.permission.ACCESS_FINE_LOCATION
- ์์ฑ, ์์ดํ์ด, ๋ชจ๋ฐ์ผ ๋ฐ์ดํฐ ๋ฑ ์ด์ฉํ ์ ์๋ ์์น ์ ๊ณต์๋ฅผ ์ฌ์ฉํด ์ต๋ํ ์ ํํ ์์น์ ์ ๊ทผํ๋ ๊ถํ - android.permission.ACCESS_BACKGROUND_LOCATION
- ์๋๋ก์ด๋ 10(API ๋ ๋ฒจ 29) ์ด์์์ ๋ฐฑ๊ทธ๋ผ์ด๋ ์ํ์์ ์์น์ ์ ๊ทผํ๋ ๊ถํ
์๋๋ก์ด๋ ๊ถํ ์ค์ ๋ฐ ํ๋ ๋ฐฉ๋ฒ
1. ๋งค๋ํ์คํธ์ ๊ถํ ์ถ๊ฐ
<manifest ... >
<!-- Always include this permission -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- Include only if your app benefits from precise location access. -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
</manifest>
- ์ฑ์ด ์์น ์ ๋ณด์ ์ ๊ทผํ๋ ค๋ฉด, ๋จผ์ AndroidManifest.xml ํ์ผ์ ์์น ๊ถํ์ ์ถ๊ฐํด์ผ ํจ
2. ๊ถํ ์์ฒญ
class MainActivity : AppCompatActivity() {
companion object {
private const val PERMISSION_REQUEST_ACCESS_FINE_LOCATION = 100
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
requestLocationPermission()
}
private fun requestLocationPermission() {
if (ContextCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED
) {
// ๊ถํ์ด ์์ ๊ฒฝ์ฐ, ์ฌ์ฉ์์๊ฒ ์์ฒญ
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
PERMISSION_REQUEST_ACCESS_FINE_LOCATION
)
} else {
// ๊ถํ์ด ์ด๋ฏธ ์์ ๊ฒฝ์ฐ, ์์น ์ ๋ณด๋ฅผ ์ฌ์ฉํ ์ ์์
getLocation()
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<String>,
grantResults: IntArray
) {
when (requestCode) {
PERMISSION_REQUEST_ACCESS_FINE_LOCATION -> {
if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
// ๊ถํ์ด ๋ถ์ฌ๋๋ฉด ์์น ์ ๋ณด๋ฅผ ์ฌ์ฉํ ์ ์์
getLocation()
} else {
// ๊ถํ์ด ๊ฑฐ๋ถ๋๋ฉด, ๊ธฐ๋ฅ ์ฌ์ฉ ๋ถ๊ฐ
}
return
}
}
}
private fun getLocation
- ๋ฐํ์ ์, ์ฑ์ ์ฌ์ฉ์์๊ฒ ๊ถํ์ ์์ฒญํด์ผ ํจ
์๋๋ก์ด๋ 6.0(API ๋ ๋ฒจ 23) ์ด์์์๋ ์ฌ์ฉ์๊ฐ ์ฑ์ ์ฌ์ฉํ๋ ๋์ ๊ถํ์ ๋ถ์ฌํ๊ฑฐ๋ ์ทจ์ํ ์ ์์ - ์์ ์ฝ๋๋ ACCESS_FINE_LOCATION ๊ถํ์ ์์ฒญํ๊ณ ํ๋ํ๋ ์์ ์ฝ๋
- ์ ์ฝ๋์์ requestLocationPermission ํจ์๋ ๋จผ์ ์ฑ์ ์์น ๊ถํ์ด ์๋์ง ํ์ธ
๊ถํ์ด ์๋ค๋ฉด ActivityCompat.requestPermissions ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ๊ถํ์ ์์ฒญํ๊ณ ,
๊ฒฐ๊ณผ๋ onRequestPermissionsResult ์ฝ๋ฐฑ ๋ฉ์๋์์ ์ฒ๋ฆฌ
์ฌ์ฉ์๊ฐ ๊ถํ์ ๋ถ์ฌํ๋ฉด getLocation ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ์์น ์ ๋ณด๋ฅผ ์ฌ์ฉํ ์ ์์
2) ํ๋ซํผ API์ ์์น ๋งค๋์
→ ์๋๋ก์ด๋ ๋จ๋ง ๋ด๋ถ์์ ์์น ์ ๋ณด๋ฅผ ์ป๋ ๋ฐฉ๋ฒ
val manager = getSystemService(LOCATION_SERVICE) as LocationManager
- ์ฌ์ฉ์์ ์์น๋ฅผ ์ป์ ๋๋ LocationManager๋ผ๋ ์์คํ ์๋น์ค๋ฅผ ์ด์ฉ
var result = "All Providers : "
val providers = manager.allProviders
for (provider in providers) {
result += " $provider. "
}
Log.d("maptest", result) // All Providers : passive, gps, network..
- ์์น ์ ๊ณต์ ์ง์ ํ๊ธฐ
- GPS: GPS ์์ฑ์ ์ด์ฉ
- Network: ์ด๋ ํต์ ๋ง์ ์ด์ฉ
- Wifi: ์์ดํ์ด๋ฅผ ์ด์ฉ
- Passive: ๋ค๋ฅธ ์ฑ์์ ์ด์ฉํ ๋ง์ง๋ง ์์น ์ ๋ณด๋ฅผ ์ด์ฉ - ํ์ฌ ๊ธฐ๊ธฐ์ ์ด๋ค ์์น ์ ๊ณต์๊ฐ ์๋์ง๋ฅผ ์๊ณ ์ถ๋ค๋ฉด LocationManager์ allProviders ํ๋กํผํฐ๋ฅผ ์ด์ฉ
result = "Enabled Providers : "
val enabledProviders = manager.getProviders(true)
for (provider in enabledProviders) {
result += " $provider. "
}
Log.d("maptest", result) // Enabled Providers : passive, gps, network..
- ์ง๊ธ ์ฌ์ฉํ ์ ์๋ ์์น ์ ๊ณต์๋ฅผ ์์๋ณด๋ ค๋ฉด getProviders() ํจ์๋ฅผ ์ด์ฉ
if (ContextCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_FINE_LOCATION
) == PackageManager.PERMISSION_GRANTED
) {
val location: Location? = manager.getLastKnownLocation(LocationManager.GPS_PROVIDER)
location?.let{
val latitude = location.latitude
val longitude = location.longitude
val accuracy = location.accuracy
val time = location.time
Log.d("map_test", "$latitude, $location, $accuracy, $time")
}
}
- ์์น์ ๋ณด์ป๊ธฐ
- LocationManager์ getLastKnownLocation() ํจ์๋ฅผ ์ด์ฉ
- Location์ ์์น์ ์ ํ๋, ์๋, ๊ฒฝ๋, ํ๋ ์๊ฐ ๋ฑ์ ๋ฐ์ดํฐ๋ฅผ ํฌํจ
- getAccuracy(): ์ ํ๋
- getLatitude(): ์๋
- getLongitude(): ๊ฒฝ๋
- getTime(): ํ๋ ์๊ฐ
val listener: LocationListener = object : LocationListener {
override fun onLocationChanged(location: Location) {
Log.d("map_test,","${location.latitude}, ${location.longitude}, ${location.accuracy}")
}
}
manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10_000L, 10f, listener)
// (.. ์๋ต ..) //
manager.removeUpdates(listener)
- ๊ณ์ ์์น๋ฅผ ๊ฐ์ ธ์์ผ ํ๋ค๋ฉด LocationListener๋ฅผ ์ด์ฉ
- onLocationChanged(): ์๋ก์ด ์์น๋ฅผ ๊ฐ์ ธ์ค๋ฉด ํธ์ถ
- onProviderEnabled(): ์์น ์ ๊ณต์๊ฐ ์ด์ฉํ ์ ์๋ ์ํฉ์ด๋ฉด ํธ์ถ
- onProviderDisabled(): ์์น ์ ๊ณต์๊ฐ ์ด์ฉํ ์ ์๋ ์ํฉ์ด๋ฉด ํธ์ถ
3) ๊ตฌ๊ธ Play ์๋น์ค์ ์์น ๋ผ์ด๋ธ๋ฌ๋ฆฌ
→ ์ฌ์ค 2๋ฒ๋ณด๋ค ์ด๊ฒ ๋ ํธํ๊ณ ์ ํ๋๊ฐ ๋์
// ๊ตฌ๊ธ play ์๋น์ค ์ฌ์ฉ ์ ์ธ : Gradle ํ์ผ์ ์
๋ ฅ
implementation 'com.google.android.gms:play-services:12.0.1'
- ์์น ์ ๊ณต์๋ฅผ ์ง์ ํ ๋ ๊ณ ๋ คํ ์ฌํญ
- ์ ๋ ฅ์ ์ ๊ฒ ์๋นํ๋๊ฐ?
- ์ ํ๋๋ ๋์๊ฐ?
- API๊ฐ ๊ฐ๋จํ๊ฐ?
- ๋ถ๊ฐ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋๊ฐ?
- ๋๋ถ๋ถ ์๋๋ก์ด๋ ๊ธฐ๊ธฐ๋ฅผ ์ง์ํ๋๊ฐ?
๋ฐ๋ผ์ ๊ตฌ๊ธํ๋ ์ด์ ์์น ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ - ๊ตฌ๊ธ์์๋ ์ต์ ์ ์๊ณ ๋ฆฌ์ฆ์ผ๋ก ์์น ์ ๊ณต์๋ฅผ ์ง์ ํ ์ ์๋๋ก Fused Location Provider๋ผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ ๊ณต
// ๊ตฌ๊ธ api ํด๋ผ์ด์ธํธ ์ด๊ธฐํ
val connectionCallback = object: GoogleApiClient.ConnectionCallbacks{
override fun onConnected(p0: Bundle?) {
// ์์น ์ ๊ณต์๋ฅผ ์ฌ์ฉํ ์ ์์ ๋
// ์์น ํ๋
}
override fun onConnectionSuspended(p0: Int) {
// ์์น ์ ๊ณต์๋ฅผ ์ฌ์ฉํ ์ ์์ ๋
}
}
val onConnectionFailCallback = object : GoogleApiClient.OnConnectionFailedListener{
override fun onConnectionFailed(p0: ConnectionResult) {
// ์ฌ์ฉํ ์ ์๋ ์์น ์ ๊ณต์๊ฐ ์์ ๋
}
}
val apiClient = GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(connectionCallback)
.addOnConnectionFailedListener(onConnectionFailCallback)
.build()
- Fused Location Provider์์ ํต์ฌ ํด๋์ค
- FusedLocationProviderClient: ์์น ์ ๋ณด๋ฅผ ์ป์
- GoogleApiClient: ์์น ์ ๊ณต์ ์ค๋น ๋ฑ ๋ค์ํ ์ฝ๋ฐฑ์ ์ ๊ณต - GoogleApi Client์์๋ GoogleApiClient.ConnectionCallbacks์
GoogleApiClient.OnConnection FailedListener ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ ๊ฐ์ฒด๋ฅผ ์ง์
val providerClient = LocationServices.getFusedLocationProviderClient(this)
- FusedLocationProviderClient ์ด๊ธฐํ
apiClient.connect()
- GoogleApiClient ๊ฐ์ฒด์ ์์น ์ ๊ณต์๋ฅผ ์์ฒญ
// ์์น ์ ๊ณต์๋ฅผ ์ฌ์ฉํ ์ ์๋ ์ํฉ์ผ ๋
override fun onConnected(p0: Bundle?) {
if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) === PackageManager.PERMISSION_GRANTED){
providerClient.lastLocation.addOnSuccessListener(
this@MainActivity,
object: OnSuccessListener<Location> {
override fun onSuccess(p0: Location?) {
p0?.let {
val latitude = p0.latitude
val longitude = p0.longitude
Log.d("map_test", "$latitude, $longitude")
}
}
}
)
apiClient.disconnect()
}
}
- onConnected() ํจ์์์ FusedLocationProviderClient์ getLastLocation() ํจ์ ํธ์ถ
๋ฐ์ํ
๐ฌ C O M M E N T