0

so I want to get the latitude and longitude from the device, but when I build my application on android Lollipop or API 22 I'm not getting the current latitude and longitude. is this because of android permission or what? here is my code

I'm using play service location version:

implementation 'com.google.android.gms:play-services-location:17.0.0'

LocationUser.kt

class LocationUser(context: Context) {
    private var fusedLocation: FusedLocationProviderClient? = null
    private val INTERVAL: Long = 300000
    private val FASTEST_INTERVAL: Long = 300000
    private val REQUEST_LOCATION_PERMISSION = 1
    lateinit var locationRequest: LocationRequest
    private lateinit var lastLocation: Location


    fun startLocationUpdates(context: Context) {
        Log.d("LOCATION UPDATE", "started location update")
        locationRequest = LocationRequest()
        locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
        locationRequest.interval = INTERVAL
        locationRequest.fastestInterval = FASTEST_INTERVAL

        val builder = LocationSettingsRequest.Builder()
        builder.addLocationRequest(locationRequest)
        val locationSettingsRequest = builder.build()

        val settingsClient = LocationServices.getSettingsClient(context)
        settingsClient.checkLocationSettings(locationSettingsRequest)

        fusedLocation = LocationServices.getFusedLocationProviderClient(context)
        if (ActivityCompat.checkSelfPermission(
                context,
                android.Manifest.permission.ACCESS_FINE_LOCATION
            ) != PackageManager.PERMISSION_GRANTED &&
            ActivityCompat.checkSelfPermission(
                context,
                android.Manifest.permission.ACCESS_COARSE_LOCATION
            ) != PackageManager.PERMISSION_GRANTED
        ) {
            return
        }
        fusedLocation!!.requestLocationUpdates(locationRequest, locationCallback, Looper.myLooper())
        Log.d("LOCATION UPDATE", "end location update")
    }

    fun isPermissionGranted(context: Context): Boolean {
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (context.checkSelfPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) ==
                PackageManager.PERMISSION_GRANTED
            ) {
                true
            } else {
                ActivityCompat.requestPermissions(
                    context as Activity, arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION),
                    REQUEST_LOCATION_PERMISSION
                )
                false
            }
        } else {
            true
        }
    }

    private val locationCallback = object : LocationCallback() {
        override fun onLocationResult(locationResult: LocationResult) {
            locationResult.lastLocation
            onLocationChanged(context, locationResult.lastLocation)
            super.onLocationResult(locationResult)
        }
    }

    fun onLocationChanged(context: Context, location: Location) {
        Log.d("UWUWU", "location changed")
        lastLocation = location
        val geocoder = Geocoder(context, Locale.getDefault())
        val latitude = lastLocation.latitude
        val longitude = lastLocation.longitude
        val sharedPref = SharedPref(context)
        Log.d("latitude", latitude.toString())
        Log.d("longitude", longitude.toString())
        sharedPref.saveStringPref("latitude_user", latitude.toString())
        sharedPref.saveStringPref("longitude_user", longitude.toString())

        try {
            val addresses: List<Address> = geocoder.getFromLocation(latitude, longitude, 1)
            val namaKota = addresses[0].subAdminArea
            val namaKecamatan = addresses[0].locality
            sharedPref.saveStringPref("alamat_user", "$namaKecamatan, $namaKota")
        } catch (e: Exception) {
            e.localizedMessage
        }
        Log.d("UWUWU", "location changed")

    }
}

and in the activity I called the class like this

MainActivity.kt

class MainActivity : AppCompatActivity() {

    private val REQUEST_LOCATION_PERMISSION = 1
    private val REQUESTING_LOCATION_UPDATES_KEY = "requesting_location_update"
    private val  requestingLocationUpdates = true
    val locationUser = LocationUser(this)

    @SuppressLint("SimpleDateFormat", "SetTextI18n")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        ../
        val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
        if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
            checkUserGPS()
        }

        if(locationUser.isPermissionGranted(this)){
            locationUser.startLocationUpdates(this)
        }
        Log.d("GRANTED ?", locationUser.isPermissionGranted(this).toString())
    }

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.menu_setting, menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        if (item.itemId == R.id.menu_settings) {
            val intent = Intent(this, SettingsActivity::class.java)
            startActivity(intent)
            return true
        }
        return super.onOptionsItemSelected(item)
    }


    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        if (requestCode == REQUEST_LOCATION_PERMISSION) {
            if (grantResults.contains(PackageManager.PERMISSION_GRANTED)) {
                Toast.makeText(this, "permission granted", Toast.LENGTH_SHORT).show()
            }
        }
    }

    private fun checkUserGPS() {
        val dialog = AlertDialog.Builder(this)
        dialog.setMessage("GPS tidak aktif, apakah kamu ingin megaktifkannya?")
            .setCancelable(false)
            .setPositiveButton("iya") { _, which ->
                startActivityForResult(Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS), 11)
            }
            .setNegativeButton("tidak") { dialog, _ ->
                dialog.cancel()
                finish()
            }
            .create()
            .show()
    }

    override fun onResume() {
        locationUser.startLocationUpdates(this)
        super.onResume()
    }

}

when I see log I noticed that the function of onLocationChange not called when function startLocationUpdates function is called. is this because of permission or what, I'm suffering StackOverflow and get this question which is vice versa with my problem, and I noticed the same thing which is locationcallback is not triggered

FusedLocationProviderClient requestLocationUpdates doesn't trigger LocationCallBack for API 23 above

I'm confused right now

1 Answers1

0

The fused Location Provider will only maintain background location if at least one client is connected to it. Now just turning on the location service will not guarantee to store the last known location.

Once the first client connects, it will immediately try to get a location. If your activity is the first client to connect and getLastLocation() is invoked right away in onConnected(), that might not be enough time for the first location to arrive..

I suggest you to launch the Maps app first, so that there is at least some confirmed location, and then test your app.

Dony
  • 24
  • 6