Skip to content

Commit 4e940cd

Browse files
committed
Feat: Add LocationService for fetching current location
This commit introduces a new `LocationService` class responsible for handling location-related operations. - It provides a `hasLocationPermission()` method to check for fine or coarse location permissions. - It includes a suspend function `getCurrentLocation()` that uses the `FusedLocationProviderClient` to fetch the current location with high accuracy. This function leverages `suspendCancellableCoroutine` for proper coroutine cancellation and handles potential `SecurityException` if permissions are not granted. - The `LocationService` is annotated with `@Singleton` and `@Inject` for dependency injection.
1 parent b8f3525 commit 4e940cd

File tree

1 file changed

+65
-0
lines changed

1 file changed

+65
-0
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package com.warbler.utilities
2+
3+
import android.Manifest
4+
import android.content.Context
5+
import android.content.pm.PackageManager
6+
import android.location.Location
7+
import androidx.core.app.ActivityCompat
8+
import com.google.android.gms.location.FusedLocationProviderClient
9+
import com.google.android.gms.location.LocationServices
10+
import com.google.android.gms.location.Priority
11+
import com.google.android.gms.tasks.CancellationTokenSource
12+
import kotlinx.coroutines.suspendCancellableCoroutine
13+
import javax.inject.Inject
14+
import javax.inject.Singleton
15+
import kotlin.coroutines.resume
16+
import kotlin.coroutines.resumeWithException
17+
18+
@Singleton
19+
class LocationService
20+
@Inject
21+
constructor(
22+
private val context: Context,
23+
) {
24+
private val fusedLocationClient: FusedLocationProviderClient by lazy {
25+
LocationServices.getFusedLocationProviderClient(context)
26+
}
27+
28+
fun hasLocationPermission(): Boolean =
29+
ActivityCompat.checkSelfPermission(
30+
context,
31+
Manifest.permission.ACCESS_FINE_LOCATION,
32+
) == PackageManager.PERMISSION_GRANTED ||
33+
ActivityCompat.checkSelfPermission(
34+
context,
35+
Manifest.permission.ACCESS_COARSE_LOCATION,
36+
) == PackageManager.PERMISSION_GRANTED
37+
38+
suspend fun getCurrentLocation(): Location? =
39+
suspendCancellableCoroutine { continuation ->
40+
if (!hasLocationPermission()) {
41+
continuation.resumeWithException(SecurityException("Location permission not granted"))
42+
return@suspendCancellableCoroutine
43+
}
44+
45+
val cancellationTokenSource = CancellationTokenSource()
46+
47+
continuation.invokeOnCancellation {
48+
cancellationTokenSource.cancel()
49+
}
50+
51+
try {
52+
fusedLocationClient
53+
.getCurrentLocation(
54+
Priority.PRIORITY_HIGH_ACCURACY,
55+
cancellationTokenSource.token,
56+
).addOnSuccessListener { location ->
57+
continuation.resume(location)
58+
}.addOnFailureListener { exception ->
59+
continuation.resumeWithException(exception)
60+
}
61+
} catch (e: SecurityException) {
62+
continuation.resumeWithException(e)
63+
}
64+
}
65+
}

0 commit comments

Comments
 (0)