android - 实时位置跟踪更新延迟
问题描述
我正在为一组用户创建一个用于实时 gps 跟踪的应用程序。我设法在地图上用标记显示每个用户位置(地图活动 - 使用谷歌地图),并且每 5 秒更新一次地图上的位置(我更新用户的“经度”和“纬度”字段Firebase 数据库每 3 秒一次,然后每 5 秒读取一次此字段并更新地图上的所有标记)。
我试着用 3 部不同的手机四处走动,并注意到并非所有的标记(它并不总是相同的标记,但如果某个标记卡在一部手机上,则相同的标记卡在其他手机上)随着我一起移动走。他们开始移动一小段时间,然后完全停止移动。在我继续走一会儿之后,它们突然更新(跳到当前位置)然后又卡住了......或者换句话说,一些标记的更新发生了很大的延迟。
这种延迟的原因可能是什么,我该如何解决?
我的 Firebase 数据库(经理和用户)的图片:
(我创建了一个代表一个组的经理,经理有一个在他的组中的用户列表,然后我浏览经理的用户列表并更新他们在 Firebase 数据库上的位置。然后当用户点击“地图”按钮通过 GroupMapActivity 并在那里我每 5 秒从 Firebase 数据库读取位置并更新标记)。
使用服务更新 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) {
}
});
}
}
解决方案
推荐阅读
- javascript - IE 11 的选项组问题
- css - Chrome 在移动视图上的滚动条位置问题
- facebook - 新域未得到验证。错误 - URL 被阻止:此重定向失败,因为重定向 URI 未列入白名单
- angular - 使用闪屏检测应用程序何时以离子/角度完全加载
- json - 小值的 Elasticsearch 查询范围精度问题
- r - 问题在行动按钮
- node.js - 在 prod 的同一台机器上安装两个 nodeJs 版本是否安全
- javascript - 使用 Cloud Functions 从 Firebase Storage 获取下载网址
- python - 刷新页面时烧瓶网站重复返回值
- opencv - 无法在 cnn 中获取图像通道