Skip to content

Commit 19e5e6a

Browse files
committed
Refactor: Improve location permission handling and marker updates
This commit refactors the location permission handling and marker update logic to enhance the app's functionality and robustness . - Implements a retry mechanism for location permission requests to ensure the app continues to function even if permissions are initially denied. - Improves the logic for checking and requesting necessary permissions, including background location permission for Android 10 and higher. - Adds logging to track the marker update process and identify potential issues. - Simplifies the camera animation logic. - Refactors the marker update logic to handle different user roles and improve efficiency. - Removes unnecessary code and comments. - Addresses potential null pointer exceptions in marker updates. - Improves the clarity and maintainability of the code.
1 parent f573869 commit 19e5e6a

File tree

2 files changed

+188
-96
lines changed

2 files changed

+188
-96
lines changed

app/src/main/java/com/pigo/areo/MainActivity.kt

Lines changed: 80 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package com.pigo.areo
22

33
import android.Manifest
44
import android.annotation.SuppressLint
5-
import android.content.ComponentName
65
import android.content.Context
76
import android.content.Intent
87
import android.content.pm.PackageManager
@@ -47,6 +46,7 @@ class MainActivity : AppCompatActivity(), OnMapReadyCallback {
4746

4847
companion object {
4948
private const val PERMISSION_REQUEST_CODE = 123
49+
private const val RETRY_DELAY_MS = 10000L // 10 seconds
5050
}
5151

5252
private lateinit var binding: ActivityMainBinding
@@ -58,15 +58,17 @@ class MainActivity : AppCompatActivity(), OnMapReadyCallback {
5858
}
5959

6060
private var cameraUpdateJob: Job? = null
61+
private var permissionRetryJob: Job? = null
6162

6263
private val requestPermissionLauncher = registerForActivityResult(
6364
ActivityResultContracts.RequestMultiplePermissions()
6465
) { permissions ->
65-
if (permissions[Manifest.permission.ACCESS_FINE_LOCATION] == true && permissions[Manifest.permission.ACCESS_COARSE_LOCATION] == true && permissions[Manifest.permission.WAKE_LOCK] == true) {
66+
val allPermissionsGranted = permissions.all { it.value }
67+
if (allPermissionsGranted) {
6668
checkBatteryOptimization()
6769
} else {
68-
Log.e("PermissionError", "Location or wake lock permissions denied.")
69-
// Handle permission denial (e.g., show a message to the user)
70+
Log.e("PermissionError", "Required permissions denied.")
71+
startPermissionRetryCoroutine()
7072
}
7173
}
7274

@@ -92,78 +94,104 @@ class MainActivity : AppCompatActivity(), OnMapReadyCallback {
9294

9395
appBarConfiguration = AppBarConfiguration(
9496
setOf(
95-
R.id.tripDetailsFragment, R.id.createTripFragment, R.id.currentTripFragment
97+
R.id.tripDetailsFragment,
98+
R.id.createTripFragment,
99+
R.id.currentTripFragment
96100
)
97101
)
98102
binding.bottomNavigation.setupWithNavController(navController)
99103
}
100104

101105
private fun requestLocationPermissions() {
102-
val permissionsToRequest = mutableListOf(
106+
val locationPermissions = arrayOf(
103107
Manifest.permission.ACCESS_FINE_LOCATION,
104108
Manifest.permission.ACCESS_COARSE_LOCATION,
105-
)
106-
107-
// Request background location permission on Android 10 (API level 29) and higher
108-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
109-
permissionsToRequest.add(Manifest.permission.ACCESS_BACKGROUND_LOCATION)
109+
Manifest.permission.WAKE_LOCK
110+
).apply {
111+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
112+
plus(Manifest.permission.ACCESS_BACKGROUND_LOCATION)
113+
}
110114
}
111115

112-
if (permissionsToRequest.all {
113-
ContextCompat.checkSelfPermission(this, it) == PackageManager.PERMISSION_GRANTED
114-
}) {
115-
// All permissions already granted
116-
checkBatteryOptimization()
116+
val permissionsToRequest = locationPermissions.filter {
117+
ActivityCompat.checkSelfPermission(this, it) != PackageManager.PERMISSION_GRANTED
118+
}.toTypedArray()
119+
120+
if (permissionsToRequest.isNotEmpty()) {
121+
requestPermissionLauncher.launch(permissionsToRequest)
117122
} else {
118-
// Request permissions
119-
requestPermissionLauncher.launch(
120-
permissionsToRequest.toTypedArray()
121-
)
123+
checkBatteryOptimization()
122124
}
123125
}
126+
127+
private fun startPermissionRetryCoroutine() {
128+
permissionRetryJob = lifecycleScope.launch {
129+
while (isActive) {
130+
if (arePermissionsGranted()) {
131+
permissionRetryJob?.cancel()
132+
checkBatteryOptimization()
133+
return@launch
134+
}
135+
Log.d("PermissionRetry", "Retrying permission request...")
136+
delay(RETRY_DELAY_MS)
137+
requestLocationPermissions()
138+
}
139+
}
140+
}
141+
142+
private fun arePermissionsGranted(): Boolean {
143+
val requiredPermissions = arrayOf(
144+
Manifest.permission.ACCESS_FINE_LOCATION,
145+
Manifest.permission.ACCESS_COARSE_LOCATION,
146+
Manifest.permission.WAKE_LOCK
147+
).apply {
148+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
149+
plus(Manifest.permission.ACCESS_BACKGROUND_LOCATION)
150+
}
151+
}
152+
return requiredPermissions.all {
153+
ActivityCompat.checkSelfPermission(this, it) == PackageManager.PERMISSION_GRANTED
154+
}
155+
}
156+
124157
private fun checkBatteryOptimization() {
125-
val powerManager = getSystemService(POWER_SERVICE) as PowerManager
158+
val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
126159
if (!powerManager.isIgnoringBatteryOptimizations(packageName)) {
127160
requestDisableBatteryOptimization()
128161
} else {
129-
// Battery optimization is disabled, now check for GPS
130162
checkGpsAndStartService()
131163
}
132164
}
133165

166+
@SuppressLint("BatteryLife")
167+
private fun requestDisableBatteryOptimization() {
168+
val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS).apply {
169+
data = Uri.parse("package:$packageName")
170+
}
171+
startActivity(intent)
172+
}
173+
134174
private fun checkGpsAndStartService() {
135175
val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
136176
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
137-
// GPS is enabled, start location service
138177
startLocationService()
139178
} else {
140-
// GPS is not enabled, prompt user to enable it
141179
openLocationSettings()
142180
}
143181
}
144182

145-
146183
private fun startLocationService() {
147-
148-
// Start location updates after starting the service
149184
fetchLastKnownLocation()
150185
startPeriodicCameraUpdate()
151186
}
152187

153-
@SuppressLint("BatteryLife")
154-
private fun requestDisableBatteryOptimization() {
155-
val intent = Intent().apply {
156-
action = Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
157-
data = Uri.parse("package:$packageName")
158-
}
159-
startActivity(intent)
160-
}
161-
162188
private fun fetchLastKnownLocation() {
163189
if (ActivityCompat.checkSelfPermission(
164-
this, Manifest.permission.ACCESS_FINE_LOCATION
190+
this,
191+
Manifest.permission.ACCESS_FINE_LOCATION
165192
) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
166-
this, Manifest.permission.ACCESS_COARSE_LOCATION
193+
this,
194+
Manifest.permission.ACCESS_COARSE_LOCATION
167195
) != PackageManager.PERMISSION_GRANTED
168196
) {
169197
return
@@ -179,10 +207,7 @@ class MainActivity : AppCompatActivity(), OnMapReadyCallback {
179207
override fun onLocationResult(locationResult: LocationResult) {
180208
locationResult.lastLocation?.let { location ->
181209
updateLocationOnMap(location)
182-
sharedViewModel.addTripLocation(
183-
LatLng(location.latitude, location.longitude)
184-
)
185-
210+
sharedViewModel.addTripLocation(LatLng(location.latitude, location.longitude))
186211
}
187212
}
188213
}, null)
@@ -195,13 +220,11 @@ class MainActivity : AppCompatActivity(), OnMapReadyCallback {
195220
}
196221
}
197222

198-
199223
private fun startPeriodicCameraUpdate() {
200224
cameraUpdateJob = lifecycleScope.launch {
201225
while (isActive) {
202-
val userRole = sharedViewModel.userRole.value
203226
sharedViewModel.updateCameraPosition()
204-
delay(if (userRole == SharedViewModel.UserRole.DRIVER) 1500 else 5000)
227+
delay(if (sharedViewModel.userRole.value == SharedViewModel.UserRole.DRIVER) 1500 else 5000)
205228
}
206229
}
207230
}
@@ -215,46 +238,39 @@ class MainActivity : AppCompatActivity(), OnMapReadyCallback {
215238
sharedViewModel.updateCurrentMarkerAndAddMarkers(gMap)
216239
Log.d("LocationUpdate", "Updated current marker and added markers")
217240
}
218-
219241
}
220242

221243
private fun animateCameraToLocation(latLng: LatLng) {
222-
val cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, 16f)
223-
gMap.animateCamera(cameraUpdate)
244+
gMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 16f))
224245
Log.d("LocationUpdate", "Animated camera to new location: $latLng")
225246
}
226247

227-
228248
override fun onMapReady(googleMap: GoogleMap) {
229-
sharedViewModel.setGoogleMap(googleMap)
230249
gMap = googleMap
231-
val uiSettings = gMap.uiSettings
232-
233-
uiSettings.isCompassEnabled = false
234-
uiSettings.isMyLocationButtonEnabled = false
235-
uiSettings.isMapToolbarEnabled = false
236-
uiSettings.isIndoorLevelPickerEnabled = false
250+
val uiSettings = gMap.uiSettings.apply {
251+
isCompassEnabled = false
252+
isMyLocationButtonEnabled = false
253+
isMapToolbarEnabled = false
254+
isIndoorLevelPickerEnabled = false
255+
}
237256

238257
changeMapStyle()
258+
sharedViewModel.setGoogleMap(gMap)
239259
}
240260

241261
override fun onDestroy() {
242262
super.onDestroy()
243-
cameraUpdateJob?.cancel() // Cancel coroutine job when activity is destroyed
263+
cameraUpdateJob?.cancel()
264+
permissionRetryJob?.cancel()
244265
}
245266

246267
private fun changeMapStyle() {
247268
val style = MapStyleOptions.loadRawResourceStyle(this, R.raw.map_style)
248269
gMap.setMapStyle(style)
249270
}
250271

251-
252272
private fun openLocationSettings() {
253-
val intent = Intent().apply {
254-
component = ComponentName(
255-
"com.android.settings", "com.android.settings.Settings\$LocationSettingsActivity"
256-
)
257-
}
273+
val intent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
258274
startActivity(intent)
259275
}
260-
}
276+
}

0 commit comments

Comments
 (0)