Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 38 additions & 10 deletions app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Open the picker after the user denies location permission.

If the user selects “Don’t allow,” neither permission is granted. This branch shows denial UI and never calls openLocationPicker(). The linked issue requires manual map selection without location permission. Open the picker after denial and treat the permission as necessary only for the optional current-position feature. Android also recommends allowing users to continue without granting a permission when the feature can work without it. (developer.android.com)

showLocationPermissionDeniedDialog()
} else {
Snackbar
.make(
binding.root,
context.getString(R.string.nc_location_permission_required),
Snackbar.LENGTH_LONG
)
.show()
}
}
}

Expand Down Expand Up @@ -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)) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Open the picker when location services are disabled.

If the user disables device location services, this branch shows a settings dialog instead of opening the picker. The user cannot select a location manually, although the map does not require a device location fix. Open the picker in this case. Keep the settings action available for users who want their current position. LocationManagerCompat.isLocationEnabled reports whether device location is enabled. (developer.android.com)

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() {
Expand Down Expand Up @@ -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"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)) }
}
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading