Я создаю приложение для отслеживания GPS в реальном времени для группы пользователей.Мне удалось отобразить местоположение каждого пользователя с маркером на карте (активность на карте - с помощью Google Maps), а также обновлять местоположение на карте каждые 5 секунд (я обновляю поля «долгота» и «широта» пользователя вБаза данных Firebase каждые 3 секунды, а затем читайте эти поля каждые 5 секунд и обновляйте все маркеры на карте).
Я попытался обойти 3 разных телефона и заметил, что не все маркеры (это не всегдате же маркеры, но если какой-то маркер застрял на одном телефоне, тот же самый маркер на других телефонах) движется со мной, когда я иду.Вначале они начинают двигаться в течение небольшого промежутка времени, а затем вообще перестают двигаться.После того, как я продолжаю идти некоторое время, они внезапно обновляются (переходят к текущему местоположению), а затем снова застревают ... Или, другими словами, обновление некоторых маркеров происходит с большими задержками.
Что может бытьпричина таких задержек и как я могу это исправить?
Картинки моей базы данных Firebase (менеджеры и пользователи):
Картинки моей базы данных Firebase - менеджеры
Изображения моей базы данных Firebase - пользователи
(я создаю менеджера, представляющего группу, и у менеджера есть список пользователей, которые находятся в егогруппы, а затем я просматриваю список пользователей менеджера и обновляю их местоположение в базе данных Firebase. Затем, когда пользователь нажимает кнопку «карта», он проходит к GroupMapActivity и там я читаю местоположения из базы данных Firebase каждые 5 секунд иобновить маркеры).
Код для обновления местоположения в базе данных 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();
}
}
Карта группы Acтивность:
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) {
}
});
}
}