2017-06-06 208 views
0

Android的實時位置,比方說,我有一些數據如下:Geofire和Mapbox與火力地堡

{ 
    "rallye" : { 
    "positions" : { 
     "ATYFOP8lNRThzrEC83" : { 
     ".priority" : "u1q04dmvuq", 
     "g" : "u1q04dmvuq", 
     "l" : [ -116.04463242, 19.55545101 ] 
     }, 
     "AZYF2P8lNSThzrEC63" : { 
     ".priority" : "u1q04dtcbk", 
     "g" : "u1q04dtcbk", 
     "l" : [ 116.045306, 17.555276 ] 
     } 
在我火力實時數據庫

與該Android類別:

package com.sherdle.universal.rallye; 

import android.support.v4.app.FragmentActivity; 
import android.support.v7.app.AlertDialog; 
import android.os.*; 

import android.view.animation.AccelerateDecelerateInterpolator; 
import android.view.animation.Interpolator; 

import com.firebase.geofire.GeoFire; 
import com.firebase.geofire.GeoLocation; 
import com.firebase.geofire.GeoQuery; 
import com.firebase.geofire.GeoQueryEventListener; 

import com.google.firebase.database.DatabaseError; 
import com.google.firebase.database.DatabaseReference; 
import com.google.firebase.database.FirebaseDatabase; 


import com.mapbox.mapboxsdk.Mapbox; 
import com.mapbox.mapboxsdk.annotations.Marker; 
import com.mapbox.mapboxsdk.annotations.MarkerOptions; 
import com.mapbox.mapboxsdk.camera.CameraPosition; 
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory; 
import com.mapbox.mapboxsdk.geometry.LatLng; 

import com.mapbox.mapboxsdk.maps.MapboxMap; 
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; 
import com.mapbox.mapboxsdk.maps.SupportMapFragment; 

import com.sherdle.universal.R; 

import java.util.HashMap; 
import java.util.Map; 

public class rallye_activity extends FragmentActivity implements GeoQueryEventListener, MapboxMap.OnCameraChangeListener { 

    // in welchem Suchradius sollen andere Teams auf der Karte angezeigt werden? 
    private static final int TEAMSIMRADIUS = 100; 
    private static final GeoLocation INITIAL_CENTER = new GeoLocation(52.543535, 8.55123); 
    private static final int INITIAL_ZOOM_LEVEL = 14; 
    private static final String GEO_FIRE_REF = "/rallye/positions"; 

    private MapboxMap map; 
    private GeoFire geoFire; 
    private GeoQuery geoQuery; 

    private Map<String,Marker> markers; 


    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.content_rallye_activity); 

     Mapbox.getInstance(this, getString(R.string.mapbox_access_token)); 

     SupportMapFragment mapFragment = (SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.container); 
     this.map = mapFragment.getMap(); 

     LatLng latLngCenter = new LatLng(INITIAL_CENTER.latitude, INITIAL_CENTER.longitude); 
     this.map.moveCamera(CameraUpdateFactory.newLatLngZoom(latLngCenter, INITIAL_ZOOM_LEVEL)); 
     this.map.setOnCameraChangeListener(this); 

     DatabaseReference ref = FirebaseDatabase.getInstance().getReference("/rallye/positions"); 
     final GeoFire geoFire = new GeoFire(ref); 

     // radius in km 
     this.geoQuery = this.geoFire.queryAtLocation(INITIAL_CENTER, 1); 

     // setup markers 
     this.markers = new HashMap<String, Marker>(); 

    } 

    @Override 
    protected void onStart() { 
     super.onStart(); 
     // add an event listener to start updating locations again 
     this.geoQuery.addGeoQueryEventListener(this); 
    } 

    @Override 
    protected void onStop() { 
     super.onStop(); 
     // remove all event listeners to stop updating in the background 
     this.geoQuery.removeAllListeners(); 
     for (Marker marker: this.markers.values()) { 
      marker.remove(); 
     } 
     this.markers.clear(); 
    } 

    @Override 
    public void onKeyEntered(String key, GeoLocation location) { 
     // Add a new marker to the map 
     Marker marker = this.map.addMarker(new MarkerOptions().position(new LatLng(location.latitude, location.longitude))); 
     this.markers.put(key, marker); 
    } 

    @Override 
    public void onKeyExited(String key) { 
     // Remove any old marker 
     Marker marker = this.markers.get(key); 
     if (marker != null) { 
      marker.remove(); 
      this.markers.remove(key); 
     } 
    } 

    @Override 
    public void onKeyMoved(String key, GeoLocation location) { 
     // Move the marker 
     Marker marker = this.markers.get(key); 
     if (marker != null) { 
      this.animateMarkerTo(marker, location.latitude, location.longitude); 
     } 
    } 

    @Override 
    public void onGeoQueryReady() { 
    } 

    @Override 
    public void onGeoQueryError(DatabaseError error) { 
     new AlertDialog.Builder(this) 
       .setTitle("Error") 
       .setMessage("There was an unexpected error querying GeoFire: " + error.getMessage()) 
       .setPositiveButton(android.R.string.ok, null) 
       .setIcon(android.R.drawable.ic_dialog_alert) 
       .show(); 
    } 

    // Animation handler for old APIs without animation support 
    private void animateMarkerTo(final Marker marker, final double lat, final double lng) { 
     final Handler handler = new Handler(); 
     final long start = SystemClock.uptimeMillis(); 
     final long DURATION_MS = 3000; 
     final Interpolator interpolator = new AccelerateDecelerateInterpolator(); 
     final LatLng startPosition = marker.getPosition(); 
     handler.post(new Runnable() { 
      @Override 
      public void run() { 
       float elapsed = SystemClock.uptimeMillis() - start; 
       float t = elapsed/DURATION_MS; 
       float v = interpolator.getInterpolation(t); 

       double currentLat = (lat - startPosition.getLatitude()) * v + startPosition.getLatitude(); 
       double currentLng = (lng - startPosition.getLongitude()) * v + startPosition.getLongitude(); 
       marker.setPosition(new LatLng(currentLat, currentLng)); 

       // if animation is not finished yet, repeat 
       if (t < 1) { 
        handler.postDelayed(this, 16); 
       } 
      } 
     }); 
    } 

    private double zoomLevelToRadius(double zoomLevel) { 
     // Approximation to fit circle into view 
     return 16384000/Math.pow(2, zoomLevel); 
    } 

    @Override 
    public void onCameraChange(CameraPosition cameraPosition) { 
     // Update the search criteria for this geoQuery and the circle on the map 
     LatLng center = cameraPosition.target; 
     double radius = zoomLevelToRadius(cameraPosition.zoom); 
     this.geoQuery.setCenter(new GeoLocation(center.getLatitude(), center.getLongitude())); 
     // radius in km 
     this.geoQuery.setRadius(radius/1000); 
    } 
} 

這是我的佈局XML

<?xml version="1.0" encoding="utf-8"?> 
<fragment xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/map" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:name="com.mapbox.mapboxsdk.maps.SupportMapFragment"/> 

事實上:我想在此Mapbox地圖上顯示帶有多個標記的RealForge中的geofire數據。

但我得到這個錯誤

this.map = mapFragment.getMap(); 

然後我用的是 「新」 的功能:getMapAsync()

this.map = mapFragment.getMapAsync(this); 

沒有這些功能之一,我得到這個錯誤:

FATAL EXCEPTION: main 
Process: com.foo.bar, PID: 12380 
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.foo.bar/com.sherdle.universal.rallye.rallye_activity}: android.view.InflateException: Binary XML file line #2: Error inflating class fragment 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2689) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2754) 
at android.app.ActivityThread.access$900(ActivityThread.java:177) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1448) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:145) 
at android.app.ActivityThread.main(ActivityThread.java:5938) 
at java.lang.reflect.Method.invoke(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:372) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1400) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1195) 
Caused by: android.view.InflateException: Binary XML file line #2: Error inflating class fragment 
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:770) 
at android.view.LayoutInflater.inflate(LayoutInflater.java:483) 
at android.view.LayoutInflater.inflate(LayoutInflater.java:415) 
at android.view.LayoutInflater.inflate(LayoutInflater.java:366) 
at android.transition.Scene.enter(Scene.java:175) 
at com.android.internal.policy.impl.PhoneWindow.transitionTo(PhoneWindow.java:483) 
at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:426) 
at android.app.Activity.setContentView(Activity.java:2267) 
at com.sherdle.universal.rallye.rallye_activity.onCreate(rallye_activity.java:54) 
+0

不應該是'類= 「com.google.android.gms.maps.SupportMapFragment」'而不是你的當前片段的名字嗎? – Yupi

+0

我認爲這隻適用於Google地圖?我使用mapbox,我想我必須使用com.mapbox.mapboxsdk.maps.SupportMapFragment而不是GMS路徑。與GMS路徑我得到相同的錯誤 – georf

+0

'android.view.InflateException:二進制XML文件行#2:錯誤膨脹類片段' - 您的問題肯定是在片段XML。你檢查他們是否提供他們自定義XML顯示地圖? – Yupi

回答

0

您正在使用錯誤的ID來查找片段。在XML中定義的ID是map。您正在尋找container

變化:

SupportMapFragment mapFragment = (SupportMapFragment)getSupportFragmentManager() 
    .findFragmentById(R.id.container); 

到:

SupportMapFragment mapFragment = (SupportMapFragment)getSupportFragmentManager() 
    .findFragmentById(R.id.map); 
+0

哦,我的錯誤,我忘了在我的源代碼中發現這個錯誤後在這裏改變了這個在stackoverflow。我改變它的地圖,但得到相同的錯誤:/ – georf