ABHISHEK
ABHISHEK

Reputation: 57

Unable to get correct Location using FusedLocationClientProvider

Hi everyone i am working on a project i am using kotlin for this project.

There are many things that i have to do but i got stuck one thing which is to get users current location using google maps.I know there are heaps of tutorials but all i have done is from google maps official documentation using FusedLocationClientProvider.Everything works fine till the loading and showing location of user but i don't get correct location.It shows that i'm in california which i'm not so how would i make it show correct location.

I have attached the code that i'm using for current location

I have used a text view for testing to show current location.

package com.example.soundsource

import android.content.pm.PackageManager
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.google.android.gms.maps.CameraUpdateFactory
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.OnMapReadyCallback
import com.google.android.gms.maps.SupportMapFragment
import com.google.android.gms.maps.model.LatLng
import com.google.android.gms.maps.model.MarkerOptions
import android.Manifest
import android.app.Service
import android.content.Context
import android.location.Geocoder
import android.location.Location
import android.location.LocationListener
import android.location.LocationManager
import android.util.Log
import android.widget.TextView
import com.google.android.gms.location.FusedLocationProviderClient
import com.google.android.gms.location.LocationServices
import com.google.android.libraries.places.api.Places
import java.lang.StringBuilder
import java.util.*
import com.google.android.libraries.places.api.net.PlacesClient
import kotlin.math.*


class SoundLocation : AppCompatActivity(),OnMapReadyCallback{

    private var map: GoogleMap? = null

    // The entry point to the Places API.
    private lateinit var placesClient: PlacesClient

    // The entry point to the Fused Location Provider.
    private lateinit var fusedLocationProviderClient: FusedLocationProviderClient

    private lateinit var locationManager:LocationManager

    companion object {
        private val defaultLocation = LatLng(-31.952854, 115.857342)
        private var locationPermissionGranted = false
        private const val DEFAULT_ZOOM = 15
        private const val PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1
        private var lastKnownLocation: Location? = null
        // Keys for storing activity state.
        private const val KEY_CAMERA_POSITION = "camera_position"
        private const val KEY_LOCATION = "location"
    }

    private lateinit var addressLocation:TextView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_sound_location)

        val mapFragment = supportFragmentManager.findFragmentById(R.id.map) as? SupportMapFragment
        mapFragment?.getMapAsync(this)

       addressLocation = findViewById(R.id.address)

        // Construct a GeoDataClient.
        Places.initialize(applicationContext, getString(R.string.google_maps_key))
        placesClient = Places.createClient(this)

        fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)

    }


    override fun onMapReady(googleMap: GoogleMap?) {
        this.map = googleMap
        map?.mapType = GoogleMap.MAP_TYPE_HYBRID
        getLocationPermission()
        updateLocationUI()
        getDeviceLocation()
    }

    private fun moveCamera(lat:Double,lon:Double,current:String){
        map?.apply {
            addMarker(
                MarkerOptions()
                    .position(LatLng(lat,lon))
                    .title(current)
            )
            moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(lat,lon),10f))
        }
    }

    private fun getAddress(lat:Double,lon:Double): String {
        // distance between two latitude and longitude
        val Perth = LatLng(-31.952854, 115.857342)
        val dlat = lat-Perth.latitude
        val dlon = lon-Perth.longitude
        var distance = sin(dlat/2)* sin(dlon/2) + cos(lat)+ cos(lon)*sin(dlat/2)* sin(dlon/2)
        distance = atan2(sqrt(distance), sqrt(1-distance))
        distance *= 6371


        //current location address
        val geoCoder = Geocoder(this, Locale.getDefault())
        val addresses = geoCoder.getFromLocation(lat,lon,1)
        val returnAddress = addresses[0]
        val fullAddress = StringBuilder("")
        for (i in 0..returnAddress.maxAddressLineIndex) {
            fullAddress.append(returnAddress.getAddressLine(i)).append("\n")
        }
        fullAddress.append(" \n ").append(String.format(" %.1f kms",distance))


        return fullAddress.toString()
    }

    private fun updateLocationUI() {
        if (map == null)
            return
        try {
            if (locationPermissionGranted) {
                map?.isMyLocationEnabled = true
                map?.uiSettings?.isMyLocationButtonEnabled = true
            } else {
                map?.isMyLocationEnabled = false
                map?.uiSettings?.isMyLocationButtonEnabled = false
                lastKnownLocation = null
                getLocationPermission()
            }
        } catch (e: SecurityException) {
            Log.e("Exception: %s", e.message, e)
        }
    }

    private fun getLocationPermission() {
        if (ContextCompat.checkSelfPermission(this.applicationContext, Manifest.permission.ACCESS_FINE_LOCATION)
            == PackageManager.PERMISSION_GRANTED 
        ) {
            locationPermissionGranted = true
        } else {
            ActivityCompat.requestPermissions(
                this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
                PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION
            )
        }
    }

    override fun onRequestPermissionsResult(requestCode: Int,
                                            permissions: Array<String>,
                                            grantResults: IntArray) {
        locationPermissionGranted = false
        when (requestCode) {
            PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION -> {
                if (grantResults.isNotEmpty() &&
                    grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    locationPermissionGranted = true
                }
            }
        }
        updateLocationUI()
    }

    private fun getDeviceLocation() {
        try {
            if (locationPermissionGranted) {
                val locationResult = fusedLocationProviderClient.lastLocation
                locationResult.addOnCompleteListener(this) { task ->
                    if (task.isSuccessful) {

                        lastKnownLocation = task.result
                        if (lastKnownLocation != null) {

                           val currentAddress = getAddress(lastKnownLocation!!.latitude,
                               lastKnownLocation!!.longitude)
                            addressLocation.text = currentAddress
                            moveCamera(lastKnownLocation!!.latitude,
                                lastKnownLocation!!.longitude,currentAddress)
                        }


                    } else {
                        map?.moveCamera(CameraUpdateFactory
                            .newLatLngZoom(defaultLocation, DEFAULT_ZOOM.toFloat()))
                        map?.uiSettings?.isMyLocationButtonEnabled = false
                    }
                }
            }
        } catch (e: SecurityException) {
            Log.e("Exception: %s", e.message, e)
        }
    }

}

Upvotes: 0

Views: 127

Answers (1)

Gavin Wright
Gavin Wright

Reputation: 3212

Are you testing this on an emulator? Emulators don't have actual GPS built-in, so by default your location will be in California. You can set your location from the emulator settings, though. Or just test it on a real phone.

Upvotes: 2

Related Questions