Skip to main content

Simplify Your Tax Calculations with GST Calculator 2024: The Ultimate Tool for Businesses and Individuals

How to get Android Device Current locaction, i.e latitude and longitude in Kotlin Using Fused Location SDK.

 In this Android development article, you will learn, how to get device current location in android kotlin using Google Fused Location Client SDK.


Now a days, device current location fetching is a common feature in many applications, and for us we need to write same code in every project. So I make this code in such a way that, we can integrate the device location pick feature (i.e latitude, longitude ) within 5 minute. Just follow this steps-

Okay, first we create an android project and create a activity 

MainActivity.kt and respective xml file is activity_main.xml


Add Location Permission in AndroidMenifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.devicecurrentlocation">

    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".LocationPickerActivity"
            android:excludeFromRecents="true"
            android:label=" "
            android:screenOrientation="portrait"
            android:theme="@style/Transparent" />
        <activity
            android:name=".MainActivity"
            android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>


styles.xml

<resources xmlns:tools="http://schemas.android.com/tools">
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorAccent">@color/colorAccent</item>
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    </style>
    <style name="Transparent" parent="Theme.AppCompat.Dialog">
        <item name="android:windowIsTranslucent">true</item>
        <item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
        <item name="android:windowBackground">@android:color/transparent</item>
        <item name="android:windowContentOverlay">@null</item>
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowIsFloating">true</item>
        <item name="android:backgroundDimEnabled">true</item>
        <item name="android:windowCloseOnTouchOutside">true</item>


    </style>

    <style name="TransparentDialog" parent="Theme.AppCompat.Light.Dialog">
        <item name="android:windowFrame">@null</item>
        <item name="android:windowIsTranslucent">true</item>
        <item name="android:layout_gravity">top</item>
        <item name="android:windowMinWidthMajor">90%</item>
        <item name="android:windowMinWidthMinor">90%</item>
        <item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
        <item name="android:windowBackground">@android:color/transparent</item>
        <item name="android:windowContentOverlay">@null</item>
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowActionBar">false</item>
        <item name="android:windowIsFloating">true</item>
        <item name="android:backgroundDimEnabled">true</item>
        <item name="android:windowCloseOnTouchOutside">true</item>
        <item name="android:windowFullscreen">false</item>
    </style>

</resources>


colors.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorAccent">#00C0A5</color>
    <color name="colorPrimary">#00C0A5</color>
    <color name="colorPrimaryDark">#00C0A5</color>
</resources>


strings.xml

<resources>
    <string name="app_name">DeviceCurrentLocation</string>
    <string name="current_device_location">Current Device Location</string>
    <string name="get_location">Get Location</string>
    <string name="loading">Loading</string>
</resources>


activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/current_device_location"
        android:textSize="25sp"
        app:layout_constraintBottom_toBottomOf="@+id/guideline"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent=".30" />

    <Button
        android:id="@+id/btnLocation"
        android:layout_width="match_parent"
        android:layout_height="55dp"
        android:layout_marginStart="15dp"
        android:layout_marginEnd="15dp"
        android:text="@string/get_location"
        app:layout_constraintTop_toTopOf="@+id/guideline" />

    <TextView
        android:id="@+id/tvLatLng"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="25sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btnLocation" />

</androidx.constraintlayout.widget.ConstraintLayout>


MainActivity.kt

package com.example.devicecurrentlocation

import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*
import org.json.JSONObject


class MainActivity : AppCompatActivity() {

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


        btnLocation.setOnClickListener {
            val intent = Intent(this, LocationPickerActivity::class.java)
            resultLauncher.launch(intent)
        }
    }

    @SuppressLint("SetTextI18n")
    private val resultLauncher = registerForActivityResult(StartActivityForResult()) { result ->
        if (result.resultCode == Activity.RESULT_OK) {
            // There are no request codes

            try {
                val data: Intent? = result.data

                val mJson = JSONObject(data?.getStringExtra("response")!!)

                tvLatLng.text = "Latitude: ${mJson.optString("lat")}" +
                        "\nLongitude: ${mJson.optString("lng")}"

            } catch (e: Exception) {
                e.printStackTrace()
            }

        }
    }

}



activity_location_picker.xml

 
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".LocationPickerActivity">

</androidx.constraintlayout.widget.ConstraintLayout>


LocationPickerActivity.kt

package com.example.devicecurrentlocation

import android.Manifest
import android.annotation.SuppressLint
import android.app.Activity
import android.app.AlertDialog
import android.app.Dialog
import android.content.Context
import android.content.Intent
import android.content.IntentSender.SendIntentException
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.location.Location
import android.net.Uri
import android.os.Bundle
import android.os.Looper
import android.provider.Settings
import android.view.LayoutInflater
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.google.android.gms.common.api.ApiException
import com.google.android.gms.common.api.ResolvableApiException
import com.google.android.gms.location.*
import com.karumi.dexter.BuildConfig
import com.karumi.dexter.Dexter
import com.karumi.dexter.MultiplePermissionsReport
import com.karumi.dexter.PermissionToken
import com.karumi.dexter.listener.multi.MultiplePermissionsListener
import kotlinx.android.synthetic.main.progress_dialog.view.*
import org.json.JSONObject
import java.text.DateFormat
import java.util.*

class LocationPickerActivity : AppCompatActivity(),
    MultiplePermissionsListener {


    private val updateIntervalInMillisecond: Long = 10000

    private val fastestUpdateIntervalInMilliseconds: Long = 5000

    private val requestCheckSettings = 100
    private val context: Context = this


    // location last updated time
    var mLastUpdateTime: String? = null
    private var mFusedLocationClient: FusedLocationProviderClient? = null
    private var mSettingsClient: SettingsClient? = null
    private var mLocationRequest: LocationRequest? = null
    private var mLocationSettingsRequest: LocationSettingsRequest? = null
    private var mLocationCallback: LocationCallback? = null
    var mCurrentLocation: Location? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_location_picker)
        this.setFinishOnTouchOutside(false)



        reqLocationPermission()


    }


    private fun reqLocationPermission() {

        Dexter.withContext(this)
            .withPermissions(
                Manifest.permission.ACCESS_COARSE_LOCATION,
                Manifest.permission.ACCESS_FINE_LOCATION

            )
            .withListener(this).onSameThread()
            .check()

    }


    private fun initLocation() {
        mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this)

        mSettingsClient = LocationServices.getSettingsClient(this)
        mLocationCallback = object : LocationCallback() {
            override fun onLocationResult(locationResult: LocationResult) {
                super.onLocationResult(locationResult)
                // location is received
                mCurrentLocation = locationResult.lastLocation
                mLastUpdateTime = DateFormat.getTimeInstance().format(Date())
                updateLocationUI()
            }
        }
        mLocationRequest = LocationRequest()
        mLocationRequest!!.interval = updateIntervalInMillisecond
        mLocationRequest!!.fastestInterval = fastestUpdateIntervalInMilliseconds
        mLocationRequest!!.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
        val builder = LocationSettingsRequest.Builder()
        builder.addLocationRequest(mLocationRequest!!).setAlwaysShow(true).setNeedBle(true)
        mLocationSettingsRequest = builder.build()
    }


    @SuppressLint("MissingPermission")
    private fun startLocationUpdates() {
        mSettingsClient
            ?.checkLocationSettings(mLocationSettingsRequest!!)
            ?.addOnSuccessListener(this) {

                mFusedLocationClient!!.requestLocationUpdates(
                    mLocationRequest!!,
                    mLocationCallback!!, Looper.myLooper()!!
                )
                //  Toast.makeText(context, "startLocationUpdates before", Toast.LENGTH_SHORT).show();

                // updateLocationUI();
                //   Toast.makeText(context, "startLocationUpdates after", Toast.LENGTH_SHORT).show();
            }
            ?.addOnFailureListener(this) { e ->
                when ((e as ApiException).statusCode) {
                    LocationSettingsStatusCodes.RESOLUTION_REQUIRED -> {

                        try {
                            // Show the dialog by calling startResolutionForResult(), and check the
                            // result in onActivityResult().
                            val rae = e as ResolvableApiException
                            rae.startResolutionForResult(
                                this,
                                requestCheckSettings
                            )
                        } catch (sie: SendIntentException) {

                        }
                    }
                    LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE -> {
                        val errorMessage =
                            "Location settings are inadequate, and cannot be " +
                                    "fixed here. Fix in Settings."

                        Toast.makeText(context, errorMessage, Toast.LENGTH_LONG).show()
                    }
                }

                //updateLocationUI();
            }
    }


    private fun stopLocationUpdates() {
        // Removing location updates
        mFusedLocationClient
            ?.removeLocationUpdates(mLocationCallback)
            ?.addOnCompleteListener(this) {
                //Toast.makeText(getApplicationContext(), "Location updates stopped!", Toast.LENGTH_SHORT).show();
            }
    }


    fun updateLocationUI() {
        var loc: String? = null
        if (mCurrentLocation != null) {
            loc = "Lat: " + mCurrentLocation!!.latitude + ", " +
                    "Lng: " + mCurrentLocation!!.longitude
            try {

                val mObject = JSONObject()
                mObject.put("lat", mCurrentLocation!!.latitude)
                mObject.put("lng", mCurrentLocation!!.longitude)
                mObject.put("date_in_mili", mCurrentLocation!!.time)
                //mObject.put("address", Util.getCompleteAddressString(context,mCurrentLocation!!.latitude,mCurrentLocation!!.longitude))


                //  PrefUtils.saveUserLocation(context,mObject.toString().trim())

                successResult(mObject)
            } catch (e: Exception) {
                e.printStackTrace()
            }
            stopLocationUpdates()
        }

        // giving a blink animation on TextView


    }


    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        when (requestCode) {

            requestCheckSettings -> when (resultCode) {
                Activity.RESULT_OK -> reqLocationPermission()
                Activity.RESULT_CANCELED -> cancelResult()
            }
        }
    }

    private fun openSettings() {
        val intent = Intent()
        intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
        val uri = Uri.fromParts(
            "package",
            BuildConfig.APPLICATION_ID, null
        )
        intent.data = uri
        intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
        //startActivityForResult(intent,REQUEST_CHECK_SETTINGS)
        startActivity(intent)
        finish()
    }

    private fun successResult(json: JSONObject) {
        val intent: Intent = intent
        intent.putExtra("response", json.toString())
        setResult(Activity.RESULT_OK, intent)
        finish()
    }

    private fun cancelResult() {
        val intent: Intent = intent
        setResult(Activity.RESULT_CANCELED, intent)
        finish()
    }


    override fun onPermissionsChecked(report: MultiplePermissionsReport) {
        // Here you have to check granted permissions


        if (report.areAllPermissionsGranted()) {
            val dialog = progressDialog(context, getString(R.string.loading))
            dialog.show()
            initLocation()
            startLocationUpdates()

        } else {
            if (report.isAnyPermissionPermanentlyDenied) {

                showSettingsDialog()

            } else {
                reqLocationPermission()
            }


        }


    }

    override fun onPermissionRationaleShouldBeShown(
        p0: MutableList<com.karumi.dexter.listener.PermissionRequest>?,
        token: PermissionToken?
    ) {

        token?.continuePermissionRequest()
    }


    private fun showSettingsDialog() {
        val builder: AlertDialog.Builder = AlertDialog.Builder(this)
        builder.setTitle("Need Permissions")
        builder.setMessage("This app needs permission to use this feature. You can grant them in app settings.")
        builder.setPositiveButton(
            "GOTO SETTINGS"
        ) { dialog, _ ->
            dialog.cancel()
            openSettings()
        }
        builder.setNegativeButton(
            "Cancel"
        ) { dialog, _ ->
            dialog.cancel()
            cancelResult()
        }
        builder.show()
    }

    @SuppressLint("InflateParams")
    fun progressDialog(context: Context, message: String): Dialog {
        val dialog = Dialog(context, R.style.TransparentDialog)
        val inflate = LayoutInflater.from(context).inflate(R.layout.progress_dialog, null)
        dialog.setContentView(inflate)
        inflate.tvMessage.text = message

        dialog.setCancelable(false)
        dialog.window!!.setBackgroundDrawable(
            ColorDrawable(Color.TRANSPARENT)
        )
        return dialog
    }

}


progress_dialog.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="80dp">

        <ProgressBar
            android:id="@+id/progressBar"
            style="?android:attr/progressBarStyle"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:layout_centerVertical="true"
            android:layout_margin="15dp"
            android:backgroundTint="@color/colorAccent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/tvMessage"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_margin="7dp"
            android:layout_toEndOf="@+id/progressBar"
            android:text="@string/loading"
            app:layout_constraintBottom_toBottomOf="@id/progressBar"
            app:layout_constraintStart_toEndOf="@id/progressBar"
            app:layout_constraintTop_toTopOf="@id/progressBar" />
    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.cardview.widget.CardView>


   



Comments

Popular posts from this blog

How to fetch Latitude, Longitude from address and vice-versa(address from Latitude, Longitude) using Google Geo coder SDK in android| Kotlin

 In this Android development related article, you will get a simple solution that, how to get address using Latitude, Longitude and vice-versa. i.e latitude, longitude from an address text. It is very easy and simple. Read full article and carefully follow all the steps. Here we use google Geocoder SDK. Okay, first we create an android project in kotlin and create an Activity say MainActivity.kt. Use the below code- Function get Latitude, Longitude from Address- fun getLatLngFromAddress (context: Context, mAddress: String): String { val coder = Geocoder(context) lateinit var address: List<Address> try { address = coder.getFromLocationName(mAddress, 5 ) if (address == null ) { return "Fail to find Lat,Lng" } val location = address[ 0 ] return " Latitude: ${location.latitude}\n Longitude: ${location.longitude}" } catch (e: Exception...

How to consume REST APIs in Laravel | Laravel Development | Solution

In Laravel, you can call a REST API using the HTTP client provided by the framework. Laravel's HTTP client allows you to make GET, POST, PUT, DELETE, and other HTTP requests to external APIs. Here's how you can call a REST API in Laravel: Install Laravel (if not already done): If you haven't already set up a Laravel project, you can create one using Composer by running the following command: composer create - project -- prefer - dist laravel / laravel project - name Create a Controller (optional): You can create a controller to encapsulate the API call logic, but this step is not strictly necessary. You can also make API calls directly from your routes or other parts of your application. To create a controller, run the following command: php artisan make: controller ApiController Make an API Request: You can make API requests using Laravel's HTTP client, which is a fluent, expressive interface for making HTTP requests. Here's how you can make a simple GET request t...

Create Any Recyclerview Adapter within 5 seconds, in Android | Kotlin.

 In every single android application, we need to make many number of recycler-view adapter. So every time you create a blank adapter and modify it as per your requirements. But it is very boring and as well as time taking. So here I give you a solution that you can create any recyclerview adapter within 5 seconds using file template in Android Studio. So, Lets read this full article- First we open android studio and create a project. After project creation  Open File->new->Edit File Template... Follow this below screenshot Okay, After click on "Edit File Template" a popup is open "File and Code Template", Now click on the  " + " icon and set set your template name. Now set your template name, template extension and template body. after doing everything click on "Apply" and then click on "OK" The template body I after after the screenshot Template Body Copy this code and paste it on the template body section, which I marked in scre...