I have created some classes using those you can easily get the current location. I used FusedLocationProviderClient for getting the current location.
First Add this into your manifest File:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Then Check for location permission:
 private fun startCheckingLocation() {
    if (checkLocationPermissions() == true) {
        checkGPSEnabled()
    } else {
        askLocationPermission()
    }
}
checkLocationPermissions method:
 private fun checkLocationPermissions(): Boolean? {
    return PermissionUtils.hasPermissions(
        requireContext(),
        Manifest.permission.ACCESS_FINE_LOCATION,
        Manifest.permission.ACCESS_COARSE_LOCATION
    )
}
checkGPSEnabled method:
 private fun checkGPSEnabled() {
    GpsUtils(requireContext()) {
        it?.let {
            startCheckingCurrentLocation()
        }
    }.apply {
        turnGPSOn(gpsDialogCallback)
    }
}
As OnActivityResult is Deprecated:
     private val gpsDialogCallback =     registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) { activityResult ->
        activityResult?.let { result ->
            when (result.resultCode) {
                RESULT_OK -> {
                    startCheckingCurrentLocation()
                }
                RESULT_CANCELED -> {
                }
            }
        }
    }
startCheckingCurrentLocation method :
 private fun startCheckingCurrentLocation() {
    LocationUtils(requireContext()) { location ->
        Log.d(TAG, ">>>>>>>>>>>>>>" + location.latitude + " " + location.longitude)
        startIntentService(location)
    }.apply {
        startLocationUpdates()
    }
}
For GPS I have created one class that you can simply put and use it:
GPSUtils:
class GpsUtils(
private val context: Context,
private val gpsStatus: (isEnable: Boolean?) -> Unit
) {
private val mSettingsClient: SettingsClient = LocationServices.getSettingsClient(context)
private val mLocationSettingsRequest: LocationSettingsRequest
private val locationManager: LocationManager =
    context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
private val locationRequest: LocationRequest = LocationRequest.create()
init {
    locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
    locationRequest.interval = 10 * 1000.toLong()
    locationRequest.fastestInterval = 2 * 1000.toLong()
    val builder = LocationSettingsRequest.Builder().addLocationRequest(locationRequest)
    mLocationSettingsRequest = builder.build()
    builder.setAlwaysShow(true) //this is the key ingredient
}
// method for turn on GPS
fun turnGPSOn(gpsDialogCallback: ActivityResultLauncher<IntentSenderRequest>) {
    if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
        gpsStatus.invoke(true)
    } else {
        mSettingsClient
            .checkLocationSettings(mLocationSettingsRequest)
            .addOnSuccessListener(
                (context as Activity)
            ) {
                //  GPS is already enable, callback GPS status through listener
                gpsStatus.invoke(true)
            }
            .addOnFailureListener(context) { e ->
                when ((e as ApiException).statusCode) {
                    LocationSettingsStatusCodes.RESOLUTION_REQUIRED -> try {
                        // Show the dialog by calling startResolutionForResult() and check the result in onActivityResult().
                        if (e is ResolvableApiException) {
                            try {
                                val intentSenderRequest = IntentSenderRequest.Builder(e.resolution).build()
                                gpsDialogCallback.launch(intentSenderRequest)
                            } catch (throwable: Throwable) {
                                // Ignore the error.
                            }
                        }
                    } catch (sie: IntentSender.SendIntentException) {
                        // Ignore the error.
                        Timber.i("PendingIntent unable to execute request.")
                    }
                    LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE -> {
                        // Location settings are not satisfied. However, we have no way to fix the
                        // settings so we won't show the dialog.
                        val errorMessage =
                            "Location settings are inadequate, and cannot be fixed here. Fix in Settings."
                        Timber.e(errorMessage)
                    }
                    LocationSettingsStatusCodes.CANCELED -> {
                        val errorMessage =
                            "Location settings are inadequate, and cannot be fixed here. Fix in Settings."
                        Timber.e(errorMessage)
                    }
                    LocationSettingsStatusCodes.SUCCESS -> {
                        // All location settings are satisfied. The client can initialize location
                        // requests here.
                        val errorMessage =
                            "Location settings are inadequate, and cannot be fixed here. Fix in Settings."
                        Timber.e(errorMessage)
                    }
                }
            }
    }
}
}
For checking location I have created one more class :
class LocationUtils(
context: Context,
private val latLng: (location: Location) -> Unit) {
private var fusedLocationClient: FusedLocationProviderClient? = null
private val locationRequest = LocationRequest.create()?.apply {
    interval = 20 * 1000.toLong()
    fastestInterval = 2 * 1000.toLong()
    priority = LocationRequest.PRIORITY_HIGH_ACCURACY
}
init {
    fusedLocationClient = LocationServices.getFusedLocationProviderClient(context)
}
/**
 * call when location permission is allowed and you want to fetch the last location of the user
 */
fun getLastLocation() {
    fusedLocationClient?.lastLocation?.addOnSuccessListener { location ->
        location?.let {
            latLng.invoke(location)
            stopLocationUpdates()
        }
    }
}
/**
 * Requested location callback
 */
private val locationCallback = object : LocationCallback() {
    override fun onLocationResult(locationResult: LocationResult?) {
        locationResult ?: return
        for (location in locationResult.locations) {
            location?.let {
                latLng.invoke(it)
                stopLocationUpdates()
            }
        }
        super.onLocationResult(locationResult)
    }
}
/**
 * call when location permission is already given to user and you want to receive continues location updates
 */
fun startLocationUpdates() {
    fusedLocationClient?.requestLocationUpdates(
        locationRequest,
        locationCallback,
        Looper.getMainLooper()
    )
}
/**
 * call when you want to stop location updates
 */
fun stopLocationUpdates() {
    fusedLocationClient?.removeLocationUpdates(locationCallback)?.addOnCompleteListener { }
}
}
I have created one worker class to get the address from latlng:
class FetchAddressWorker(
context: Context,
workerParameters: WorkerParameters
) :
Worker(context, workerParameters) {
companion object {
    const val TAG = "FetchAddressWorker"
}
override fun doWork(): Result {
    val geoCoder = Geocoder(applicationContext, Locale.getDefault())
    var errorMessage = ""
    val lat: Double = inputData.getDouble(CPKConstants.LATITUDE, 0.0)
    val lng: Double = inputData.getDouble(CPKConstants.LONGITUDE, 0.0)
    var addresses: List<Address> = emptyList()
    try {
        addresses =
            geoCoder.getFromLocation(lat, lng, 1)
    } catch (ioException: IOException) {
        // Catch network or other I/O problems.
        errorMessage = "Service not available"
        LogUtils.e(TAG, errorMessage, ioException)
    } catch (illegalArgumentException: IllegalArgumentException) {
        // Catch invalid latitude or longitude values.
        errorMessage = "Invalid lat lng used"
        LogUtils.e(
            TAG,
            "$errorMessage. Latitude = $lat , Longitude =  $lng",
            illegalArgumentException
        )
    }
    // Handle case where no address was found.
    if (addresses.isEmpty()) {
        if (errorMessage.isEmpty()) {
            errorMessage = "No Address Found"
            LogUtils.e(TAG, errorMessage)
        }
        val data = Data.Builder()
            .putString(
                CPKConstants.FAILURE_RESULT,
                errorMessage
            )
            .build()
        return Result.failure(data)
    } else {
        val address: Address = addresses[0]
        // Fetch the address lines using getAddressLine,
        // join them, and send them to the thread.
        val addressFragments = with(address) {
            (0..maxAddressLineIndex).map { getAddressLine(it) }
        }
        LogUtils.i(TAG, "Address Found " + addressFragments.joinToString(separator = "\n"))
        
       
        val data = Data.Builder()
            .putString(
                CPKConstants.SUCCESS_RESULT,
                addressFragments.joinToString(separator = "\n")
            )
            .build()
        // Indicate whether the work finished successfully with the Result
        return Result.success(data)
    }
}
}
Than use AddressResultReceiver in your fragment or activity:
 internal inner class AddressResultReceiver(handler: Handler) : ResultReceiver(handler) {
    override fun onReceiveResult(resultCode: Int, resultData: Bundle?) {
        // Display the address string
        // or an error message sent from the intent service.
        val addressOutput = resultData?.getString(AppConstants.RESULT_DATA_KEY).orEmpty()
        //displayAddressOutput()
        // Show a toast message if an address was found.
        if (resultCode == AppConstants.SUCCESS_RESULT) {
            Boast.showText(requireContext(), "Address found = $addressOutput")
            txtContinueWith.text = addressOutput
        }
    }
}
You will need to initialize this in fragment or activity where you will use the above receiver to get the address:
  private var resultReceiver = AddressResultReceiver(Handler())
These are some constants that you should use as it is.
//Location Constants
const val LOCATION_SERVICE = "LOCATION_SERVICE"
const val SUCCESS_RESULT = 0
const val FAILURE_RESULT = 1
const val PACKAGE_NAME = "com.google.android.gms.location.sample.locationaddress"
const val RECEIVER = "$PACKAGE_NAME.RECEIVER"
const val RESULT_DATA_KEY = "${PACKAGE_NAME}.RESULT_DATA_KEY"
const val LOCATION_DATA_EXTRA = "${PACKAGE_NAME}.LOCATION_DATA_EXTRA"
Start worker from view
  private fun startAddressWorkManager(location: Location) {
    val inputData = Data.Builder()
        .putDouble(CPKConstants.LATITUDE, location.latitude)
        .putDouble(CPKConstants.LONGITUDE, location.longitude)
        .build()
    val constraints = Constraints.Builder()
        .setRequiredNetworkType(NetworkType.CONNECTED)
        .build()
    val fetchAddressWorkRequest: WorkRequest =
        OneTimeWorkRequestBuilder<FetchAddressWorker>()
            .setConstraints(constraints)
            .setInputData(inputData)
            .build()
    WorkManager
        .getInstance(this)
        .enqueue(fetchAddressWorkRequest)
    WorkManager.getInstance(this).getWorkInfoByIdLiveData(fetchAddressWorkRequest.id)
        .observe(this,
            { workInfo ->
                when (workInfo.state) {
                    WorkInfo.State.SUCCEEDED -> {
                        if (workInfo.state.isFinished) {
                            val addressData =
                                workInfo.outputData.getString(CPKConstants.SUCCESS_RESULT)
                            Timber.d("AddressData %s", addressData)
                            _binding?.searchEdt?.setText(addressData)
                        }
                    }
                    else -> {
                        Timber.d("workInfo %s", workInfo)
                    }
                }
            })
}