在地图上同时显示多个用户的位置(Kotlin、Firebase 实时数据库)
Posted
技术标签:
【中文标题】在地图上同时显示多个用户的位置(Kotlin、Firebase 实时数据库)【英文标题】:Show multiple user`s location at the same time on a map (Kotlin, Firebase Realtime Database) 【发布时间】:2021-07-29 18:13:18 【问题描述】:这个问题反映了上一个问题:Show multiple registered user`s location on the same map (android Studio, Firebase, Kotlin)
我的主要问题是我在 Android Studio 中创建了一个聊天应用程序,并且还使用 Google Api 添加了一个地图活动。我正在使用 Firebase 实时数据库,这就是我的树目前的样子:
我希望“用户位置”出现在每个注册用户的下方,因此所有注册用户的位置都会作为标记出现在我的 Google 地图上。
这是我的 MapsActivity:
class MapsActivity : AppCompatActivity(), OnMapReadyCallback
companion object
var currentUser: User? = null
val TAG = "MapsActivity"
private lateinit var map: GoogleMap
private val LOCATION_PERMISSION_REQUEST = 1
private lateinit var fusedLocationClient: FusedLocationProviderClient
private lateinit var locationRequest: LocationRequest
private lateinit var locationCallback: LocationCallback
private fun getLocationAccess()
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED)
map.isMyLocationEnabled = true
getLocationUpdates()
startLocationUpdates()
else
ActivityCompat.requestPermissions(this, arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION), LOCATION_PERMISSION_REQUEST)
private fun getLocationUpdates()
locationRequest = LocationRequest()
locationRequest.interval = 30000
locationRequest.fastestInterval = 20000
locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
locationCallback = object : LocationCallback()
override fun onLocationResult(locationResult: LocationResult)
if (locationResult.locations.isNotEmpty())
val location = locationResult.lastLocation
// val uid = FirebaseAuth.getInstance().currentUser?.uid
// val rootRef = FirebaseFirestore.getInstance()
// val usersRef = rootRef.collection("users")
// val uidRef = uid?.let usersRef.document(it)
// if (uidRef != null)
// uidRef.get()
// .addOnSuccessListener document ->
// if (document != null)
// val latitude = document.getDouble("latitude")
// val longitude = document.getDouble("longitude")
// Log.d(TAG, ", " + location.latitude + location.longitude)
// else
// Log.d(TAG, "No such document")
//
//
// .addOnFailureListener exception ->
// Log.d(TAG, "get failed with ", exception)
//
//
lateinit var databaseRef: DatabaseReference
databaseRef = Firebase.database.reference
val locationlogging = LocationLogging(location.latitude, location.longitude)
databaseRef.child("/userlocation").setValue(locationlogging)
.addOnSuccessListener
Toast.makeText(applicationContext, "Locations written into the database", Toast.LENGTH_LONG).show()
.addOnFailureListener
Toast.makeText(applicationContext, "Error occured while writing your location to the database", Toast.LENGTH_LONG).show()
@SuppressLint("MissingPermission")
private fun startLocationUpdates()
fusedLocationClient.requestLocationUpdates(locationRequest,locationCallback, null)
@SuppressLint("MissingPermission")
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray)
if (requestCode == LOCATION_PERMISSION_REQUEST)
if (grantResults.contains(PackageManager.PERMISSION_GRANTED))
map.isMyLocationEnabled = true
else Toast.makeText(this, "User has not granted location access permission", Toast.LENGTH_LONG).show()
finish()
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_maps)
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
val mapFragment = supportFragmentManager
.findFragmentById(R.id.map) as SupportMapFragment
mapFragment.getMapAsync(this)
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
override fun onMapReady(googleMap: GoogleMap)
map = googleMap
getLocationAccess()
override fun onCreateOptionsMenu(menu: Menu?): Boolean
menuInflater.inflate(R.menu.nav_menu_map, menu)
return super.onCreateOptionsMenu(menu)
我注释掉了一些代码,因为我无法正确实现它。当我运行代码时,经纬度出现在我的 Logcat 中,但在我的实时数据库中,它清除了 /users 下的所有数据,并被经纬度替换。
这是我的位置记录:
import com.google.firebase.database.IgnoreExtraProperties
@IgnoreExtraProperties
data class LocationLogging(
var Latitude: Double? = 0.0,
var Longitude: Double? = 0.0
)
我正在寻找一种简单的方法,将坐标放入我的每个注册用户下的 Firebase 实时数据库中,并同时在地图上显示所有位置。
【问题讨论】:
【参考方案1】:您可以通过firebase auth SDK获取当前用户并更改保存数据的路径以将其保存在用户路径下。您需要更改这部分代码:
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
lateinit var databaseRef: DatabaseReference
databaseRef = Firebase.database.reference
val locationlogging = LocationLogging(location.latitude, location.longitude)
databaseRef.child("users").child(user.getUid()).child("userlocation").setValue(locationlogging)
.addOnSuccessListener
Toast.makeText(applicationContext, "Locations written into the database", Toast.LENGTH_LONG).show()
.addOnFailureListener
Toast.makeText(applicationContext, "Error occured while writing your location to the database", Toast.LENGTH_LONG).show()
【讨论】:
谢谢,它成功了。我一直在寻找这个解决方案很长时间了。纬度和经度现在保存在我的每个用户下。但是,它不会在地图上显示所有用户的位置。它只显示设备的位置。您知道使标记同时出现在同一张地图上的另一种方法吗?谢谢 谢谢。很高兴听到。您能否在另一个问题中解释一下并显示一些代码。 上面提供了我的谷歌地图活动,我认为这是应该去的地方,但我可能错了。我的其他活动是注册/登录/消息传递页面。谷歌地图一次只显示一台设备的位置。我还从我的另一台设备为另一位用户登录,但该用户也显示 1 个标记。我想在同一张地图中同时显示所有在线用户的位置。有可能吗? 你能在另一个问题中发布。在这里将两者都放在一个上将是太多了。以上是关于在地图上同时显示多个用户的位置(Kotlin、Firebase 实时数据库)的主要内容,如果未能解决你的问题,请参考以下文章
Google Maps API 仅显示一个用户位置,但 Firebase 上保存了多个用户位置(Kotlin android 应用)