geofire android 存储和检索位置并将其显示在地图上
Posted
技术标签:
【中文标题】geofire android 存储和检索位置并将其显示在地图上【英文标题】:geofire android to store and retrive locations and display it on map 【发布时间】:2017-04-18 23:00:04 【问题描述】:我正在用 android 开发一个出租车应用程序。我需要存储我的出租车的检索和更新位置,并使用 geofire 在地图上显示它。我已使用 firebase 进行身份验证。
需要一个完整的 android geofire 教程,但找不到任何
我也看过 SFVehicle 的例子,但不太了解
任何帮助将不胜感激!!!
【问题讨论】:
【参考方案1】:首先,目前还没有关于 geofire 的完整教程,因此您可以使用的只有 Geofire go for java 和 js 的官方文档。这里有一个小但可能有用的东西—— https://firebase.googleblog.com/2013/09/geofire-location-queries-for-fun-and.html, https://medium.com/google-cloud/firebase-is-cool-geofire-is-just-awesome-b7f2be5e0f0f#.x78gjws28, 我希望这些可以对你有所帮助。
【讨论】:
【参考方案2】:我为 Android 创建了一个库,它提供基于地理位置的 Firestore 数据,以在 KM / MILES 中查找给定半径内的数据列表。
它还可以在单个查询读取中提供更快的响应,并通过实时更新对查询中的 ADDED 和 REMOVED 数据进行分类。
您可以参考Geo-Firestore
它有完善的文档,因此您可以轻松地开发它。
【讨论】:
【参考方案3】:这里还有一些链接 https://firebase.googleblog.com/2014/08/geofire-goes-mobile.html https://firebase.googleblog.com/2014/06/geofire-20.html How to save GeoFire coordinates along with other items in Firebase database?
【讨论】:
【参考方案4】:这是一个获取驱动程序当前位置的示例代码
public class MainActivity extends AppCompatActivity implements
OnMapReadyCallback, PermissionsListener
// Variables needed to initialize a map
private MapboxMap mapboxMap;
private MapView mapView;
// Variables needed to handle location permissions
private PermissionsManager permissionsManager;
// Variables needed to add the location engine
private LocationEngine locationEngine;
private long DEFAULT_INTERVAL_IN_MILLISECONDS = 1000L;
private long DEFAULT_MAX_WAIT_TIME = DEFAULT_INTERVAL_IN_MILLISECONDS *1;
// Variables needed to listen to location updates
private MainActivityLocationCallback callback = new MainActivityLocationCallback(this);
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
// Mapbox access token is configured here. This needs to be called either in your application
// object or in the same activity which contains the mapview.
Mapbox.getInstance(this, "");
// This contains the MapView in XML and needs to be called after the access token is configured.
setContentView(R.layout.activity_main);
mapView = findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);
mapView.getMapAsync(this);
@Override
public void onMapReady(@NonNull final MapboxMap mapboxMap)
this.mapboxMap = mapboxMap;
mapboxMap.setStyle(Style.TRAFFIC_NIGHT,
new Style.OnStyleLoaded()
@Override
public void onStyleLoaded(@NonNull Style style)
enableLocationComponent(style);
);
/**
* Initialize the Maps SDK's LocationComponent
*/
@SuppressWarnings( "MissingPermission")
private void enableLocationComponent(@NonNull Style loadedMapStyle)
// Check if permissions are enabled and if not request
if (PermissionsManager.areLocationPermissionsGranted(this))
// Get an instance of the component
LocationComponent locationComponent = mapboxMap.getLocationComponent();
// Set the LocationComponent activation options
LocationComponentActivationOptions locationComponentActivationOptions =
LocationComponentActivationOptions.builder(this, loadedMapStyle)
.useDefaultLocationEngine(false)
.build();
// Activate with the LocationComponentActivationOptions object
locationComponent.activateLocationComponent(locationComponentActivationOptions);
// Enable to make component visible
locationComponent.setLocationComponentEnabled(true);
// Set the component's camera mode
locationComponent.setCameraMode(CameraMode.TRACKING);
// Set the component's render mode
locationComponent.setRenderMode(RenderMode.COMPASS);
initLocationEngine();
else
permissionsManager = new PermissionsManager(this);
permissionsManager.requestLocationPermissions(this);
/**
* Set up the LocationEngine and the parameters for querying the device's location
*/
@SuppressLint("MissingPermission")
private void initLocationEngine()
locationEngine = LocationEngineProvider.getBestLocationEngine(this);
LocationEngineRequest request = new LocationEngineRequest.Builder(DEFAULT_INTERVAL_IN_MILLISECONDS)
.setPriority(LocationEngineRequest.PRIORITY_HIGH_ACCURACY)
.setMaxWaitTime(DEFAULT_MAX_WAIT_TIME).build();
locationEngine.requestLocationUpdates(request, callback, getMainLooper());
locationEngine.getLastLocation(callback);
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
permissionsManager.onRequestPermissionsResult(requestCode, permissions, grantResults);
@Override
public void onExplanationNeeded(List<String> permissionsToExplain)
Toast.makeText(this, "Enable Location", Toast.LENGTH_LONG).show();
@Override
public void onPermissionResult(boolean granted)
if (granted)
if (mapboxMap.getStyle() != null)
enableLocationComponent(mapboxMap.getStyle());
else
Toast.makeText(this, "Permission Not Granted", Toast.LENGTH_LONG).show();
finish();
private static class MainActivityLocationCallback
implements LocationEngineCallback<LocationEngineResult>
private final WeakReference<MainActivity> activityWeakReference;
MainActivityLocationCallback(MainActivity activity)
this.activityWeakReference = new WeakReference<>(activity);
/**
* The LocationEngineCallback interface's method which fires when the device's location has changed.
*
* @param result the LocationEngineResult object which has the last known location within it.
*/
@Override
public void onSuccess(LocationEngineResult result)
MainActivity activity = activityWeakReference.get();
if (activity != null)
Location location = result.getLastLocation();
if (location == null)
return;
FirebaseDatabase database = FirebaseDatabase.getInstance();
String somi_id2 = "emp_samad";
DatabaseReference myRef3 = database.getReference("current");
GeoFire geoFire = new GeoFire(myRef3);
geoFire.setLocation(somi_id2,new GeoLocation(location.getLatitude(),location.getLongitude()));
Toast.makeText(activity,String.valueOf(location.getLatitude()+"\n"+String.valueOf(location.getLongitude())),Toast.LENGTH_SHORT).show();
// Pass the new location to the Maps SDK's LocationComponent
if (activity.mapboxMap != null && result.getLastLocation() != null)
activity.mapboxMap.getLocationComponent().forceLocationUpdate(result.getLastLocation());
/**
* The LocationEngineCallback interface's method which fires when the device's location can not be captured
*
* @param exception the exception message
*/
@Override
public void onFailure(@NonNull Exception exception)
Log.d("LocationChangeActivity", exception.getLocalizedMessage());
MainActivity activity = activityWeakReference.get();
if (activity != null)
Toast.makeText(activity, exception.getLocalizedMessage(),
Toast.LENGTH_SHORT).show();
@Override
protected void onStart()
super.onStart();
mapView.onStart();
@Override
protected void onResume()
super.onResume();
mapView.onResume();
@Override
protected void onPause()
super.onPause();
mapView.onPause();
@Override
protected void onStop()
super.onStop();
mapView.onStop();
@Override
protected void onSaveInstanceState(Bundle outState)
super.onSaveInstanceState(outState);
mapView.onSaveInstanceState(outState);
@Override
protected void onDestroy()
super.onDestroy();
// Prevent leaks
if (locationEngine != null)
locationEngine.removeLocationUpdates(callback);
mapView.onDestroy();
@Override
public void onLowMemory()
super.onLowMemory();
mapView.onLowMemory();
现在是在地图上实时显示他的代码
public class MainActivity extends AppCompatActivity
implements
OnMapReadyCallback, PermissionsListener
private MapView mapView;
private PermissionsManager permissionsManager;
private MapboxMap mapboxMap;
private GeoJsonSource geoJsonSource;
private ValueAnimator animator;
public static double pre_lat,pre_long;
public static Marker marker;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
Mapbox.getInstance(this, "*YOUR_KEY*");
setContentView(R.layout.activity_main);
Mapbox.getInstance(this, "");
mapView = findViewById(R.id.mapView);
//fetchData process = new fetchData();
// process.execute();
mapView.onCreate(savedInstanceState);
mapView.getMapAsync(new OnMapReadyCallback()
@Override
public void onMapReady(@NonNull final MapboxMap mapboxMap)
MainActivity.this.mapboxMap = mapboxMap;
mapboxMap.setCameraPosition(new CameraPosition.Builder()
.zoom(19)
.target(new
LatLng(24.987029999999997,67.056585))
.build());
mapboxMap.setStyle(Style.DARK,
new Style.OnStyleLoaded()
@Override
public void onStyleLoaded(@NonNull Style style)
// enableLocationComponent(style);
// Create an Icon object for the marker to use
FirebaseDatabase database = FirebaseDatabase.getInstance();
String somi_id2 = "emp_samad";
DatabaseReference myRef3 = database.getReference("current");
GeoFire geoFire = new GeoFire(myRef3);
GeoQuery geoQuery = geoFire.queryAtLocation(new GeoLocation(24.987043333333336, 67.05663333333334), 10);
geoFire.getLocation("emp_samad", new LocationCallback()
@Override
public void onLocationResult(String key, GeoLocation location)
if (location != null)
pre_lat = location.latitude;
pre_long = location.longitude;
// Location prevLoc = new Location(location.latitude,location.longitude);
// Location newLoc = ;
// float bearing = prevLoc.bearingTo(newLoc) ;
marker = mapboxMap.addMarker(new MarkerOptions()
.position(new LatLng(pre_lat,pre_long))
.icon(IconFactory.getInstance(MainActivity.this).fromResource(R.drawable.marker)));
System.out.println(String.format("The location for key %s is [%f,%f]", key, location.latitude, location.longitude));
else
System.out.println(String.format("There is no location for key %s in GeoFire", key));
@Override
public void onCancelled(DatabaseError databaseError)
);
geoQuery.addGeoQueryDataEventListener(new GeoQueryDataEventListener()
@Override
public void onDataEntered(DataSnapshot dataSnapshot, GeoLocation location)
System.out.println(String.format("The location is [%f,%f]", location.latitude, location.longitude));
@Override
public void onDataExited(DataSnapshot dataSnapshot)
@Override
public void onDataMoved(DataSnapshot dataSnapshot, GeoLocation location)
@Override
public void onDataChanged(DataSnapshot dataSnapshot, GeoLocation location)
double lat = pre_lat;
double lon = pre_long;
LatLng pre_latlng = new LatLng(lat,lon);
LatLng washington = new LatLng(location.latitude,location.longitude);
ValueAnimator markerAnimator = ValueAnimator.ofObject(new TypeEvaluator<LatLng>()
@Override
public LatLng evaluate(float fraction, LatLng startValue, LatLng endValue)
return new LatLng(startValue.getLatitude() + (endValue.getLatitude() - startValue.getLatitude()) * fraction, startValue.getLongitude() + (endValue.getLongitude() - startValue.getLongitude()) * fraction);
, new LatLng[]pre_latlng, washington);
markerAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()
@Override
public void onAnimationUpdate(ValueAnimator animation)
if (marker != null)
marker.setPosition((LatLng) animation.getAnimatedValue());
);
markerAnimator.setDuration(7500);
//markerAnimator.setRepeatCount(ValueAnimator.INFINITE);
//markerAnimator.setRepeatMode(ValueAnimator.REVERSE);
markerAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
markerAnimator.start();
/* if(marker!=null)
//marker.remove();
//marker.setPosition(new LatLng(location.latitude,location.longitude));
System.out.println(String.format("The location is [%f,%f]", location.latitude, location.longitude));
*/
@Override
public void onGeoQueryReady()
@Override
public void onGeoQueryError(DatabaseError error)
);
);
);
@SuppressWarnings( "MissingPermission")
private void enableLocationComponent(@NonNull Style loadedMapStyle)
// Check if permissions are enabled and if not request
if (PermissionsManager.areLocationPermissionsGranted(this))
// Get an instance of the component
LocationComponent locationComponent = mapboxMap.getLocationComponent();
// Activate with options
locationComponent.activateLocationComponent(
LocationComponentActivationOptions.builder(this, loadedMapStyle).build());
// Enable to make component visible
locationComponent.setLocationComponentEnabled(true);
// Set the component's camera mode
locationComponent.setCameraMode(CameraMode.TRACKING);
// Set the component's render mode
locationComponent.setRenderMode(RenderMode.COMPASS);
else
permissionsManager = new PermissionsManager(this);
permissionsManager.requestLocationPermissions(this);
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
permissionsManager.onRequestPermissionsResult(requestCode, permissions, grantResults);
@Override
public void onExplanationNeeded(List<String> permissionsToExplain)
Toast.makeText(this, "Enable Location", Toast.LENGTH_LONG).show();
@Override
public void onPermissionResult(boolean granted)
if (granted)
mapboxMap.getStyle(new Style.OnStyleLoaded()
@Override
public void onStyleLoaded(@NonNull Style style)
// enableLocationComponent(style);
);
else
Toast.makeText(this, "Permission Not Granted", Toast.LENGTH_LONG).show();
// finish();
@Override
@SuppressWarnings( "MissingPermission")
public void onStart()
super.onStart();
mapView.onStart();
@Override
public void onResume()
super.onResume();
mapView.onResume();
@Override
public void onPause()
super.onPause();
mapView.onPause();
@Override
public void onStop()
super.onStop();
mapView.onStop();
@Override
public void onLowMemory()
super.onLowMemory();
mapView.onLowMemory();
@Override
public void onDestroy()
super.onDestroy();
mapView.onDestroy();
@Override
public void onMapReady(@NonNull MapboxMap mapboxMap)
你必须使用的是实现一个 geofire 库 地火实施
implementation 'com.firebase:geofire-android:3.0.0'
希望对你有帮助
【讨论】:
以上是关于geofire android 存储和检索位置并将其显示在地图上的主要内容,如果未能解决你的问题,请参考以下文章
如何从 GeoFire 中检索持续更新的位置数据并将其放在 Google 地图上?