Android 如何在Kotlin中访问函数内部的局部变量

Android 如何在Kotlin中访问函数内部的局部变量,android,kotlin,Android,Kotlin,我正在Kotlin开发一个android应用程序,我创建了一些函数来获取位置经度和纬度,并将它们保存在变量中,一切都设置好了,现在我想将这些变量和另一个变量一起发送到firebase数据库,所以我创建了一个函数,在调用时将数据发送到firebase,并在其中创建了一个数据类,我尝试将mlong和mlat设置为全局,但当发送到firebase时,它始终显示经度和纬度为0.0,这意味着longit和latit var从未改变 以下是我将“mlong”和“mlat”设置为全局变量时的活动代码: pac

我正在Kotlin开发一个android应用程序,我创建了一些函数来获取位置经度和纬度,并将它们保存在变量中,一切都设置好了,现在我想将这些变量和另一个变量一起发送到firebase数据库,所以我创建了一个函数,在调用时将数据发送到firebase,并在其中创建了一个数据类,我尝试将mlong和mlat设置为全局,但当发送到firebase时,它始终显示经度和纬度为0.0,这意味着longit和latit var从未改变

以下是我将“mlong”和“mlat”设置为全局变量时的活动代码:

package com.example.getlocation


import android.annotation.SuppressLint
import android.content.Intent
import android.graphics.Typeface
import android.location.Location
import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.google.android.gms.location.FusedLocationProviderClient
import com.google.android.gms.location.LocationServices
import com.google.firebase.database.FirebaseDatabase
import com.example.getlocation.SplashActivity.Companion.saveUF
import kotlinx.android.synthetic.main.activity_main.*
import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.location.LocationManager
import android.os.Looper
import android.provider.Settings
import android.widget.TextView
import androidx.core.app.ActivityCompat
import com.google.android.gms.location.*




class MainActivity : AppCompatActivity() {

val PERMISSION_ID = 42

lateinit var mFusedLocationClient: FusedLocationProviderClient

var mlat = 0.0
var mlong = 0.0

//firebase database
val mDatabase = FirebaseDatabase.getInstance()
val mRef = mDatabase.getReference("user").child("messages")


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

    //the font
    val typeface = Typeface.createFromAsset(assets, "Arslan-Wessam-B.ttf")
    // Set the typeface
    appName.typeface = typeface

    buSync.setOnClickListener {

        insertToFirebase()
    }
}



@SuppressLint("MissingPermission")
fun getLastLocation() {
    if (checkPermissions()) {
        if (isLocationEnabled()) {

            mFusedLocationClient.lastLocation.addOnCompleteListener(this) { task ->
                var location: Location? = task.result
                if (location == null) {
                    requestNewLocationData()
                } else {
                    mlat = location.latitude
                    mlong = location.longitude
                }
            }
        } else {
            Toast.makeText(this, "Turn on location", Toast.LENGTH_LONG).show()
            val intent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
            startActivity(intent)
        }
    } else {
        requestPermissions()
    }
}

//get location
@SuppressLint("MissingPermission")
private fun requestNewLocationData() {
    var mLocationRequest = LocationRequest()
    mLocationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
    mLocationRequest.interval = 0
    mLocationRequest.fastestInterval = 0
    mLocationRequest.numUpdates = 1

    mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
    mFusedLocationClient!!.requestLocationUpdates(
        mLocationRequest, mLocationCallback,
        Looper.myLooper()
    )
}

private val mLocationCallback = object : LocationCallback() {
    override fun onLocationResult(locationResult: LocationResult) {
        var mLastLocation: Location = locationResult.lastLocation
        mlong = mLastLocation.latitude
        mlat = mLastLocation.longitude
    }
}

private fun isLocationEnabled(): Boolean {
    var locationManager: LocationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
    return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager.isProviderEnabled(
        LocationManager.NETWORK_PROVIDER
    )
}

private fun checkPermissions(): Boolean {
    if (ActivityCompat.checkSelfPermission(
            this,
            Manifest.permission.ACCESS_COARSE_LOCATION
        ) == PackageManager.PERMISSION_GRANTED &&
        ActivityCompat.checkSelfPermission(
            this,
            Manifest.permission.ACCESS_FINE_LOCATION
        ) == PackageManager.PERMISSION_GRANTED
    ) {
        return true
    }
    return false
}

private fun requestPermissions() {
    ActivityCompat.requestPermissions(
        this,
        arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION),
        PERMISSION_ID
    )
}


override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
    if (requestCode == PERMISSION_ID) {
        if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
            getLastLocation()
        }
    }
}


fun insertToFirebase() {

    //get user location test
    mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
    getLastLocation()

    data class Insert(
        var et: String? = "",
        var un: String? = "",
        var msg: String? = "",
        var longit: Double? = 0.0,
        var latit: Double? = 0.0
    )

    //get shared preferences
    saveUF = getSharedPreferences("com.example.getlocation", MODE_PRIVATE)
    //get username value from shared preferences
    var username = saveUF?.getString("userName", "")



    //insert data to the object
    var insert = Insert(etUserNameTest.text.toString(), username, "hello", mlong, mlat)

    mRef.push().setValue(insert)
}
}
为此:

        textview1.text = mLastLocation.latitude.toString()
        textview2.text = mLastLocation.longitude.toString()
然后读取textview1和textview2中的文本并将其保存在var中,然后将其发送到firebase数据库,但这是一种不好的方法

有没有办法让定位函数更新mlong和mlat,或者在定位函数中定义它们并将它们用掉


编辑(已解决):代码没有问题,但在按钮上单击位置时,尚未将其带出,其默认值已发送到firebase,因此我必须单击两次,或者从oncreate调用函数,或者最好的方法是在带出位置时进行回调,同时放置进度条或其他内容,就这样

您应该在全局级别定义两个变量,并在函数内部更新它们。之后,您可以在任何地方方便地使用它。mlong和mlat是全局的,我在location函数中对它们进行了更新,但更新只是局部的,它从未在外部更改过。我要说的是,将保留字
this
放入以设置它们,并确保您正在设置全局变量。像
this.mlat
this.mlong
尝试用断点调试它。查看是否达到所有预期位置。尝试在此处打印lat long
else{mlat=location.latitude mlong=location.longitude}
        textview1.text = mLastLocation.latitude.toString()
        textview2.text = mLastLocation.longitude.toString()