'Get current location inside a fragment
I need to get the current location of the user and store its values in separate longitude and latitude variables. Right now in the following code I have set them statically.
Here is my Location Fragment (all my fragments are displayed inside an Activity using viewpager):
package com.example.atry.MakeComplaint
import Retrofit.INodeJS
import Retrofit.Observables
import Retrofit.RetrofitClient
import android.app.Activity
import android.content.ContentValues.TAG
import android.content.Context
import android.content.Context.*
import android.content.Intent
import android.content.IntentSender
import android.content.pm.PackageManager
import android.location.*
import android.net.Uri
import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.google.android.gms.maps.MapView
import android.widget.LinearLayout
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.example.atry.R
import com.google.android.gms.common.GooglePlayServicesNotAvailableException
import com.google.android.gms.common.api.ResolvableApiException
import com.google.android.gms.dynamic.SupportFragmentWrapper
import com.google.android.gms.location.*
import com.google.android.gms.maps.*
import com.google.android.gms.maps.model.*
import io.reactivex.disposables.CompositeDisposable
import kotlinx.android.synthetic.main.fragment_complaint_details.view.*
import kotlinx.android.synthetic.main.fragment_location.*
import kotlinx.android.synthetic.main.fragment_location.view.*
import retrofit2.Call
import retrofit2.Response
import java.io.IOException
import java.util.Observer
import java.util.Optional.empty
import javax.security.auth.callback.Callback
class LocationFragment : Fragment(), OnMapReadyCallback, GoogleMap.OnMarkerClickListener {
override fun onMarkerClick(p0: Marker?)= false
private lateinit var map: GoogleMap
private lateinit var mapView : MapView
// lateinit var typeName: String
lateinit var myAPI: INodeJS
var MyCategory: Observables.ComplaintType?=null
private var listener: OnLocationFragmentInteractionListener? = null
var objectComplaint =
Observables.Complaint(
1 , "dummy problem" ,
"url" ,
Observables.Location("78.4","17.4"),
Observables.ComplaintType("Smell", "null"),
Observables.Status(2 , "Unresolved")
)
//for updating user's location/ for current location
private lateinit var fusedLocationClient: FusedLocationProviderClient
private lateinit var lastLocation: Location
private lateinit var locationCallback: LocationCallback
private lateinit var locationRequest: LocationRequest
private var locationUpdateState = false
companion object {
private const val LOCATION_PERMISSION_REQUEST_CODE = 1
private const val REQUEST_CHECK_SETTINGS = 2 //For updating user's location as they move
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val permissions = arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_COARSE_LOCATION)
requestPermissions( permissions,0)
arguments?.let {
}
//INIT API
val retrofit = RetrofitClient.instanc
myAPI = retrofit.create(INodeJS::class.java)
//static way of bringing category names
// if(arguments!!.getString("typeName") !=null){
//
// typeName =arguments!!.getString("typeName")
// Log.d("got it!!",typeName)
//
// }
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val v = inflater.inflate(com.example.atry.R.layout.fragment_location, container, false)
mapView = v.findViewById(R.id.maps)
mapView.onCreate(savedInstanceState)
mapView.onResume()
try {
MapsInitializer.initialize(getActivity()!!.getApplicationContext());
} catch (sendEx: IntentSender.SendIntentException) {
sendEx.printStackTrace();
}
mapView.getMapAsync(this)
v.backToList.setOnClickListener {
backFragment()
}
v.forwardToDescription.setOnClickListener{
getAllData()
}
return v
}
override public fun onResume() {
super.onResume();
mapView.onResume();
}
override public fun onPause() {
super.onPause();
mapView.onPause();
}
override public fun onDestroy() {
super.onDestroy();
mapView.onDestroy();
}
override public fun onLowMemory() {
super.onLowMemory();
mapView.onLowMemory()
}
override fun onMapReady(googleMap: GoogleMap?) {
map = googleMap!!
map.uiSettings?.isZoomControlsEnabled = true
map.isMyLocationEnabled = true
// var criteria = Criteria()
// var locationManager = context!!.getSystemService(LOCATION_SERVICE) as LocationManager
// var provider = locationManager.getBestProvider(criteria, true)
// var location = locationManager.getLastKnownLocation(provider)
// var latitude = location.latitude
// var longitude = location.longitude
// latitude and longitude
val latitude = 17.385044
val longitude = 78.486671
val marker = MarkerOptions().position(LatLng(latitude,longitude)).title("hello maps")
marker.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED))
map.addMarker(marker)
val cameraPosition = CameraPosition.builder().target(LatLng(latitude,longitude)).zoom(12f).build()
map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition))
}
private fun backFragment() {
val manager = (context as AppCompatActivity).supportFragmentManager
manager.popBackStackImmediate()
}
fun sendCategoryItem(category: Observables.ComplaintType) {
this.MyCategory = category
Log.d("here", "i am here 1")
Log.d("here", MyCategory.toString())
}
fun getAllData(){
val latitude = 17.4
val longitude = 78.4
// LocationUtils().getInstance(appContext)
// LocationUtils().getLocation().observe(this, Observer {loc: Location? ->
// location = loc!!
// // Yay! location recived. Do location related work here
// Log.i(TAG,"Location: ${location.latitude} ${location.longitude}")
//
// })
var typename = MyCategory!!.typeName.toString()
val call = myAPI.checkExistingComplain(typename,longitude.toString(), latitude.toString() )
Log.d("T", typename)
Log.d("Lo", longitude.toString())
Log.d("La", latitude.toString())
call.enqueue(object : retrofit2.Callback<Observables.checkExistingResult> {
override fun onFailure(call: Call<Observables.checkExistingResult>?, t: Throwable?) {
Log.d("NO", t!!.message)
}
override fun onResponse(call: Call<Observables.checkExistingResult>?, response: Response<Observables.checkExistingResult>?) {
if(response?.body()?.Complain ==null) {
setExistingData(response!!.body()!!.Complain)
descriptionFragment()
// notifyDataSetChanged()
}
else if(response!!.code() == 200){
Log.d("YES", "200")
Log.d("response", response.body().toString())
objectComplaint = response.body()!!.Complain
Log.d("got the complaint",objectComplaint.toString())
setExistingData(objectComplaint)
existPopup()
}
else if(response!!.code() == 201){
Log.d("response", response.body().toString())
// alreadyMadeComplaintPopup()
}
else{
descriptionFragment()
}
val item = objectComplaint
listener?.onLocationFragmentInteraction(item)
}
})
}
interface OnLocationFragmentInteractionListener {
// TODO: Update argument type and name
fun onLocationFragmentInteraction(item: Observables.Complaint?)
}
override fun onAttach(context: Context) {
super.onAttach(context)
if (context is OnLocationFragmentInteractionListener) {
listener = context as OnLocationFragmentInteractionListener
} else {
throw RuntimeException("$context must implement OnLocationFragmentInteractionListener")
}
}
fun setExistingData(test: Observables.Complaint) {
objectComplaint = test
}
//opening up the checkExisting popup
private fun existPopup(){
val fm = activity!!.supportFragmentManager
val dialog = PopupDialog() // creating new object
dialog.show(fm, "dialog")
}
private fun descriptionFragment() {
val dFragment= Category_Description()
val lFragment = LocationFragment()
val manager = (context as AppCompatActivity).supportFragmentManager
val transaction = manager.beginTransaction()
transaction.replace(
R.id.location_screen,
dFragment
) // give your fragment container id in first parameter
transaction.show(dFragment)
transaction.hide(lFragment)
transaction.isAddToBackStackAllowed
transaction.addToBackStack(lFragment.fragmentManager.toString()) // if written, this transaction will be added to backstack
transaction.commit()
}
}
What can I try next?
Solution 1:[1]
Here look at this example: GpsUtils
Its pretty self explanatory. Just call GpsUtils.getInstance().findDeviceLocation(activity) from your fragment and after that accessing the static latitude and longitude variables in the GpsUtils class should give you the current locations. Note: Theres scope for improvement regarding the design of this class but it does the job pretty fine.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | because_im_batman |
