1
votes

Changer la position du marqueur par lat et lang en temps réel dans la base de données Firebase sans ajouter de nouveau marqueur

Ma base de données Firebase en temps réel

 entrez la description de l'image ici

J'essaye de changer de position pour de nombreuses langues lat à un moment donné, comme les voitures dans uber, mais quand je change lat ou lang ou les deux, cela ne change pas la position du marqueur mais il fait un nouveau marqueur. Je veux que lorsque la lat par exemple est modifiée dans la base de données en temps réel, les marqueurs ont également changé en fonction de la valeur de cette lat

J'essaie de créer une condition

public class Map extends FragmentActivity implements OnMapReadyCallback {
FirebaseDatabase database;
DatabaseReference myRef;
GoogleMap mMap;
MarkerOptions options;
Marker mCurrLocationMarker;
LatLng ll;
model save;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_map);
    // 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);
}

  @Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;

    database = FirebaseDatabase.getInstance();
    myRef = database.getReference("user");

    myRef.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for (DataSnapshot ds : dataSnapshot.getChildren()) {

                Double lang = ds.child("lang").getValue(Double.class);
                Double lat = ds.child("lat").getValue(Double.class);
                save = new model(lat, lang);
                ll = new LatLng(save.getLat(), save.getLang());

                mCurrLocationMarker = mMap.addMarker(options
                        .position(ll));

            }

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
}

mais le le problème est que j'ai> 1 marqueurs pour que cette solution ne m’affiche sur la carte qu’un marqueur car marker! = null

`if (marker != null) 
    setPosition 
 else "marker == null"` 
    add new marker 

Je m'attendais à ce que la position du marqueur soit modifiée lorsque je change lat et lang en temps réel dans Firebase, mais le résultat est créé un autre marqueur.


9 commentaires

Veuillez partager le code complet de ce cours


une seconde je vais le copier


@HemendraGangwar terminé


Vous souhaitez suivre la position actuelle de l'utilisateur à l'aide d'un marqueur?


@Alex Mamo exactement ce que je veux


@mohamedgaber, s'il vous plaît laissez-moi savoir si vous êtes familier avec Kotin, montrez que je peux partager le code de piste complet


@HemendraGangwar oui c'est très gentil de ta part <33


Une réponse expliquant comment activer votre position actuelle à l'aide de ce point bleu vous sera-t-elle utile?


@Alex Mamo je le fais déjà dans mon application <3 et le fais setvalue dans la base de données en temps réel mon problème avec la lecture de cette valeur sans ajouter un nouveau marqueur, changez simplement la position que vous savez


4 Réponses :


0
votes

Essayez ceci.

Et vous devez implémenter OnMapReadyCallback

mMap.clear();

Et mMap rend une variable privée ou publique.

Avant d'appeler la méthode de boucle

Insérer le code de suivi

@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;

}

Vous utilisez la mauvaise méthode pour addValueEventListener.

Vous pouvez soumettre addValueEventlistener dans la méthode onCreate, et vous devez également vérifier la valeur null avant l'appel.

Dans la méthode OnMapReadyCallback, ne liez que la variable mMap.


19 commentaires

je l'essaye maintenant et je te dis la sortie merci mon frère <3


Tentative d'appel de la méthode virtuelle 'void com.google.android.gms.maps.model.Marker.remove ()' sur une référence d'objet nulle


vérifiez d'abord si (mCurrLocationMarker! = null) puis appelez mCurrLocationMarker.clear ()


Vous pouvez appeler avant la boucle for.


@mirzak mCurrLocationMarker.remove? je ne trouve pas mCurrLocationMarker.clear ()


Et aucun moyen de changer de position sans ajouter de marqueur dans Google. Dans votre cas mMap.clear ();


hhhhhh j'utilise mMap.clear avant pour la boucle comme tu le dis et ça marche parfaitement: `` Merci mon ami @Akio Alex


laissez-moi vous demander que c'est une bonne méthode, il est clair que tous les marqueurs sont appelés à chaque fois


ce que vous pensez de son utilisation dans l'application


si j'ai 100 marqueurs et que l'un est en train de changer, les 100 marqueurs sont clairs et rajoutés pour changer la position d'un marqueur seulement


Ma pensée n'est pas un autre moyen de mettre à jour le marqueur de carte google.


@AkioAlex mais pourquoi je ne remarque pas d'effacer un autre marqueur lorsque j'exécute l'application


Je ne remarque pas d'autre marqueur ajouté, c'est bien mais je ne le comprends pas


pouvez-vous expliquer ce qui se passe exactement dans mMap.clear


Dans la méthode claire, supprimez tous les marqueurs sur les marqueurs de carte google. Donc je ne sais pas ce qui se passe dans la méthode. Mais il n'y a pas d'autre moyen de mise à jour dans Google map. Si vous n'aimez pas cela, trouvez une autre bibliothèque.


ok très merci, le code est exécuté et je devrais vous donner accepter la réponse merci <3333


Vous pouvez mettre à jour l'emplacement du marqueur précédent en utilisant mCurrLocationMarker.setPosition (new LatLng (37.7750,122.4183)); plutôt que supprimer le marqueur précédent (assurez-vous de vérifier si mCurrLocationMarker est nul ). (docs)


@sam je vous ai lu un commentaire mais je ne peux pas le comprendre et le transformer en code


J'ai essayé cela mais, le marqueur ne se met pas à jour vers le nouvel emplacement. Veuillez consulter mon code: github.com/muankit/new/blob/master/ TrackActivity.java



0
votes

Veuillez jeter un œil pour un suivi complet du marqueur, animez et déplacez comme uber, avec le code Kotlin ci-dessous:

Ajoutez initialement votre auditeur Firebase

 myRef.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for (DataSnapshot ds : dataSnapshot.getChildren()) {

            Double lang = ds.child("lang").getValue(Double.class);
            Double lat = ds.child("lat").getValue(Double.class);
            save = new model(lat, lang);
            ll = new LatLng(save.getLat(), save.getLang());

            displayLocation(ll) 

       }
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {

    }
});


13 commentaires

merci merci je vais le convertir en code java et l'essayer


@mohamedgaber, Oui s'il vous plaît et faites-moi savoir si vous rencontrez toujours un problème.


mon ami, j'essaie l'autre réponse dans cet article, c'est dire mMap.clear avant pour (DataSnapshot ds: dataSnapshot.getChildren ()) cela fonctionne mais c'est la bonne méthode ou non ce que vous en pensez


@mohamedgaber J'éviterais d'utiliser mMap.clear () car cela supprimera chaque marqueur de la carte lorsque plusieurs sont présents. Il n'est pas clair si vous avez plusieurs marqueurs sur la carte à la fois pour différents utilisateurs ou pour le même utilisateur. Le code fourni ici par Hemendra mettra à jour l'emplacement d'un marqueur unique avec les valeurs lat / lng les plus récentes tout en utilisant également le plus efficace child_ * écouteurs d'événements pour écouter les mises à jour au lieu d'écouter l'ensemble de l'utilisateur Les données.


je sais mais problème je suis très pauvre dans kotlin j'essaie d'exécuter du code mais c'est très difficile pour moi


val latLatLng = dataSnapshot.value as ArrayList ? if (latLatLng !!. size == 2) {displayLocation (latLatLng)} ne le comprend pas


J'essaye toujours mais sans aucun résultat je suis pauvre à kotlin


@mohamedgaber vient de mettre à jour ma réponse en bas, vérifiez-la une fois.


displayLocation a de nombreuses erreurs, je ne peux pas le comprendre et le résoudre


Je remarque GPS_PROVIDER mais je n'en ai pas besoin


je cherche uniquement à mettre à jour la lat et la lang en lisant lat et lang de firebase


s'il vous plaît si vous avez résolu mon problème, aidez-moi avec cela


C'est mon exigence, si vous n'en avez pas besoin, vous pouvez supprimer la condition



1
votes

Suite à mes commentaires sur d'autres réponses, voici ce que j'ai trouvé en fonction de votre question.

Ce code affichera plusieurs marqueurs sur la carte, mais un seul marqueur pour chaque identifiant sous / utilisateurs dans la base de données. Si l'emplacement d'un identifiant particulier change, son marqueur associé sera déplacé sans affecter les autres marqueurs sur la carte.

Attention: Le code ci-dessous mettra à jour votre carte en réel- temps. Vous pouvez mettre en cache les nouveaux emplacements de marqueurs et ne les mettre à jour qu'une fois toutes les 2 à 5 secondes environ, en fonction de la fréquence à laquelle vos données changent.

Quelques notes rapides avant de plonger dans le code:

  • Chaque marqueur est lié à son ID de chaîne dans la base de données sous une carte appelée mNamedMarkers .
  • Le model n'étant pas fourni et ne semble pas pertinent, je l'ai omis du code ci-dessous.
  • Je ne sais pas si vous venez d'un milieu germanique, mais lng est l'abréviation de Longitude, et non de "lang" dans ce contexte. Je changerais également les entrées de votre base de données pour utiliser lng plutôt que lang / long / longitude / etc (cela économise de l'espace et élimine la confusion).
  • Dans le code ci-dessous, j'ai ajouté getMarkerOptions (key) , afin que vous puissiez ajouter du code pour obtenir des images, des titres et du texte différents pour chaque marqueur en fonction de son ID. Actuellement, il produira les mêmes données pour chaque marqueur.
  • J'ai ajouté un balisage Javadoc pour chaque fonction afin de résumer ce que chacune fait.
  • Il existe quelques TODO à développer.

Voici le code:

public class Map extends FragmentActivity implements OnMapReadyCallback {
    FirebaseDatabase database;
    DatabaseReference userLocationsRef;
    GoogleMap mMap;

    Map<String, Marker> mNamedMarkers = new HashMap<String,Marker>();

    ChildEventListener markerUpdateListener = new ChildEventListener() {

            /**
             * Adds each existing/new location of a marker.
             *
             * Will silently update any existing markers as needed.
             * @param dataSnapshot  The new location data
             * @param previousChildName  The key of the previous child event
             */
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
                    String key = dataSnapshot.getKey();
                    Log.d(TAG, "Adding location for '" + key + "'");

                    Double lng = ds.child("lang").getValue(Double.class);
                    Double lat = ds.child("lat").getValue(Double.class);
                    LatLng location = new LatLng(lat, lng);

                    Marker marker = mNamedMarkers.get(key);

                    if (marker == null) {
                        MarkerOptions options = getMarkerOptions(key);
                        marker = mMap.addMarker(options.position(location));
                        mNamedMarkers.put(key, marker);
                    } else {
                        // This marker-already-exists section should never be called in this listener's normal use, but is here to handle edge cases quietly.
                        // TODO: Confirm if marker title/snippet needs updating.
                        marker.setPosition(location);
                    }
            }

            /**
             * Updates the location of a previously loaded marker.
             *
             * Will silently create any missing markers as needed.
             * @param dataSnapshot  The new location data
             * @param previousChildName  The key of the previous child event
             */
            @Override
            public void onChildChanged(DataSnapshot dataSnapshot, String previousChildName) {
                    String key = dataSnapshot.getKey();
                    Log.d(TAG, "Location for '" + key + "' was updated.");

                    Double lng = ds.child("lang").getValue(Double.class);
                    Double lat = ds.child("lat").getValue(Double.class);
                    LatLng location = new LatLng(lat, lng);

                    Marker marker = mNamedMarkers.get(key);

                    if (marker == null) {
                        // This null-handling section should never be called in this listener's normal use, but is here to handle edge cases quietly.
                        Log.d(TAG, "Expected existing marker for '" + key + "', but one was not found. Added now.");
                        MarkerOptions options = getMarkerOptions(key); // TODO: Read data from database for this marker (e.g. Name, Driver, Vehicle type)
                        marker = mMap.addMarker(options.position(location));
                        mNamedMarkers.put(key, marker);
                    } else {
                        // TODO: Confirm if marker title/snippet needs updating.
                        marker.setPosition(location);
                    }
            }

            /**
             * Removes the marker from its GoogleMap instance
             * @param dataSnapshot  The removed data
             */
            @Override
            public void onChildRemoved(DataSnapshot dataSnapshot) {
                    String key = dataSnapshot.getKey();
                    Log.d(TAG, "Location for '" + key + "' was removed.");

                    Marker marker = mNamedMarkers.get(key);
                    if (marker != null)
                        marker.remove()
            }

            /**
             * Ignored.
             * @param dataSnapshot  The moved data
             * @param previousChildName  The key of the previous child event
             */
            @Override
            public void onChildMoved(DataSnapshot dataSnapshot, String previousChildName) {
                    // Unused
                    Log.d(TAG, "Priority for '" + dataSnapshot.getKey() "' was changed.");
            }

            /**
             * Error handler when listener is canceled.
             * @param databaseError  The error object
             */
            @Override
            public void onCancelled(DatabaseError databaseError) {
                    Log.w(TAG, "markerUpdateListener:onCancelled", databaseError.toException());
                    Toast.makeText(mContext, "Failed to load location markers.", Toast.LENGTH_SHORT).show();
            }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_map);
            // 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);
    }

    /**
     * Waits for the map to be ready then loads markers from the database.
     * @param googleMap  The GoogleMap instance
     */
    @Override
    public void onMapReady(GoogleMap googleMap) {
            mMap = googleMap;

            database = FirebaseDatabase.getInstance();
            userLocationsRef = database.getReference("user");

            userLocationsRef.addChildEventListener(markerUpdateListener);



            // later when the activity becomes inactive.
            // userLocationsRef.removeEventListener(markerUpdateListener)
    }

    /**
     * Retrieves the marker data for the given key.
     * @param key  The ID of the marker
     * @return A MarkerOptions instance containing this marker's infoormation
     */
    private MarkerOptions getMarkerOptions(String key) {
        // TODO: Read data from database for the given marker (e.g. Name, Driver, Vehicle type)
        return new MarkerOptions().title('Location placeholder').snippet('Update this with marker information');
    } 
}


8 commentaires

ce problème me fatigue j'espère que votre code fonctionne grâce à vos efforts <33


sam Map mNamedMarkers = new HashMap ();


J'ai corrigé la carte et la rendre Hashmap à la place


Heureux de l'entendre juger que je n'ai pas touché Java / Android depuis des années.


Dieu vous bénisse merci je suis essayer environ 3 jours sans résultat et vous m'avez sauvé


je ne sais pas ce que je dois te dire mais je t'aime <33


J'ai essayé cela mais, le marqueur ne se met pas à jour vers le nouvel emplacement. Veuillez consulter mon code: github.com/muankit/new/blob/master/ TrackActivity.java


Après avoir parcouru le code lié, le seul problème immédiat que je vois est l'utilisation de "lng" sur Ligne 40 et "lang" sur Ligne 75



0
votes
    mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
        @Override
        public boolean onMarkerClick(final Marker marker) {
            dbref.addSnapshotListener(Mapsimport1.this, new EventListener<DocumentSnapshot>() {
                @Override
                public void onEvent(DocumentSnapshot documentSnapshot, FirebaseFirestoreException e) {
                    if (e != null) {
                        Toast.makeText(Mapsimport1.this, "Error while loading!", Toast.LENGTH_SHORT).show();
                        Log.d(TAG, e.toString());
                        return;
                    }

                    if (documentSnapshot.exists()) {
                        String acmilan = documentSnapshot.getString(marker.getTitle());
                                Log.d("acmilan**",acmilan);
                        marker.setSnippet(acmilan);                        }
                }
            });
            return false;
        }
    });

0 commentaires