在地图上同时显示多个用户的位置(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 应用)

IOS |在地图上显示多个自选位置

怎样在百度地图上同时标注多个位置

高德地图怎样实现实时定位,得到当前地点的坐标,位置

如何在android中的谷歌地图上绘制路线并计算多个标记之间的距离

能够在黑莓地图中显示多个位置,但地图的位置是固定的。我无法放大和缩小