2017-06-17 9 views
0

私のアンドロイドアプリケーションでGoogleマップにロケーションフォームのfirebaseデータベースを更新しようとしています。私はfirebaseのonDataChangeメソッドを使用しています。私の問題は、高度と経度の場所がfirebaseデータベースで変更されても、私はまだGoogleマップ上の場所を更新できないということです。以下は私のMapsActivity.javaクラスのコードです。firebaseを使用してGoogleマップの場所を更新できません

import android.support.v4.app.FragmentActivity; 
import android.os.Bundle; 
import android.util.Log; 

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.LatLng; 
import com.google.android.gms.maps.model.MarkerOptions; 
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; 

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback { 

    private GoogleMap mMap; 
    String value; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_maps); 
     // Obtain the SupportMapFragment and get notified when the map is ready to be used. 
     SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager() 
       .findFragmentById(R.id.map); 
     mapFragment.getMapAsync(this); 

     FirebaseDatabase database = FirebaseDatabase.getInstance(); 
     DatabaseReference myRef = database.getReference("Location"); 

     // myRef.setValue("Hello, World!"); 

     myRef.addValueEventListener(new ValueEventListener() { 
      @Override 
      public void onDataChange(DataSnapshot dataSnapshot) { 
       value = dataSnapshot.getValue(String.class); 
       String [] separated = value.split(","); 
       String latiPos= separated[0].trim(); 
       String longiPos =separated[1].trim(); 
       String TAG ="VAL"; 
       double dLat = Double.parseDouble(latiPos); 
       double dLong = Double.parseDouble(longiPos); 
       // Add a marker in Sydney and move the camera 
       LatLng sydney = new LatLng(dLat, dLong); 
       mMap.addMarker(new MarkerOptions().position(sydney).title(latiPos+" "+longiPos)); 


      } 

      @Override 
      public void onCancelled(DatabaseError databaseError) { 

      } 
     }); 
    } 


    /** 
    * Manipulates the map once available. 
    * This callback is triggered when the map is ready to be used. 
    * This is where we can add markers or lines, add listeners or move the camera. In this case, 
    * we just add a marker near Sydney, Australia. 
    * If Google Play services is not installed on the device, the user will be prompted to install 
    * it inside the SupportMapFragment. This method will only be triggered once the user has 
    * installed Google Play services and returned to the app. 
    */ 
    @Override 
    public void onMapReady(GoogleMap googleMap) { 
     mMap = googleMap; 

     // Add a marker in Sydney and move the camera 
    // LatLng sydney = new LatLng(-34, 151); 
     // mMap.addMarker(new MarkerOptions().position(sydney).title(value)); 
     //mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney)); 
    } 
} 
+0

を削除してくださいあなたは 'onDataChange'が呼び出されていることを確認して、正しく緯度/経度の値を解析するということがありますか?おそらくあなたの問題には関係しませんが、 'dataSnapshot.getValue()'をJavaクラスのlat/long値と一緒に使うことをお勧めします... 'gson'を使ってjson文字列から逆直列化します。 db内でのデータ構造の説明)。 –

+0

はい、ログに値を出力して値を確認しました。 –

+0

もう1つの可能性のある問題は、 'mMap'が利用可能なタイミングの周りにある可能性があります(つまり、' onDataChange'コールバックの後で 'onMapReady'が起きます)...もし起こった場合はNPEを取得するべきです...いずれにしても、 'mMap'が設定されるまでfirebaseクエリを実行します。 –

答えて

1

私はあなたの問題を解決することをお勧めしたい二つのものがあります。

  1. は、簡単にデータを格納および取得するためのJavaオブジェクトにFirebaseDatabaseに保存されたデータを包みます。今すぐ あなたはデータベースに保存しているデータを処理するために多くの作業をしています。したがって、 は、Javaオブジェクトとして格納するデータを表すクラスを定義します。その後、データベースへの読み取り/書き込み ははるかに簡単になります。ここでは、上のコードで見たマップマーカ を表すために使用できるクラスの例を示します。

    public class LocationMarker { 
    
        double latitude; 
        double longitude; 
    
    
        /** 
        * Required Empty Constructor used by Firebase 
        */ 
        public LocationMarker() { 
        } 
    
        public LocationMarker(double latitude, double longitude) { 
         this.latitude = latitude; 
         this.longitude = longitude; 
    
        } 
    
        public double getLatitude() { 
         return latitude; 
        } 
    
        public void setLatitude(double latitude) { 
         this.latitude = latitude; 
        } 
    
        public double getLongitude() { 
         return longitude; 
        } 
    
        public void setLongitude(double longitude) { 
         this.longitude = longitude; 
        } 
    
    
        /** 
        * These getters will be ignored when the object is serialized into a JSON object. 
        * Since they will be ignored this means that they don't need a corresponding property (field) 
        * in the Database. This is how we can return a value without having them declared as an instance variable. 
        */ 
    
        @Exclude 
        public LatLng getPosition(){ 
         return new LatLng(latitude, longitude); 
        } 
    
        @Exclude 
        public String getTitle(){ 
         return Double.toString(latitude) + " " + Double.toString(longitude); 
        } 
    } 
    

    これで、データベースに場所を書き込むのがはるかに簡単になりました。

    DatabaseReference myRef = FirebaseDatabase.getInstance().getReference(); 
    double latitude = -34; 
    double longitude = 151; 
    LocationMarker locationMarker = new LocationMarker(latitude,longitude); 
    myRef.child("Location").setValue(locationMarker); 
    

    と読む:

    myRef.addValueEventListener(new ValueEventListener() { 
        @Override 
        public void onDataChange(DataSnapshot dataSnapshot) { 
    
         LocationMarker locationMarker = dataSnapshot.getValue(LocationMarker.class); 
    
         if(locationMarker != null){ 
          LatLng sydney = locationMarker.getPosition(); 
          mMap.addMarker(new MarkerOptions() 
                .position(sydney) 
                .title(locationMarker.getTitle)); 
         } 
        } 
    
        @Override 
        public void onCancelled(DatabaseError databaseError) { 
    
        } 
    }); 
    
  2. onMapReady()onDataChange()非同期的に起こるの呼び出し。 これは、onMapReady()が呼び出されたときを制御できないということです。 また、によってonDataChange()が呼び出されたときに、あなたはコントロールできません。 有効なGoogleMapオブジェクトを取得する前に、FirebaseDatabaseの呼び出しが返されることがあります。

    @Override 
    public void onMapReady(GoogleMap googleMap) { 
        mMap = googleMap; 
        addValueEventListener(); 
    } 
    
    //.... 
    
    private void addValueEventListener(){ 
    
        if(mMap == null) return; 
    
        myRef.addValueEventListener(new ValueEventListener() { 
          @Override 
          public void onDataChange(DataSnapshot dataSnapshot) { 
    
           LocationMarker locationMarker = dataSnapshot.getValue(LocationMarker.class); 
    
           if(locationMarker != null){ 
           LatLng sydney = locationMarker.getPosition(); 
           mMap.addMarker(new MarkerOptions() 
                .position(sydney) 
                .title(locationMarker.getTitle)); 
           } 
          } 
    
          @Override 
          public void onCancelled(DatabaseError databaseError) { 
    
          } 
        }); 
    } 
    

希望、これは保存し、データベースにマップマーカーを取り出す示すのに役立ちます:だからあなたのValueEventListeneronMapReady()への呼び出しに追加します。これは、 "場所"の下に単一のマーカーを格納する必要があります。複数のマーカーのデータベース構造を調整する必要があります。また、任意の追加のリスナー:)

関連する問題