我正在为一组用户创建一个用于实时gps跟踪的应用程序。我设法在地图上用标记显示每个用户的位置(地图活动-使用Google Maps),并且每5秒更新一次地图上的位置(我在以下位置更新了用户的“经度”和“纬度”字段Firebase数据库每3秒更新一次,然后每5秒阅读一次此字段并更新地图上的所有标记。
我尝试在3部不同的手机上四处走动,发现并不是所有的标记(它并不总是相同的标记,但是如果某个标记贴在一个电话上,那么同一标记贴在另一部电话上)正在移动我走路的时候他们开始时会移动一小段时间,然后完全停止移动。在我走了一段时间之后,它们突然更新(跳到当前位置),然后又卡住了...换句话说,某些标记的更新发生了很大的延迟。
这种延迟的原因可能是什么,我该如何解决?
我的Firebase数据库的图片(管理员和用户):
Pictures of my Firebase Database - Managers
Pictures of my Firebase Database - Users
(我创建了一个代表组的管理器,并且该管理器具有该组中的用户列表,然后浏览该管理器的用户列表并更新了它们在Firebase数据库上的位置。用户单击“地图”按钮,它会转到GroupMapActivity,然后每隔5秒钟从Firebase Databse中读取一次位置,然后更新标记。)
使用服务在Firebase数据库上更新位置的代码:
package com.example.lidor.findmygroup;
import android.app.IntentService;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.HashMap;
import java.util.Map;
public class FindMeService extends IntentService
{
FirebaseDatabase firebaseDatabase;
DatabaseReference databaseReference;
String userEmail = "", key = "";
LocationTrack locationTrack;
double longitude, latitude;
User user;
public FindMeService()
{
super("FindMeService");
}
@Override
protected void onHandleIntent(Intent intent)
{
firebaseDatabase = FirebaseDatabase.getInstance();
if (intent.hasExtra("email"))
userEmail = intent.getStringExtra("email").toString();
databaseReference = firebaseDatabase.getReference("USERS");
databaseReference.addValueEventListener(new ValueEventListener()
{
@Override
public void onDataChange(DataSnapshot dataSnapshot)
{
for (DataSnapshot d : dataSnapshot.getChildren())
{
User curUser = d.getValue(User.class);
if (userEmail.equals(curUser.Email))
{
key = d.getKey();
user = curUser;
break;
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
while (true)
{
try
{
Thread.sleep(3000);
locationTrack = new LocationTrack(FindMeService.this);
if (locationTrack.canGetLocation())
{
longitude = locationTrack.getLongitude();
latitude = locationTrack.getLatitude();
databaseReference.child("USERS").child(key).
addListenerForSingleValueEvent(new ValueEventListener()
{
@Override
public void onDataChange(DataSnapshot dataSnapshot)
{
Map<String, Object> updates = new HashMap<>();
for (DataSnapshot s : dataSnapshot.getChildren())
{
updates.put(s.getKey(), s.getValue());
}
updates.put("UserName", user.UserName);
updates.put("Age", user.Age);
updates.put("Phone", user.Phone);
updates.put("City", user.City);
updates.put("Email", user.Email);
updates.put("longitude", longitude);
updates.put("latitude", latitude);
updates.put("Is_In_Group", user.Is_In_Group);
updates.put("ManagerEmail", user.ManagerEmail);
updates.put("Is_Manager", user.Is_Manager);
updates.put("Is_Connected", user.Is_Connected);
databaseReference.child(key).updateChildren(updates);
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
else
{
locationTrack.showSettingsAlert();
Toast.makeText(FindMeService.this, "No GPS signal",
Toast.LENGTH_LONG).show();
}
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
@Override
public void onDestroy()
{
super.onDestroy();
}
}
组图活动:
package com.example.lidor.findmygroup;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class GroupMapActivity extends FragmentActivity implements OnMapReadyCallback
{
private GoogleMap mMap;
Handler handler;
String email = "", managerEmail = "", managerKey = "";
int i = 0;
Marker marker;
FirebaseAuth firebaseAuth;
FirebaseDatabase firebaseDatabase, firebaseDatabase1, firebaseDatabase2;
DatabaseReference databaseReference, databaseReference1, databaseReference2;
Boolean endFor = false, endFor1 = false, endFor2 = false;
ProgressDialog progressDialog;
HashMap<String, Marker> markers;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_group_map);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
firebaseAuth = FirebaseAuth.getInstance();
firebaseDatabase = FirebaseDatabase.getInstance();
firebaseDatabase1 = FirebaseDatabase.getInstance();
firebaseDatabase2 = FirebaseDatabase.getInstance();
//builder = new LatLngBounds.Builder();
Intent intent = getIntent();
if (intent.hasExtra("email")) email = intent.getStringExtra("email").toString();
markers = new HashMap<>();
progressDialog = new ProgressDialog(GroupMapActivity.this);
progressDialog.setMessage("Map Loading Please Wait...");
progressDialog.show();
}
@Override
public void onMapReady(GoogleMap googleMap)
{
mMap = googleMap;
handler = new Handler();
handler.postDelayed(new Runnable()
{
public void run()
{
Real_Time_Group_Map();
progressDialog.dismiss();
handler.postDelayed(this, 1000);
}
}, 1000);
}
public void Real_Time_Group_Map()
{
// 1# -------------------------------------------------------------------------------------
databaseReference = firebaseDatabase.getReference("USERS");
databaseReference.addValueEventListener(new ValueEventListener()
{
@Override
public void onDataChange(DataSnapshot dataSnapshot)
{
for (DataSnapshot d : dataSnapshot.getChildren())
{
if (endFor) continue;
User curUser = d.getValue(User.class);
if (email.equals(curUser.Email))
{
endFor = true;
managerEmail = curUser.ManagerEmail;
databaseReference = firebaseDatabase.getReference("MANAGERS");
databaseReference.addValueEventListener(new ValueEventListener()
{
@Override
public void onDataChange(DataSnapshot dataSnapshot)
{
for (DataSnapshot d : dataSnapshot.getChildren())
{
if (endFor1) continue;
Manager curManager = d.getValue(Manager.class);
if (managerEmail.equals(curManager.Email))
{
endFor1 = true;
managerKey = d.getKey();
databaseReference1 = firebaseDatabase1.getReference("MANAGERS").
child(managerKey).child("Group Users");
databaseReference1.addValueEventListener(new ValueEventListener()
{
@Override
public void onDataChange(DataSnapshot dataSnapshot)
{
for (DataSnapshot d : dataSnapshot.getChildren())
{
final String curFriend = d.getValue().toString();
databaseReference2 = firebaseDatabase2.getReference("USERS");
databaseReference2.addValueEventListener(new ValueEventListener()
{
@Override
public void onDataChange(DataSnapshot dataSnapshot)
{
for (DataSnapshot d : dataSnapshot.getChildren())
{
User curUser = d.getValue(User.class);
String emailUser = curUser.Email;
if (curFriend.equals(emailUser))
{
LatLng location = new LatLng(
curUser.latitude, curUser.longitude);
Marker delMarker = markers.get(emailUser);
if (delMarker != null) delMarker.remove();
markers.remove(emailUser);
if (curUser.Is_Manager)
{
marker = mMap.addMarker(new MarkerOptions()
.position(location).title(curUser.UserName).icon(
BitmapDescriptorFactory.defaultMarker(
BitmapDescriptorFactory.HUE_BLUE)).
snippet(emailUser));
}
else
{
marker = mMap.addMarker(new MarkerOptions()
.position(location).title(curUser.UserName)
.snippet(emailUser));
}
markers.put(emailUser, marker);
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(location,18));
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener()
{
@Override
public boolean onMarkerClick(Marker marker)
{
Intent intent = new Intent(GroupMapActivity.this, MemberActivity.class);
intent.putExtra("email", marker.getSnippet());
startActivity(intent);
return false;
}
});
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
break;
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
break;
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}