Получить местоположение устройства не работает в моем коде?

#android #kotlin #location #android-permissions

#Android #котлин #Расположение #android-разрешения

Вопрос:

Я пытаюсь указать местоположение устройства в профиле пользователя, используя разрешения на местоположение как для грубого, так и для точного. Код запрашивает разрешения, и когда он предоставляется, он обновляет поля только иногда, я не могу понять, что не так, поскольку я процедурно проверяю разрешения, а затем заполняю поля, когда разрешение было предоставлено … мой код ниже (Kotlin)

 EditProfile : AppCompatActivity() {

var usersReference: DatabaseReference? = null
var firebaseUser: FirebaseUser? = null
private val RequestCode = 438 //To enable redirect to phone gallery to select image
private var imageUri: Uri? = null //Uploaded Image URI
private var storageRef: StorageReference? = null //To enable storing on Firebase DB
private var profileImageChk: String? =
    ""   //to check if user is going to change the profile image
private var socialChk: String? = ""

//Location Manager
lateinit var fusedLocationProviderClient: FusedLocationProviderClient
lateinit var locationRequest: LocationRequest
val PERMISSION_ID = 1010


override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_edit_profile1)
    setSupportActionBar(toolbar_editpro1)

    val toolbar: Toolbar = findViewById(R.id.toolbar_editpro1)
    setSupportActionBar(toolbar)
    supportActionBar!!.title = "Edit Profile"
    supportActionBar!!.setDisplayHomeAsUpEnabled(true)

    val cityname = findViewById<EditText>(R.id.editLocation)
    val countryname = findViewById<EditText>(R.id.edit_user_country)

    //Character Count for About
    edit_user_desc.addTextChangedListener(object : TextWatcher {
        override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
            val length: Int = edit_user_desc.length()
            val convert = "$length/300"
            edit_desc_count.text = convert
            if (length > 300) {
                edit_desc_count.setTextColor(resources.getColor(R.color.colorPrimaryDark));
            }
        }

        override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
        override fun afterTextChanged(s: Editable) {}
    })

    //Location Manager
    fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)

    location_btn.setOnClickListener {
        RequestPermission()
        /* fusedLocationProviderClient.lastLocation.addOnSuccessListener{location: Location? ->
             textView.text = location?.latitude.toString()   ","   location?.longitude.toString()
         }*/
        getLastLocation()
    }

    //Creating firebase authorization for current user
    firebaseUser = FirebaseAuth.getInstance().currentUser
    usersReference =
        FirebaseDatabase.getInstance().reference.child("Users").child(firebaseUser!!.uid)
    storageRef = FirebaseStorage.getInstance().reference.child("App User Images")
    usersReference!!.addValueEventListener(object : ValueEventListener {

        override fun onDataChange(p0: DataSnapshot) {
            if (p0.exists()) {
                val user: Users? = p0.getValue(Users::class.java)
                if (user != null) {
                    edit_profile_name?.setText(user.getFirstName())
                    edit_profile_surname?.setText(user.getSurName())
                    Picasso.get().load(user.getProfile())
                        .placeholder(R.drawable.ic_baseline_whatshot_24).fit().centerCrop()
                        .into(edit_profile_image)
                    edit_comp_name?.setText(user.getCname())
                    edit_desig_name?.setText(user.getRole())
                    edit_user_desc?.setText(user.getAbout())
                    cityname.setText(user.getCity())
                    countryname.setText(user.getCountry())
                }
            }
        }

        override fun onCancelled(p0: DatabaseError) {

        }
    })

    //connecting to the display widget
    edit_profile_image.setOnClickListener {
        profileImageChk = "profile"
        selectImage()
    }

    user_profile_save.setOnClickListener {
        val name = edit_profile_name.text.toString()
        val surname = edit_profile_surname.text.toString()
        val role = edit_desig_name.text.toString()
        val cname = edit_comp_name.text.toString()
        val about = edit_user_desc.text.toString()
        val cityn = editLocation.text.toString()
        val countryn = edit_user_country.text.toString()

        if (name == "") {
            Toast.makeText(this, "Please enter your name", Toast.LENGTH_LONG).show()
        } else if (surname == "") {
            Toast.makeText(this, "Please enter your surname", Toast.LENGTH_LONG).show()
        } else if (role == "") {
            Toast.makeText(
                this,
                "Please enter your designation or a headline",
                Toast.LENGTH_LONG
            ).show()
        } else if (about == "") {
            Toast.makeText(
                this,
                "Please enter a brief description about yourself",
                Toast.LENGTH_LONG
            ).show()
        } else if (cityn == "") {
            Toast.makeText(this, "Please click on - Use Current Location", Toast.LENGTH_LONG)
                .show()
        } else {
            //to save message on Firebase
            val usersHashMap = HashMap<String, Any?>()
            usersHashMap["firstname"] = name
            usersHashMap["surname"] = surname
            usersHashMap["role"] = role
            usersHashMap["cname"] = cname
            usersHashMap["about"] = about
            usersHashMap["city"] = cityn
            usersHashMap["country"] = countryn

            usersReference!!.updateChildren(usersHashMap)
                .addOnCompleteListener { task ->
                    if (task.isSuccessful) {
                        Toast.makeText(this, "Details Updated.", Toast.LENGTH_LONG).show()
                    }
                }
        }
    }
}

private fun selectImage() {
    val intent = Intent()
    intent.type = "image/*"
    intent.action = Intent.ACTION_GET_CONTENT
    startActivityForResult(intent, RequestCode)
}

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

    if (requestCode == RequestCode amp;amp; resultCode == Activity.RESULT_OK amp;amp; data!!.data != null) {
        imageUri = data.data
        Toast.makeText(this@EditProfile, "uploading the image", Toast.LENGTH_LONG).show()
        uploadImageToDatabase()
    }
}

private fun uploadImageToDatabase() {
    if (imageUri != null) {
        //creating a unique storage reference so that there are no duplicates
        val fileRef = storageRef!!.child(System.currentTimeMillis().toString()   ".jpg")
        val uploadTask: StorageTask<*>
        uploadTask = fileRef.putFile(imageUri!!)
        uploadTask.continueWithTask(Continuation<UploadTask.TaskSnapshot, Task<Uri>>
        { task ->
            if (!task.isSuccessful) {
                task.exception?.let {
                    throw it
                }
            }
            return@Continuation fileRef.downloadUrl
        }).addOnCompleteListener { task ->
            if (task.isSuccessful) {
                val downloadUrl = task.result
                val url = downloadUrl.toString()
                //to check if user is going to change the profile image
                if (profileImageChk == "profile") {
                    val mapProfileImg = HashMap<String, Any>()
                    mapProfileImg["profile"] = url
                    usersReference!!.updateChildren(mapProfileImg)
                }
            } else {
                Toast.makeText(this, "Please Upload an Image", Toast.LENGTH_SHORT).show()
            }
        }

    }
}

private fun CheckPermission(): Boolean {
    //this function will return a boolean
    //true: if we have permission
    //false if not
    if (
        ActivityCompat.checkSelfPermission(
            this,
            android.Manifest.permission.ACCESS_COARSE_LOCATION
        ) == PackageManager.PERMISSION_GRANTED ||
        ActivityCompat.checkSelfPermission(
            this,
            android.Manifest.permission.ACCESS_FINE_LOCATION
        ) == PackageManager.PERMISSION_GRANTED
    ) {
        return true
    }
    return false
}

private fun RequestPermission() {
    //this function will allows us to tell the user to request the necessary permission if they are not granted
    ActivityCompat.requestPermissions(
        this,
        arrayOf(
            android.Manifest.permission.ACCESS_COARSE_LOCATION,
            android.Manifest.permission.ACCESS_FINE_LOCATION
        ),
        PERMISSION_ID
    )
}

private fun isLocationEnabled(): Boolean {
    //this function will return to us the state of the location service
    //if the gps or the network provider is enabled then it will return true otherwise it will return false
    val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
    return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager.isProviderEnabled(
        LocationManager.NETWORK_PROVIDER
    )
}

private fun getLastLocation() {
    val cityname = findViewById<EditText>(R.id.editLocation)
    val countryname = findViewById<EditText>(R.id.edit_user_country)

    if (CheckPermission()) {
        if (isLocationEnabled()) {
            if (ActivityCompat.checkSelfPermission(
                    this,
                    Manifest.permission.ACCESS_FINE_LOCATION
                ) != PackageManager.PERMISSION_GRANTED amp;amp; ActivityCompat.checkSelfPermission(
                    this,
                    Manifest.permission.ACCESS_COARSE_LOCATION
                ) != PackageManager.PERMISSION_GRANTED
            ) {
                // TODO: Consider calling
                //    ActivityCompat#requestPermissions
                // here to request the missing permissions, and then overriding
                //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                //                                          int[] grantResults)
                // to handle the case where the user grants the permission. See the documentation
                // for ActivityCompat#requestPermissions for more details.
                return
            }
            fusedLocationProviderClient.lastLocation.addOnCompleteListener { task ->
                val location: Location? = task.result
                if (location == null) {
                    NewLocationData()
                } else {
                    val cityn = getCityName(location.latitude, location.longitude)
                    val countryn = getCountryName(location.latitude, location.longitude)
                    Toast.makeText(this, "$cityn amp; $countryn", Toast.LENGTH_SHORT)
                        .show()
                    cityname.setText(cityn)
                    countryname.setText(countryn)
                }
            }
        } else {
            Toast.makeText(this, "Please turn on your device location.", Toast.LENGTH_SHORT)
                .show()
        }
    } else {
        RequestPermission()
    }
}

private fun NewLocationData() {
    val locationRequest = LocationRequest()
    locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
    locationRequest.interval = 0
    locationRequest.fastestInterval = 0
    locationRequest.numUpdates = 1
    fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)
    if (ActivityCompat.checkSelfPermission(
            this,
            Manifest.permission.ACCESS_FINE_LOCATION
        ) != PackageManager.PERMISSION_GRANTED amp;amp; ActivityCompat.checkSelfPermission(
            this,
            Manifest.permission.ACCESS_COARSE_LOCATION
        ) != PackageManager.PERMISSION_GRANTED
    ) {
        // TODO: Consider calling
        //    ActivityCompat#requestPermissions
        // here to request the missing permissions, and then overriding
        //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
        //                                          int[] grantResults)
        // to handle the case where the user grants the permission. See the documentation
        // for ActivityCompat#requestPermissions for more details.
        return
    }
    fusedLocationProviderClient.requestLocationUpdates(
        locationRequest, locationCallback, Looper.myLooper()
    )
}

private val locationCallback = object : LocationCallback() {
    override fun onLocationResult(locationResult: LocationResult) {
        val lastLocation: Location = locationResult.lastLocation
        val cityname = findViewById<EditText>(R.id.editLocation)
        val countryname = findViewById<EditText>(R.id.edit_user_country)

        val cityn = getCityName(lastLocation.latitude, lastLocation.longitude)
        val countryn = getCountryName(lastLocation.latitude, lastLocation.longitude)

        cityname.setText(cityn)
        countryname.setText(countryn)
    }
}

private fun getCityName(lat: Double, long: Double): String {
    var cityName: String = ""
    val geoCoder = Geocoder(this, Locale.getDefault())
    val Address = geoCoder.getFromLocation(lat, long, 3)

    cityName = Address.get(0).locality
    return cityName
}

private fun getCountryName(lat: Double, long: Double): String {
    var countryName = ""
    val geoCode = Geocoder(this, Locale.getDefault())
    val Address = geoCode.getFromLocation(lat, long, 3)

    countryName = Address.get(0).countryName
    return countryName
}
 

}

Комментарии:

1. В вашем коде есть несколько проблем. вы запрашиваете разрешение на местоположение, но результат не обрабатывается.

2. Привет, Мэйбл, не могли бы вы указать на них ?…

Ответ №1:

Я надеюсь, что вы дали

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

разрешения в манифесте и не использовать эмулятор. вам также необходимо запросить разрешение времени выполнения для устройства с более высокой версией Android.

Ваш код хорош. Рассмотрите возможность создания для него другого класса, который расширяет класс обслуживания и реализует LocationListener

 class LocationTrack extends Service implements LocationListener
 

Надеюсь, это поможет.

https://site-valley.com/2021/02/23/get-location-android-example-kotlin/