diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt index 164916cc032..5a5c7f28f5a 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -74,6 +74,7 @@ import androidx.core.content.ContextCompat import androidx.core.content.FileProvider import androidx.core.content.PermissionChecker import androidx.core.content.PermissionChecker.PERMISSION_GRANTED +import androidx.core.location.LocationManagerCompat import androidx.core.net.toUri import androidx.core.os.bundleOf import androidx.core.view.ViewCompat @@ -2837,6 +2838,20 @@ class ChatActivity : .make(binding.root, context.getString(R.string.take_photo_permission), Snackbar.LENGTH_LONG) .show() } + } else if (requestCode == REQUEST_LOCATION_PERMISSION) { + if (grantResults.any { it == PackageManager.PERMISSION_GRANTED }) { + openLocationPicker() + } else if (!shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)) { + showLocationPermissionDeniedDialog() + } else { + Snackbar + .make( + binding.root, + context.getString(R.string.nc_location_permission_required), + Snackbar.LENGTH_LONG + ) + .show() + } } } @@ -2904,20 +2919,32 @@ class ChatActivity : Log.d(TAG, "showShareLocationScreen") val locationManager = getSystemService(LOCATION_SERVICE) as LocationManager - val isGpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) - if (!isGpsEnabled) { + if (!LocationManagerCompat.isLocationEnabled(locationManager)) { showLocationServicesDisabledDialog() - } else if (!permissionUtil.isLocationPermissionGranted()) { - showLocationPermissionDeniedDialog() + } else if (permissionUtil.isLocationPermissionGranted()) { + openLocationPicker() + } else { + requestLocationPermissions() } + } - if (permissionUtil.isLocationPermissionGranted() && isGpsEnabled) { - val intent = Intent(this, LocationPickerActivity::class.java) - intent.putExtra(KEY_ROOM_TOKEN, roomToken) - intent.putExtra(BundleKeys.KEY_CHAT_API_VERSION, chatApiVersion) - startActivity(intent) - } + private fun openLocationPicker() { + val intent = Intent(this, LocationPickerActivity::class.java) + intent.putExtra(KEY_ROOM_TOKEN, roomToken) + intent.putExtra(BundleKeys.KEY_CHAT_API_VERSION, chatApiVersion) + startActivity(intent) + } + + private fun requestLocationPermissions() { + // request both, so that the user can choose between precise and approximate location (API 31+) + requestPermissions( + arrayOf( + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.ACCESS_COARSE_LOCATION + ), + REQUEST_LOCATION_PERMISSION + ) } private fun showLocationServicesDisabledDialog() { @@ -4323,6 +4350,7 @@ class ChatActivity : private const val REQUEST_RECORD_AUDIO_PERMISSION = 222 private const val REQUEST_READ_CONTACT_PERMISSION = 234 private const val REQUEST_CAMERA_PERMISSION = 223 + private const val REQUEST_LOCATION_PERMISSION = 224 private const val FILE_DATE_PATTERN = "yyyy-MM-dd HH-mm-ss" private const val VIDEO_SUFFIX = ".mp4" private const val PICTURE_SUFFIX = ".jpg" diff --git a/app/src/main/java/com/nextcloud/talk/location/components/LocationPickerScreen.kt b/app/src/main/java/com/nextcloud/talk/location/components/LocationPickerScreen.kt index 4f743d720e8..6a8c398c5b4 100644 --- a/app/src/main/java/com/nextcloud/talk/location/components/LocationPickerScreen.kt +++ b/app/src/main/java/com/nextcloud/talk/location/components/LocationPickerScreen.kt @@ -209,7 +209,7 @@ fun LocationPickerScreen( @SuppressLint("LocalContextGetResourceValueCall") val permissionLauncher = rememberLauncherForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions -> - if (permissions.values.all { it }) { + if (permissions.values.any { it }) { requestLocationUpdates(locationManager, locationListener) { msgRes -> coroutineScope.launch { snackbarHostState.showSnackbar(context.getString(msgRes)) } } @@ -680,21 +680,27 @@ private fun LocationPickerSharePanel( @SuppressLint("MissingPermission") private fun getLastKnownLocation(locationManager: LocationManager): android.location.Location? = - when { - locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER) -> - locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER) + try { + when { + locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER) -> + locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER) - locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) -> - locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER) + locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) -> + locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER) - else -> null + else -> null + } + } catch (e: SecurityException) { + // before API 31 the GPS provider requires fine location, which may not be granted + Log.w(TAG, "Missing permission to get last known location", e) + null } private fun isLocationPermissionsGranted(context: Context): Boolean = PermissionChecker.checkSelfPermission( context, Manifest.permission.ACCESS_COARSE_LOCATION - ) == PermissionChecker.PERMISSION_GRANTED && + ) == PermissionChecker.PERMISSION_GRANTED || PermissionChecker.checkSelfPermission( context, Manifest.permission.ACCESS_FINE_LOCATION diff --git a/app/src/main/java/com/nextcloud/talk/utils/permissions/PlatformPermissionUtilImpl.kt b/app/src/main/java/com/nextcloud/talk/utils/permissions/PlatformPermissionUtilImpl.kt index a939561ab58..f29ef0e4bc7 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/permissions/PlatformPermissionUtilImpl.kt +++ b/app/src/main/java/com/nextcloud/talk/utils/permissions/PlatformPermissionUtilImpl.kt @@ -95,7 +95,11 @@ class PlatformPermissionUtilImpl(private val context: Context) : PlatformPermiss PermissionChecker.checkSelfPermission( context, Manifest.permission.ACCESS_FINE_LOCATION - ) == PermissionChecker.PERMISSION_GRANTED + ) == PermissionChecker.PERMISSION_GRANTED || + PermissionChecker.checkSelfPermission( + context, + Manifest.permission.ACCESS_COARSE_LOCATION + ) == PermissionChecker.PERMISSION_GRANTED companion object { private val TAG = PlatformPermissionUtilImpl::class.simpleName