Android marker drag problem

0

Czesc,
ostatnio robilem mala zmiane w aplikacji i to mi wylozylo wazna funkcjonalnosc. Dotychczas po zalogowaniu sie na glownym ekranie widzielismy mapke google + edittexty do wypelnienia i przycisk dodaj. Po wypelnieniu i kliknieciu przycisku dodawalo nam marker. po kliknieciu na marker pokazywaly sie szczegoly, a jesli przytrzymalismy marker to moglismy go przeniesc.

Zmiana ktora zrobilem polega na tym ze usunelem wszystkie edittexty z glownego ekranu i zostawilem jeden button. Po kliknieciu buttona odpala nam sie dialogfragment z edittextami i opcja dodaj. Po kliknieciu opcji dodaj odpala nam na nowo aktywnosc z mapa, przesyla intentem dane i w onMapReady daje funkcje ktora nanosi nam marker. Po kliknieciu na marker pokazuja sie dane jak poprzednio i UWAGA!

Tu sie wszystko psuje. Po przytrzymaniu markera i przeniesieniu go powstaja 2 markery jeden w miejscu do ktorego go przenieslismy i drugi w miejscu z ktorego zaczelismy przenosic marker. Po kliknieciu w marker przeniesiony wszystko dziala jak nalezy lecz po kliknieciu w drugi wywala apke (juz nie mowiac o tym ze chcialbym uniknac replikacji markerow).

Co ciekawe prawidlowosc powyzsza czasem sie pojawia, a czasami dziala tak jak nalezy czyli nie replikuje nam markera i pozostaje jeden przeniesiony.
Moj wniosek jest taki, ze w pierwszej wersji po zaladowaniu sie mapy dajac dodaj aktywnosc w momencie klikniecia wszystkie elementy/mechanizmy mapy byly zaladowane, a teraz cos sie nie zdarza zaladowac. Ujalem zapytania do bazy w watki i dalem, aby czekalo az sie wykonaja, ale to nic nie daje. Wkleje kod moze ktos na cos wpadnie.

Aha i jezeli ktos ma pomysl czy po kliknieciu w dialogfragmentcie przycisku dodaj da sie dialofFragment zdissmisowac i aby nastepnie wykonala sie funkcja dodawania markeru z poprzedniej aktywnosci(ta za mapa) Wowczas nie trzeba by bylo tworzyc calej aktywnosci od nowa i ten problem mozna by w taki sposob rozwiazac, ale nie wiem czy jest to mozliwe.

Ponizsza klasa to ta z mapa. W onMapReady jest Intent i funkcja sendMarkerCall ktora ustawia nam marker na mapie.

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_start);

        locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
        apiServiceStart= ApiUtils.getAPIService();


        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbarid);
        setSupportActionBar(toolbar);


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




    }


public void HereStart (View view){


    FragmentAddActivity addActivity_filtr_dialog = new FragmentAddActivity();
    addActivity_filtr_dialog.show(getSupportFragmentManager(),"FragmentAddActivity");
}



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

        if (ActivityCompat.checkSelfPermission(getApplicationContext(), ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                && ActivityCompat.checkSelfPermission(getApplicationContext(), ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

        } else {
            mMap.setMyLocationEnabled(true);
        }
        try {
            Location locationGPS = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
            //here what you need:
            double latitude = locationGPS.getLatitude();
            double longitude = locationGPS.getLongitude();
            //create marker
            myGPSPosition = new LatLng(latitude, longitude);
            mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(myGPSPosition, 13));

        }catch (NullPointerException | IllegalArgumentException e){
            e.printStackTrace();
            Toast.makeText(this,"Unable to get GPS data",Toast.LENGTH_SHORT).show();
        }


        mClusterManager = new ClusterManager<MyItem>(this, mMap);
        mMap.setOnCameraIdleListener(mClusterManager);
        mMap.setOnMarkerClickListener(mClusterManager);




        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                getAllMarkers(Login.currentUserId, "all");
            }});

        t.start(); // spawn thread

        try {
            t.join();  // wait for thread to finish
        } catch (InterruptedException e) {
            e.printStackTrace();
        }


        Intent intent = getIntent();
        int flag = intent.getIntExtra("flag",0);
        if(flag==1) {
            rodzaj = intent.getExtras().getString("kindOfActivity");
            opis = intent.getExtras().getString("descriptionOfActivity");
            data = intent.getExtras().getString("startDate");
            godzina = intent.getExtras().getString("startHour");
            adres = intent.getExtras().getString("adres");
            lat = intent.getExtras().getDouble("lat", 0);
            lng = intent.getExtras().getDouble("lng", 0);

             t = new Thread(new Runnable() {
                @Override
                public void run() {
                    sendMarkerCall(currentUserId ,lat,lng,rodzaj,opis,"nazwa1", data, godzina, adres);
                }});

            t.start(); // spawn thread

            try {
                t.join();  // wait for thread to finish
            } catch (InterruptedException e) {
                e.printStackTrace();
            }


        }
        flag=0;

        mClusterManager.setOnClusterItemClickListener(
                new ClusterManager.OnClusterItemClickListener<MyItem>() {
                    @Override public boolean onClusterItemClick(MyItem clusterItem) {

                        DialogFragmentJoin dialog = new DialogFragmentJoin();
                        dialog.show(getSupportFragmentManager(),"DialogFragmentJoin");

                        //PACK DATA IN A BUNDLE
                        int i = (int)  clusterItem.getIdOfMarker();
                        Bundle bundle = new Bundle();
                        bundle.putString("Login", clusterItem.getTitle());
                        bundle.putString("Description", clusterItem.getSnippet());
                        bundle.putInt("ActivityId", i);

                        //PASS OVER THE BUNDLE TO OUR FRAGMENT
                        dialog.setArguments(bundle);
                        return true;


                    }
                });

        mMap.setOnMarkerDragListener(new GoogleMap.OnMarkerDragListener() {

            @Override
            public void onMarkerDragStart(Marker marker) {
                Log.i("marker_status", "start moving marker" );
            }

            @Override
            public void onMarkerDragEnd(Marker marker) {
                LatLng position=marker.getPosition();
                double latMarkerDrag = (double)position.latitude;
                double lngMarkerDrag = (double)position.longitude;

                Log.i("marker_status", "marker moved " + latMarkerDrag +" "+ lngMarkerDrag);

                geocoder = new Geocoder(StartActivity.this, Locale.getDefault());

                try {
                    addresses = geocoder.getFromLocation(latMarkerDrag, lngMarkerDrag, 1); // Here 1 represent max location result to returned, by documents it recommended 1 to 5
                    Log.i("as56haj2es4", "" + addresses);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                Log.i("marker_status", "marker moved addresses: "+ addresses  + " lat: " + latMarkerDrag + " lng: " + lngMarkerDrag);

                String address = addresses.get(0).getAddressLine(0); // If any additional address line present than only, check with max available address lines by getMaxAddressLineIndex()
                Log.i("asdg12217kkfes4", "post submitted to API." + address);
              

                updateLocation(activityId, latMarkerDrag, lngMarkerDrag, address);

                Log.i("marker_status", "marker moved" );


            }

            @Override
            public void onMarkerDrag(Marker marker) {
                Log.i("marker_status", "moving marker" );



            }
        });



    }





  public void sendMarkerCall(int user_id, double lat, double lng,  String kind_of_activity, String description_of_activity, String nameOfActivity, String date, String hour,String adress) {
        Call<List<Post>> call = apiServiceStart.markerSendInterface(user_id,lat,lng, kind_of_activity,description_of_activity,nameOfActivity, date, hour, adress);
        call.enqueue(new Callback<List<Post>>() {
            @Override
            public void onResponse(@NonNull Call<List<Post>> call, @NonNull Response<List<Post>> response) {
                if(response.isSuccessful()) {
                    markerList=response.body();

                     activityId =  markerList.get(0).getActivity_id();
                    String login = markerList.get(0).getLogin();
                    String kindOfActivity=markerList.get(0).getKind_of_activity();
                    String descriptionOfActivity=markerList.get(0).getDescription_of_activity();
                    String startDate=markerList.get(0).getStart_date();
                    String startHour=markerList.get(0).getStart_hour();
                    Double lat=markerList.get(0).getLat();
                    Double lng=markerList.get(0).getLng();

                    LatLng latLng = new LatLng(lat,lng);
                    marker = mMap.addMarker(new MarkerOptions().position(latLng).title(login)
                            .snippet("Rodzaj: "+ kindOfActivity
                                    +System.lineSeparator()+"Opis: " +descriptionOfActivity
                                    +System.lineSeparator()+ "Adres Startu: " + adres
                                    +System.lineSeparator()+ "Data Startu: " + startDate
                                    +System.lineSeparator()+ "Godzina Startu: " + startHour));
                    marker.setTag(activityId);
                    marker.setDraggable(true);

                    if(getDrawableId(rodzaj)!=-1)
                        marker.setIcon(BitmapDescriptorFactory.fromResource(getDrawableId(rodzaj)));

                    mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 15));

                    Log.i("start_activity_sent", "post submitted to API." + response.body());

                    mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
                        @Override
                        public boolean onMarkerClick(Marker marker) {
                            DialogFragmentJoin dialog = new DialogFragmentJoin();
                            dialog.show(getSupportFragmentManager(),"DialogFragmentJoin");

                            //PACK DATA IN A BUNDLE
                            int i = (int)  marker.getTag();
                            Bundle bundle = new Bundle();
                            bundle.putString("Login", marker.getTitle());
                            bundle.putString("Description", marker.getSnippet());
                            bundle.putInt("ActivityId", i);

                            //PASS OVER THE BUNDLE TO OUR FRAGMENT
                            dialog.setArguments(bundle);
                            return true;
                        }
                    });

                } else {
                    System.out.println(response.errorBody().toString());
                    try {
                        JSONObject jObj = new JSONObject(response.errorBody().string());
                        String error = jObj.getString("code");
                        String errorText ="Ogólny błąd";
                        if(error.equals("badformat")){
                            errorText = "Zły format";
                        }  else if(error.equals("serverdown")){
                            errorText = "serwer chwilowo nie odpowiada";
                        } else if(error.equals("badreq")) {
                            errorText = "uzupelnij wszystkie pola";
                        }

                        Toast.makeText(getBaseContext(), errorText, Toast.LENGTH_LONG).show();
                    } catch (JSONException e) {
                        Toast.makeText(getBaseContext(), "Fatal server error. Not a JSON on a server.", Toast.LENGTH_LONG).show();
                    } catch (IOException e) {
                        Toast.makeText(getBaseContext(), "Error parsing JSON", Toast.LENGTH_LONG).show();

                    }
                }
                Toast.makeText(getBaseContext(), "Przytrzymaj marker, aby go przeniesc", Toast.LENGTH_LONG).show();

            }

            @Override
            public void onFailure(@NonNull Call<List<Post>> call, @NonNull Throwable t) {

                Log.e("start_activity_failed", "getting data failed." + t);

            }
        });
    }


Ponizej mamy nasz kod dialogFragmentu. Co ciekawe przesylajac same dane do aktywnosci za pomoca intentu w aktywnosci z mapa w onCreat'cie jest polecenie aby dodalo znacznik co okazuje sie porazka przy przesuwaniu markera. Ale gdy przesle dane intentem i wywale funkcje z onCreate'a tworzaca znacznik, a funkcje ta przypisze do buttona, aby skorzystalo z przeslanych danych i odpalilo wstawianie markeru calosc dziala. Ale ja oczywiscie sobie wymyslilem, ze musi byc inaczej i juz 2 dni sie z tym bawie...

public class FragmentAddActivity extends DialogFragment {
    private static final String TAG = "FragmentAddActivity";

    private EditText opisEt, dateEt, hourEt;
    private  String rodzaj, adres, godzina, opis, data;
    private AutoCompleteTextView rodzajAc;
    private static LatLng latLngUserActivity=null;
    private LatLng cordinates;
    private double lat, lng;
    private Button add;

    @SuppressLint("CutPasteId")
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_fragment_add, container, false);

        ArrayAdapter<String> adapter = new ArrayAdapter<String>(getContext(),
                android.R.layout.simple_dropdown_item_1line, ListOfActivities.activityList);
        rodzajAc = (AutoCompleteTextView) view.findViewById(R.id.rodzajEtId);
        rodzajAc.setAdapter(adapter);


        opisEt = (EditText) view.findViewById(R.id.opisEtId);
        dateEt = (EditText) view.findViewById(R.id.DateEtId);
        hourEt = (EditText) view.findViewById(R.id.HourEtId);
        add=(Button) view.findViewById(R.id.AddActivityFragmentId);


        PlaceAutocompleteFragment placeAutocompleteFragment = (PlaceAutocompleteFragment)getActivity().
                getFragmentManager().findFragmentById(R.id.place_autocomplete_fragment);
        placeAutocompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {


            @Override
            public void onPlaceSelected(Place place) {
                latLngUserActivity = place.getLatLng();
                adres=place.getAddress().toString();
            }

            @Override
            public void onError(Status status) {
                Toast.makeText(getContext(),"blad"+status.toString(),Toast.LENGTH_LONG).show();

            }
        });


        add.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                cordinates= FragmentAddActivity.latLngUserActivity;
                rodzaj = rodzajAc.getText().toString().trim();
                opis=opisEt.getText().toString().trim();
                data=dateEt.getText().toString().trim();
                godzina=hourEt.getText().toString().trim();



                if(   (rodzaj!=null && !rodzaj.equals(""))
                        && (data!=null && !data.equals(""))
                        && (godzina!=null && !godzina.equals(""))
                        && (cordinates!=null && !cordinates.equals(""))
                        ) {

                    lat = (double)cordinates.latitude;
                    lng = (double)cordinates.longitude;


                    Intent intent = new Intent(getContext(), StartActivity.class);
                    intent.putExtra("kindOfActivity", rodzaj);
                    intent.putExtra("descriptionOfActivity", opis);
                    intent.putExtra("startDate", data);
                    intent.putExtra("startHour", godzina);
                    intent.putExtra("adres", adres);
                    intent.putExtra("lat", lat);
                    intent.putExtra("lng", lng);
                    intent.putExtra("flag", 1);
                    startActivity(intent);

                }
                else{
                    Toast.makeText(getContext(),"Wypełnij adres, rodzaj, godzina oraz date",Toast.LENGTH_LONG).show();
                }
            }
        });


        return view;
    }

}

Edit:
Blad ktory wyskakuje po kliknieciu zreplikowanego markera:

06-26 18:55:27.527 7357-7357/com.example.ad.retrofittest E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.ad.retrofittest, PID: 7357
    java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.Integer.intValue()' on a null object reference
        at com.example.ad.retrofittest.Maps.StartActivity$6$1.onMarkerClick(StartActivity.java:364)
        at com.google.android.gms.maps.zzb.zza(Unknown Source)
        at com.google.android.gms.maps.internal.zzas.onTransact(Unknown Source)
        at android.os.Binder.transact(Binder.java:387)

Edit2: usunalem troche kodu

0

Radziłbym wywalić niepotrzebny kod, skrócić i streścić.
Nikt tego nie będzie czytać.

Poza tym:

    java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.Integer.intValue()' on a null object reference
        at com.example.ad.retrofittest.Maps.StartActivity$6$1.onMarkerClick(StartActivity.java:364)
...

No to chyba samo się tłumaczy? W metodzie onMarkerClick chcesz coś robić na obiekcie który jest/ma niezainicjowanego Integer... zacznij od tego.

Nie chce mi się myśleć nad tym.
Masz tam w ogóle jakieś wartości dla tych id markera?

int i = (int)  marker.getTag();

Używasz tam typu prostego który nie może być nullem

0

Problem naprawiony rozdzilem w funkcje sendmarkercall na 2 jedna odpowiedzialna stricte za kontakt z baza, druga funkcja odpowiedzialna za dodanie markera.

1 użytkowników online, w tym zalogowanych: 0, gości: 1