Skip to content

Commit b51f2ed

Browse files
committed
Implement api service
- `FourSquare API` - `Location API` - getCurrentLocation - Permission handling
1 parent 1ce9c71 commit b51f2ed

File tree

10 files changed

+398
-54
lines changed

10 files changed

+398
-54
lines changed

app/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ dependencies {
8282
// google-maps
8383
implementation "com.google.maps.android:maps-compose:1.0.0"
8484
implementation "com.google.android.gms:play-services-maps:18.0.2"
85+
implementation 'com.google.android.gms:play-services-location:19.0.1'
8586

8687
// retrofit
8788
implementation "com.squareup.retrofit2:retrofit:2.9.0"

app/src/main/AndroidManifest.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
package="com.adyen.android.assignment">
44

55
<uses-permission android:name="android.permission.INTERNET" />
6+
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
7+
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
8+
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
9+
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
610

711
<application
812
android:name=".AdyenApplication"

app/src/main/java/com/adyen/android/assignment/screens/MainActivity.kt

Lines changed: 121 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,57 @@
11
package com.adyen.android.assignment.screens
22

3+
import android.Manifest
4+
import android.annotation.SuppressLint
5+
import android.content.pm.PackageManager
6+
import android.location.Location
37
import android.os.Build
48
import android.os.Bundle
5-
import android.os.StrictMode
6-
import android.os.StrictMode.ThreadPolicy
9+
import android.util.Log
710
import androidx.activity.ComponentActivity
811
import androidx.activity.compose.setContent
12+
import androidx.activity.viewModels
13+
import androidx.annotation.RequiresApi
914
import androidx.compose.foundation.layout.fillMaxSize
1015
import androidx.compose.material.MaterialTheme
1116
import androidx.compose.material.Surface
1217
import androidx.compose.ui.Modifier
1318
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
1419
import androidx.lifecycle.lifecycleScope
20+
import com.adyen.android.assignment.model.request.LocationRequestModel
1521
import com.adyen.android.assignment.screens.home.view.HomeScreen
22+
import com.adyen.android.assignment.screens.home.viewmodel.HomeViewModel
23+
import com.adyen.android.assignment.screens.permission.types.LocationPermissionTypes
24+
import com.adyen.android.assignment.screens.permission.viewmodel.PermissionViewModel
1625
import com.adyen.android.assignment.ui.theme.AdyenApplicationTheme
26+
import com.adyen.android.assignment.utils.Constant.REQUEST_FINE_LOCATION_PERMISSIONS_REQUEST_CODE
27+
import com.adyen.android.assignment.utils.hasPermission
28+
import com.adyen.android.assignment.utils.requestPermissionWithRationale
29+
import com.google.android.gms.location.FusedLocationProviderClient
30+
import com.google.android.gms.location.LocationRequest
31+
import com.google.android.gms.location.LocationServices
32+
import com.google.android.gms.tasks.CancellationTokenSource
33+
import com.google.android.gms.tasks.Task
1734
import dagger.hilt.android.AndroidEntryPoint
1835
import kotlinx.coroutines.delay
19-
36+
import timber.log.Timber
2037

2138
@AndroidEntryPoint
2239
class MainActivity : ComponentActivity() {
2340

41+
private val permissionViewModel: PermissionViewModel by viewModels()
42+
private val homeViewModel: HomeViewModel by viewModels()
43+
44+
private val fusedLocationClient: FusedLocationProviderClient by lazy {
45+
LocationServices.getFusedLocationProviderClient(applicationContext)
46+
}
47+
48+
private var cancellationTokenSource = CancellationTokenSource()
49+
50+
@RequiresApi(Build.VERSION_CODES.M)
2451
override fun onCreate(savedInstanceState: Bundle?) {
2552
super.onCreate(savedInstanceState)
2653
var keepSplashScreen = true
54+
getPermission()
2755

2856
installSplashScreen().apply {
2957
setKeepOnScreenCondition {
@@ -40,12 +68,101 @@ class MainActivity : ComponentActivity() {
4068
modifier = Modifier.fillMaxSize(),
4169
color = MaterialTheme.colors.background
4270
) {
43-
HomeScreen()
71+
HomeScreen({ locationRequestOnClick() })
4472
}
4573
}
4674
}
4775
}
76+
}
77+
78+
override fun onDestroy() {
79+
super.onDestroy()
80+
cancellationTokenSource.cancel()
81+
}
82+
83+
@RequiresApi(Build.VERSION_CODES.M)
84+
override fun onStart() {
85+
super.onStart()
86+
getPermission()
87+
}
4888

89+
@SuppressLint("MissingSuperCall")
90+
override fun onRequestPermissionsResult(
91+
requestCode: Int,
92+
permissions: Array<String>,
93+
grantResults: IntArray
94+
) {
95+
if (requestCode == REQUEST_FINE_LOCATION_PERMISSIONS_REQUEST_CODE) {
96+
when {
97+
grantResults.isEmpty() ->
98+
Timber.d("User interaction was cancelled.")
99+
grantResults[0] == PackageManager.PERMISSION_GRANTED -> {
100+
permissionViewModel.setLocationPermissionState(true)
101+
}
102+
else -> {
103+
permissionViewModel.locationPermissionState.value =
104+
LocationPermissionTypes.REQUEST_FROM_SETTINGS
105+
}
106+
}
107+
}
49108
}
50109

110+
@RequiresApi(Build.VERSION_CODES.M)
111+
fun getPermission() {
112+
val permissionState = requestPermissionWithRationale(
113+
Manifest.permission.ACCESS_FINE_LOCATION,
114+
REQUEST_FINE_LOCATION_PERMISSIONS_REQUEST_CODE
115+
)
116+
if (permissionState)
117+
permissionViewModel.locationPermissionState.value =
118+
LocationPermissionTypes.REQUEST_AGAIN
119+
}
120+
121+
@RequiresApi(Build.VERSION_CODES.M)
122+
fun locationRequestOnClick() {
123+
Timber.d("locationRequestOnClick()")
124+
val permissionApproved =
125+
applicationContext.hasPermission(Manifest.permission.ACCESS_FINE_LOCATION)
126+
if (permissionApproved) {
127+
requestCurrentLocation()
128+
} else {
129+
permissionViewModel.locationPermissionState.value =
130+
LocationPermissionTypes.REQUEST_AGAIN
131+
}
132+
}
133+
134+
@SuppressLint("MissingPermission")
135+
private fun requestCurrentLocation() {
136+
if (applicationContext.hasPermission(Manifest.permission.ACCESS_FINE_LOCATION)) {
137+
val currentLocationTask: Task<Location> = fusedLocationClient.getCurrentLocation(
138+
LocationRequest.PRIORITY_HIGH_ACCURACY,
139+
cancellationTokenSource.token
140+
)
141+
currentLocationTask.addOnCompleteListener { task: Task<Location> ->
142+
if (task.isSuccessful && task.result != null) {
143+
val result: Location = task.result
144+
Log.d(
145+
TAG,
146+
"getCurrentLocation() (success): ${result.latitude}, ${result.longitude}"
147+
)
148+
homeViewModel.setCurrentLocation(
149+
LocationRequestModel(
150+
latitude = task.result.latitude,
151+
longitude = task.result.longitude
152+
)
153+
)
154+
} else {
155+
val exception = task.exception
156+
Log.d(TAG, "getCurrentLocation() (failure): $exception\"")
157+
158+
}
159+
Log.d(TAG, "getCurrentLocation() result: ${task.result.longitude}")
160+
161+
}
162+
}
163+
}
164+
165+
companion object {
166+
private const val TAG = "MainActivity"
167+
}
51168
}

0 commit comments

Comments
 (0)