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