I'm developing an Android app that uses Osmdroid to display the maps in offline mode. I have an issue when I want to zoom in or out by pinching on the map or using the build-in zoomcontrols. When I zoom in the map tiles are not always correctly rendered and when I zoom out the sometimes there are some gray tiles in the map, sometimes everything is rendered OK. It's not related on the location displayed on the map. My map tiles are stored in an osmdroid zip-file with the Mapnik source in the folder /mnt/sdcard/osmdroid. I'm using osmdroid-3.0.7.
So, any help is welcome.
See my code below (my includes aren't included here in the code):
public class MapActivity extends OSMapActivity {
private ArrayList<String[]> mapPointData;
private ArrayList<String[]> multiData;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.map);
setABTitle(getIntent().getExtras().getStringArray("geoLoc")[0]);
actionButtonVisible(getIntent().getExtras().getBoolean("routeList"));
initLayout();
setHomePoint();
}
#Override
protected void onResume() {
super.onResume();
Prefs.clearMapPrefs(this);
}
private void initLayout() {
c = this;
// Buttons # top of the activity
doseeBN = (ImageView) findViewById(R.id.mapDoseeBN);
eatdrinkBN = (ImageView) findViewById(R.id.mapEatdrinkBN);
nightlifeBN = (ImageView) findViewById(R.id.mapNightlifeBN);
sleepBN = (ImageView) findViewById(R.id.mapSleepBN);
// The LinearLayout with the ScrollView for the Subcategories in "Do & See"
doseeLL = (LinearLayout) findViewById(R.id.doseeSubCatLL);
top10BN = (Button) findViewById(R.id.mapDoseeTop10BN);
monumentsBN = (Button) findViewById(R.id.mapDoseeMonumentsBN);
museumBN = (Button) findViewById(R.id.mapDoseeMuseumsBN);
cultureBN = (Button) findViewById(R.id.mapDoseeCultureBN);
attractionsBN = (Button) findViewById(R.id.mapDoseeAttractionBN);
shoppingBN = (Button) findViewById(R.id.mapDoseeShoppingBN);
marketBN = (Button) findViewById(R.id.mapDoseeMarketBN);
// Init of the map an mapcontroller
mapView = (MapView) findViewById(R.id.osmMV);
mapView.setTileSource(TileSourceFactory.MAPNIK);
mapController = mapView.getController();
mapController.setZoom(16);
mapView.setUseDataConnection(false);
mapView.setBuiltInZoomControls(true);
mapView.setMultiTouchControls(true);
// mapView.setDrawingCacheEnabled(true);
mapData = new ArrayList<String[]>();
mapPointData = new ArrayList<String[]>();
multiData = new ArrayList<String[]>();
}
private void setHomePoint() {
//GeoPoint centerPt = new GeoPoint(50.89489, 4.34140); // Point of Grand Place Brussels
homeLat = Double.parseDouble(getIntent().getExtras().getStringArray("geoLoc")[1]);
homeLong = Double.parseDouble(getIntent().getExtras().getStringArray("geoLoc")[2]);
GeoPoint centerPt = new GeoPoint(homeLat, homeLong);
if (checkMapRange(Double.parseDouble(getIntent().getExtras().getStringArray("geoLoc")[1]),
Double.parseDouble(getIntent().getExtras().getStringArray("geoLoc")[2]))) {
mapController.setCenter(centerPt);
Drawable marker = getResources().getDrawable(R.drawable.ic_pin_marker);
ArrayList<OverlayItem> items = new ArrayList<OverlayItem>();
items.add(new OverlayItem("Here I am!", "Hello", centerPt));
ItemizedOverlay<OverlayItem> itemOverlay =
new ItemizedIconOverlay<OverlayItem>(items, marker, null, new DefaultResourceProxyImpl(this));
mapView.getOverlays().add(itemOverlay);
mapView.invalidate();
} else {
mapController.setCenter(new GeoPoint(50.89489, 4.34140));
mapController.setZoom(11);
Action.alert(this, getResources().getString(R.string.alert_title_notinregion),
getResources().getString(R.string.alert_message_notinregion), false);
mapView.setClickable(false);
}
}
public void onClickMapPointsBN(View v) {
switch(v.getId()) {
case R.id.mapDoseeBN:
setPrefsCategory("DOSEE", doseeBN, "btn_map_dosee", "btn_map_dosee_pressed");
break;
case R.id.mapEatdrinkBN:
setPrefsCategory("EATDRINK", eatdrinkBN, "btn_map_eatdrink", "btn_map_eatdrink_pressed");
break;
case R.id.mapNightlifeBN:
setPrefsCategory("NIGHTLIFE", nightlifeBN, "btn_map_nightlife", "btn_map_nightlife_pressed");
break;
case R.id.mapSleepBN:
setPrefsCategory("SLEEP", sleepBN, "btn_map_sleep", "btn_map_sleep_pressed");
break;
}
setPOIs();
}
public void onClickDoseeListBN(View v) {
switch (v.getId()) {
case R.id.mapDoseeTop10BN:
setDosseSubCat(Definitions.doseeList[0], top10BN);
break;
case R.id.mapDoseeMuseumsBN:
setDosseSubCat(Definitions.doseeList[2], museumBN);
break;
case R.id.mapDoseeCultureBN:
setDosseSubCat(Definitions.doseeList[3], cultureBN);
break;
case R.id.mapDoseeAttractionBN:
setDosseSubCat(Definitions.doseeList[4], attractionsBN);
break;
case R.id.mapDoseeShoppingBN:
setDosseSubCat(Definitions.doseeList[5], shoppingBN);
break;
case R.id.mapDoseeMarketBN:
setDosseSubCat(Definitions.doseeList[6], marketBN);
break;
default:
setDosseSubCat(Definitions.doseeList[1], monumentsBN);
break;
}
setPOIs();
}
private void setPrefsCategory(String cat, ImageView btn, String image, String imageSelected) {
boolean sel = Prefs.getBoolean(this, "map" + cat, false);
Prefs.setBoolean(this, "map" + cat, !sel);
setCategoryImage(btn, image, imageSelected, sel);
if (cat.equalsIgnoreCase("DOSEE")) {
if (sel) {
doseeLL.setVisibility(View.GONE);
} else {
doseeLL.setVisibility(View.VISIBLE);
for (String s : Definitions.doseeList) {
if (s.equals(Definitions.doseeList[1])) {
Prefs.setBoolean(this, "mapDS_" + s, true);
} else {
Prefs.setBoolean(this, "mapDS_" + s, false);
}
}
}
setSubcategoryColor(sel);
}
}
private void setCategoryImage(ImageView btn, String image, String imageSelected, boolean selected) {
String devLang = Prefs.getString(this, "devLanguage", "en");
if (!devLang.equalsIgnoreCase("en")) {
image += "_" + devLang;
imageSelected += "_" + devLang;
}
if (selected) {
btn.setImageResource(this.getResources().getIdentifier(image, "drawable", getPackageName()));
} else {
btn.setImageResource(this.getResources().getIdentifier(imageSelected, "drawable", getPackageName()));
}
}
private void setSubcategoryColor(boolean doseeSelected) {
setDoseeSubCatTextColor(true, top10BN);
setDoseeSubCatTextColor(doseeSelected, monumentsBN);
setDoseeSubCatTextColor(true, museumBN);
setDoseeSubCatTextColor(true, cultureBN);
setDoseeSubCatTextColor(true, attractionsBN);
setDoseeSubCatTextColor(true, shoppingBN);
setDoseeSubCatTextColor(true, marketBN);
}
private void setPOIs() {
mapView.getOverlays().clear();
mapView.invalidate();
mapData.clear();
setHomePoint();
boolean selected;
for (String category : Definitions.categoryList) {
selected = Prefs.getBoolean(this, "map" + category, false);
Log.d("VB.Map", "Category: " + category + " selected: " + selected);
if (selected) {
if (category.equalsIgnoreCase("DOSEE")) {
boolean subSelected;
for (String subcategory : Definitions.doseeList) {
subSelected = Prefs.getBoolean(this, "mapDS_" + subcategory, false);
if (subSelected) {
getSqlData(category, subcategory);
}
}
} else {
getSqlData(category, null);
}
}
}
removeMapDataItems();
//mapPointData = mapData;
//multiDataLocationSelector();
setMapDataPoints();
//setMultiMapPoints();
}
private void getSqlData(String category, String subCategory) {
ArrayList<String[]> sqlData = SqlDB.db.getCategoryItems(Adjust.rewriteCategoryName(category), subCategory);
for (String[] data : sqlData) {
mapData.add(data);
}
}
private void removeMapDataItems() {
for (int i = 0; i < mapData.size(); i++) {
if ((mapData.get(i)[13].equalsIgnoreCase("")) || (mapData.get(i)[14].equalsIgnoreCase(""))) {
mapData.remove(i);
i--;
}
}
}
private void setDosseSubCat(String subCat, Button btn) {
boolean selected = Prefs.getBoolean(this, "mapDS_" + subCat, false);
Prefs.setBoolean(this, "mapDS_" + subCat, !selected);
setDoseeSubCatTextColor(selected, btn);
}
private void setDoseeSubCatTextColor(boolean selected, Button btn) {
if (selected) {
btn.setTextColor(Definitions.colorDoseeSubcat);
} else {
btn.setTextColor(Definitions.colorDoseeSubcatSelected);
}
}
private void setMapDataPoints() {
if (mapData != null) {
ArrayList<OverlayItem> mapOverlays = new ArrayList<OverlayItem>();
OverlayItem overlayItem;
for (String[] item : mapData) {
multiData.add(item);
if (existsInOverlayItems(item, mapOverlays)) {
overlayItem = new OverlayItem("-1", "", new GeoPoint(Float.parseFloat(item[13]), Float.parseFloat(item[14])));
overlayItem.setMarker(getResources().getDrawable(R.drawable.ic_pin_multiple));
} else {
overlayItem = new OverlayItem(item[0], "", new GeoPoint(Float.parseFloat(item[13]), Float.parseFloat(item[14])));
overlayItem.setMarker(getResources().getDrawable(getResources().getIdentifier(item[15], "drawable", getPackageName())));
}
mapOverlays.add(overlayItem);
}
setMapOverlays(mapOverlays);
}
}
private boolean existsInOverlayItems(String[] item, ArrayList<OverlayItem> overlayItemList) {
for (int i = 0; i < overlayItemList.size(); i++) {
if ((new GeoPoint(Double.parseDouble(item[13]), Double.parseDouble(item[14]))).equals(overlayItemList.get(i).mGeoPoint)) {
overlayItemList.remove(i);
return true;
}
}
return false;
}
private void setMapOverlays(ArrayList<OverlayItem> overlays) {
ItemizedOverlay<OverlayItem> itemOverlays = new ItemizedIconOverlay<OverlayItem>(
overlays, getResources().getDrawable(R.drawable.ic_pin_marker), new ItemizedIconOverlay.OnItemGestureListener<OverlayItem>() {
public boolean onItemLongPress(int arg0, OverlayItem item) {
mapOverlayItemPressed(Integer.parseInt(item.mTitle), item);
return false;
}
public boolean onItemSingleTapUp(int arg0, OverlayItem item) {
mapOverlayItemPressed(Integer.parseInt(item.mTitle), item);
return false;
}
}, new DefaultResourceProxyImpl(this));
mapView.getOverlays().add(itemOverlays);
mapView.invalidate();
}
private void mapOverlayItemPressed(int itemId, OverlayItem overlayItem) {
if (itemId == -1) {
Collect.multiPOIList.clear();
for (String[] item : multiData) {
if ((new GeoPoint(Double.parseDouble(item[13]), Double.parseDouble(item[14]))).equals(overlayItem.mGeoPoint)) {
Collect.multiPOIList.add(item);
}
}
Action.alertWithListView(this, getResources().getString(R.string.alert_title_multiplepoi), false);
} else {
SqlDB.db.getItemsById(itemId);
Bundle b = new Bundle();
b.putInt("listSelection", 0);
Action.newIntent(c, DetailActivity.class, b);
}
}
private boolean checkMapRange(double lat, double lng) {
double mapLatMax = 50.922085;
double mapLatMin = 50.781631;
double mapLongMin = 4.240723;
double mapLongMax = 4.490662;
if ((lat > mapLatMin) && (lat < mapLatMax)) {
if ((lng > mapLongMin) && (lng < mapLongMax)) {
return true;
}
}
return false;
}
}
And here the code of the OSMapActivity:
public class OSMapActivity extends ActionbarActivity {
protected Context c;
protected MapView mapView;
protected MapController mapController;
protected ArrayList<String[]> mapData;
protected ImageView doseeBN;
protected ImageView eatdrinkBN;
protected ImageView nightlifeBN;
protected ImageView sleepBN;
protected LinearLayout doseeLL;
protected Button top10BN;
protected Button monumentsBN;
protected Button museumBN;
protected Button cultureBN;
protected Button attractionsBN;
protected Button shoppingBN;
protected Button marketBN;
protected double homeLat;
protected double homeLong;
public void onClickABActionButton(View v) {
boolean actionButton = Prefs.getBoolean(this, "abActionButtonRoute", false);
if (actionButton) {
// TODO Add with current location => location manager in separate class
/*GPS.init(this);
GPS.enableGPSProvider();
GPS.enableNetworkProvider();
//Action.loadApp(this, Intent.ACTION_VIEW, Uri.parse("geo:50.89489,4.34140?daddr=Heiveld+21+Opwijk"));
Action.loadApp(this, Intent.ACTION_VIEW, Uri.parse("http://maps.google.com/maps?saddr=" + GPS.latitude + "," + GPS.longitude
+ "&daddr=Heiveld+21+1745+Opwijk"));
GPS.stop();*/
Action.loadMapsWithMyLocation(this, homeLat, homeLong);
} else {
Collect.dbList.clear();
for (String[] data : mapData) {
Collect.dbList.add(data);
}
// TODO Load new intent with list
Action.newIntent(this, MapListActivity.class, null);
}
}
}
Thanks for your help.
Kr
I raised an issue on version 3.0.6 about this. In the comments the authors say it was fixed on Feb 1st. As the 3.0.7 jar is dated Jan 29, I assume the fix isn't in it. I'm sticking with version 3.0.5 for now, although the cycle maps don't work in it and the tile loading can be a bit flickery. If your maps are offline though, they should load pretty fast and flicker might not be an issue.
I'm not 100% sure if this is the same problem as reported here:
OSMDroid Google Group
If so then the solution (for now) seems to be to download the current OSMDroid source and build your own .jar library.
No changes to the source are required BUT the tile loading problem is fixed.
Related
UPD: I've found that there is something bad is happening to latitude and longitude field when I'm getting it from the database, for example it does not shows correctly using Toast.
I'm using a Firebase database in my project. It saves locations with additional information to Firebase database and I need to display markers corresponding to that locations on the map.
The writing database works without perfect.
However, reading does not work at all. I've followed this guide and defined the database as a field on my class, added instantiation in onCreate method and added ValueListener.
DatabaseReference databaseEvents;
//some code
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
databaseEvents = FirebaseDatabase.getInstance().getReference("events");
}
//somecode
databaseEvents.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// events.clear();
Toast.makeText(MapsActivity.this, "LUL", Toast.LENGTH_SHORT).show();
for (DataSnapshot event : dataSnapshot.getChildren()) {
Event e = event.getValue(Event.class);
events.add(e);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
//here I'm trying to display the markers.
When I'm trying to output the size of events it always prints 0 and so it does not print any marker on the map.
The full code is here:
public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback, View.OnClickListener, GoogleMap.OnInfoWindowClickListener {
private static final int PLACE_PICKER_REQUEST = 1;
private GoogleMap mMap;
private Button addEventBtn;
private PlacePicker.IntentBuilder builder;
private Place place;
private EditText editEventName;
private Spinner typeOfEvent;
private LatLng coordOfNewMarker;
private String nameOfNewMarker;
private String typeOfNewMarker;
private ViewGroup infoWindow;
private TextView infoTitle;
private TextView infoSnippet;
private Button infoButton1, infoButton2;
private OnInfoWindowElemTouchListener infoButtonListener1, infoButtonListener2;
DatabaseReference databaseEvents;
#Override
public void onClick(View v) {
place = null;
switch (v.getId()) {
case R.id.AddEventButton:
callPlacePicker();
break;
}
}
#Override
public void onInfoWindowClick(Marker marker) {
Toast.makeText(this, "Info window clicked",
Toast.LENGTH_SHORT).show();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
databaseEvents = FirebaseDatabase.getInstance().getReference("events");
}
#Override
public void onMapReady(GoogleMap googleMap){
mMap = googleMap;
addEventBtn = findViewById(R.id.AddEventButton);
final MapWrapperLayout mapWrapperLayout = findViewById(R.id.map_relative_layout);
mapWrapperLayout.init(mMap, getPixelsFromDp(MapsActivity.this, 39 + 20));
// We want to reuse the info window for all the markers,
// so let's create only one class member instance
this.infoWindow = (ViewGroup)getLayoutInflater().inflate(R.layout.custom_infowindow, null);
this.infoTitle = infoWindow.findViewById(R.id.nameTxt);
this.infoSnippet = infoWindow.findViewById(R.id.addressTxt);
this.infoButton1 = infoWindow.findViewById(R.id.btnOne);
this.infoButton2 = infoWindow.findViewById(R.id.btnTwo);
this.infoButtonListener1 = new OnInfoWindowElemTouchListener(infoButton1,
getResources().getDrawable(R.drawable.round_but_green_sel),
getResources().getDrawable(R.drawable.round_but_red_sel))
{
#Override
protected void onClickConfirmed(View v, Marker marker) {
Toast.makeText(MapsActivity.this, marker.getTitle() + "'s button clicked!", Toast.LENGTH_SHORT).show();
}
};
this.infoButton1.setOnTouchListener(infoButtonListener1);
this.infoButtonListener2 = new OnInfoWindowElemTouchListener(infoButton2,
getResources().getDrawable(R.drawable.round_but_green_sel),
getResources().getDrawable(R.drawable.round_but_red_sel))
{
#Override
protected void onClickConfirmed(View v, Marker marker) {
Toast.makeText(MapsActivity.this, marker.getSnippet() + "'s button clicked!", Toast.LENGTH_SHORT).show();
}
};
this.infoButton2.setOnTouchListener(infoButtonListener2);
mMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {
#Override
public View getInfoWindow(Marker marker) {
return null;
}
#Override
public View getInfoContents(Marker marker) {
infoTitle.setText(marker.getTitle());
infoSnippet.setText(marker.getSnippet());
infoButtonListener1.setMarker(marker);
infoButtonListener2.setMarker(marker);
mapWrapperLayout.setMarkerWithInfoWindow(marker, infoWindow);
return infoWindow;
}
});
final ArrayList<Event> events = new ArrayList<>();
databaseEvents.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// events.clear();
Toast.makeText(MapsActivity.this, "LUL", Toast.LENGTH_SHORT).show();
for (DataSnapshot event : dataSnapshot.getChildren()) {
Event e = event.getValue(Event.class);
events.add(e);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
/*
This code was being used for SQLite database which now is not being used at all.
ArrayList<Double> lat = new ArrayList<>();
ArrayList<Double> lng = new ArrayList<>();
ArrayList<String> name = new ArrayList<>();
ArrayList<String> type = new ArrayList<>();
String query = "SELECT * FROM "+ "locations";
Cursor cursor = locations.getWritableDatabase().rawQuery(query,null);
while(cursor.moveToNext()){
lat.add(cursor.getDouble(cursor.getColumnIndex("lat")));
lng.add(cursor.getDouble(cursor.getColumnIndex("lng")));
name.add(cursor.getString(cursor.getColumnIndex("name")));
type.add(cursor.getString(cursor.getColumnIndex("type")));
}*/
// It always print 0.
Toast.makeText(MapsActivity.this, ((Integer) events.size()).toString(), Toast.LENGTH_SHORT).show();
int sz = events.size();
for(int i = 0; i < sz; i++) {
mMap.addMarker(new MarkerOptions().position(new LatLng(Double.parseDouble(events.get(i).getLatitude()), Double.parseDouble(events.get(i).getLongitude())))
.title(events.get(i).getName())
.snippet(events.get(i).getType()));
}
addEventBtn.setOnClickListener(this);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == PLACE_PICKER_REQUEST) {
if (resultCode == RESULT_OK) {
place = PlacePicker.getPlace(this, data);
openDialog();
}
}
}
public void openDialog() {
android.support.v7.app.AlertDialog.Builder builder = new android.support.v7.app.AlertDialog.Builder(this);
LayoutInflater inflater = this.getLayoutInflater();
View view = inflater.inflate(R.layout.layout_dialog, null);
editEventName = view.findViewById(R.id.editEventName);
typeOfEvent = view.findViewById(R.id.spinnerEventType);
final LocationsDB locations = new LocationsDB(this);
final StatsDB stats = new StatsDB(this);
try {
final String selected = typeOfEvent.getSelectedItem().toString();
}
catch (Exception e) {
Toast.makeText(this, "BAD", Toast.LENGTH_LONG);
}
builder.setView(view)
.setTitle("Create Event")
.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
})
.setPositiveButton("create", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
coordOfNewMarker = place.getLatLng();
nameOfNewMarker = editEventName.getText().toString();
typeOfNewMarker = typeOfEvent.getSelectedItem().toString();
ContentValues event = new ContentValues();
Geocoder geocoder;
List<Address> addresses = new ArrayList<>();
geocoder = new Geocoder(getApplication(), Locale.getDefault());
try {
addresses = geocoder.getFromLocation(coordOfNewMarker.latitude,
coordOfNewMarker.longitude,
1); // Here 1 represent max location result to returned, by documents it recommended 1 to 5
} catch (IOException e) {
e.printStackTrace();
}
String address = addresses.get(0).getAddressLine(0);
event.put("lat", coordOfNewMarker.latitude);
event.put("lng", coordOfNewMarker.longitude);
event.put("name", nameOfNewMarker);
event.put("type", typeOfNewMarker);
event.put("address", address);
locations.insert(event);
addEvent(coordOfNewMarker.longitude, coordOfNewMarker.latitude, typeOfNewMarker, nameOfNewMarker, address);
ContentValues created = new ContentValues();
created.put("type", "created");
created.put("number", stats.get() + 1);
stats.update(created);
mMap.addMarker(new MarkerOptions().position(place.getLatLng()).title(editEventName.getText().toString())
.snippet(typeOfEvent.getSelectedItem().toString()));
}
});
builder.show();
}
public void callPlacePicker() {
builder = new PlacePicker.IntentBuilder();
try {
startActivityForResult(builder.build(this), PLACE_PICKER_REQUEST);
}
catch (Exception e) {
e.printStackTrace();
}
}
public static int getPixelsFromDp(Context context, float dp) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int)(dp * scale + 0.5f);
}
private void addEvent(Double lng, Double ltd, String type, String name, String address) {
String id = databaseEvents.push().getKey();
Event e = new Event(id, lng.toString(), ltd.toString(), type, name, address);
databaseEvents.child(id).setValue(e);
Toast.makeText(this, "Event added!", Toast.LENGTH_LONG).show();
}
}
I know exactly why I'm getting this error but I can't figure out how to fix it. So What I'm doing it drawing a bunch of markers using Picasso where I implement a Target and load the Marker Icon once the image is done download. However, the user is able to click a tab which would clear the map view. So in an effort to try and fix it I don't use getMap.clear() but rather track the markers in a hashmap and when the map should clear I loop through the hashmap and remove the marker from the map and clear the hashmap, however I'm still getting this issue.
Here is the function to remove the markers:
private void clearCars() throws IllegalArgumentException {
Iterator it = vehicles.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
Car aCar = (Car) pair.getValue();
if (aCar.getCurrentMarker() != null) {
if (aCar.getCurrentMarker().getmMarker() != null) {
aCar.getCurrentMarker().getmMarker().remove();
}
}
}
vehicles.clear();
}
This method draws the cars:
private void validateMap(ArrayList<Object> data) {
if (Theme.isCarTheme()) {
for (Object anObject : data) {
Car currentCar = (Car) anObject;
String uniqueIndex = currentCar.getCarID() + "-" + currentCar.getVehicleNumber();
CustomMarker aMarker = null;
if (vehicles.containsKey(uniqueIndex)) {
aMarker = ((Car) vehicles.get(uniqueIndex)).getCurrentMarker();
aMarker.getmMarker().setPosition(currentCar.getCarLocation());
} else {
MarkerOptions options = new MarkerOptions();
options.icon(BitmapDescriptorFactory.fromResource(R.drawable.blank_image));
options.position(currentCar.getCarLocation());
currentCar.setCurrentMarker(new CustomMarker(mapViewLayout.getMapView().getMap().addMarker(options)));
String strUrl = Constants.Car_IMAGE_URL + currentCar.getCarID() + assetType + ".png";
Picasso.with(getActivity()).load(strUrl).into(currentCar.getCurrentMarker());
vehicles.put(uniqueIndex, currentCar);
}
vehicles.get(uniqueIndex).setHasUpdated(true);
}
Iterator it2 = vehicles.entrySet().iterator();
while (it2.hasNext()) {
Map.Entry pair = (Map.Entry) it2.next();
Car aCar = (Car) pair.getValue();
if (aCar.isHasUpdated() == false) {
it2.remove();
aCar.getCurrentMarker().getmMarker().remove();
}
}
}
}
And this is the marker class:
public class CustomMarker implements Target {
Marker mMarker;
public CustomMarker(Marker marker) {
mMarker = marker;
}
#Override
public int hashCode() {
return mMarker.hashCode();
}
#Override
public boolean equals(Object o) {
if(o instanceof CustomMarker) {
Marker marker = ((CustomMarker) o).mMarker;
return mMarker.equals(marker);
} else {
return false;
}
}
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) throws IllegalArgumentException {
mMarker.setIcon(BitmapDescriptorFactory.fromBitmap(bitmap));
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
public Marker getmMarker() {
return mMarker;
}
}
I have an array that is filled with API data, and I have an expandablelistview to show the items of that array, now what I'm trying to do is when the user clicks on an item it saves th ID of that item into an array, so if the user select 2 items I want 2 Ids in my array, what is happening now is this: no matter if I select only one of the items it gets all of them and save it inside my array.
public class MainActivity extends Fragment {
private ExpandListAdapter ExpAdapter;
private ExpandableListView ExpandList;
private Button notificar;
private Context context;
MainActivity mContext;
private Button footer;
private double RaioEscola;
private CircleOptions mCircle;
GPSTracker tracker;
private Location location;
private Integer IdEscola;
public MainActivity() {
}
public MainActivity(Context context) {
this.context = context;
}
#Override
public View onCreateView(final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.expand, container, false);
ExpandList = (ExpandableListView) rootView.findViewById(R.id.exp_list);
notificar = (Button) rootView.findViewById(R.id.btnGetMoreResults);
new asyncTask(MainActivity.this).execute();
return rootView;
}
private class asyncTask extends AsyncTask<String, Void, Void> {
private ProgressDialog pd;
public asyncTask(MainActivity context) {
mContext = context;
pd = new ProgressDialog(getActivity());
pd.setTitle("Por Favor Espere ...");
pd.setMessage("Enviando ...");
if (!pd.isShowing()) {
pd.show();
}
}
#Override
protected Void doInBackground(final String... params) {
try {
String[] resposta = new WebService().get("filhos");
if (resposta[0].equals("200")) {
JSONObject mJSONObject = new JSONObject(resposta[1]);
JSONArray dados = mJSONObject.getJSONArray("data");
/* cria o array que vai receber os dados da api */
final ArrayList<Escolas> mArrayList = new ArrayList<Escolas>();
/* percorre o array, adicionando cada linha encontrada em um ArrayList */
for (int i = 0; i < dados.length(); i++) {
JSONObject item = dados.getJSONObject(i);
Escolas mEscolas = new Escolas();
mEscolas.setId_escola(item.optInt("id_escola"));
mEscolas.setCnpj(item.getString("cnpj"));
mEscolas.setRazao_social(item.getString("razao_social"));
mEscolas.setNome_fantasia(item.getString("nome_fantasia"));
mEscolas.setDistancia(Float.valueOf(item.getString("distancia")));
mEscolas.setLogradouro(item.optString("logradouro"));
mEscolas.setNumero(item.optString("numero"));
mEscolas.setBairro(item.getString("bairro"));
mEscolas.setComplemento(item.getString("complemento"));
mEscolas.setCep(item.getString("cep"));
mEscolas.setCidade(item.getString("cidade"));
mEscolas.setEstado(item.getString("estado"));
mEscolas.setLatitude(Float.parseFloat(item.getString("latitude")));
mEscolas.setLongitude(Float.parseFloat(item.getString("longitude")));
RaioEscola = Double.parseDouble(String.valueOf(mEscolas.getDistancia()));
IdEscola = mEscolas.getId_escola();
JSONObject alunos = item.optJSONObject("alunos");
JSONArray data = alunos.getJSONArray("data");
if (data != null) {
ArrayList<Filhos> arrayalunos = new ArrayList<Filhos>();
for (int a = 0; a < data.length(); a++) {
Filhos mFilhos = new Filhos();
JSONObject clientes = data.getJSONObject(a);
mFilhos.setId_aluno(clientes.optInt("id_aluno"));
mFilhos.setNome(clientes.optString("nome"));
mFilhos.setSobrenome(clientes.optString("sobrenome"));
mFilhos.setFoto(clientes.optString("foto"));
mFilhos.setModalidade_de_ensino(clientes.optString("modalidade_de_ensino"));
mFilhos.setObservacoes(clientes.optString("observacoes"));
arrayalunos.add(mFilhos);
}
mEscolas.setalunos(arrayalunos);
}
/* popula o array de viagens */
mArrayList.add(mEscolas);
ExpAdapter = new ExpandListAdapter(getActivity(), mArrayList);
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
ExpandList.setAdapter(ExpAdapter);
ExpAdapter.notifyDataSetChanged();
ExpAdapter.setChoiceMode(ExpandListAdapter.CHOICE_MODE_MULTIPLE);
ExpandList.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
#Override
public boolean onChildClick(final ExpandableListView parent, View v, final int groupPosition, final int childPosition, final long id) {
ExpAdapter.setClicked(groupPosition, childPosition);
final int index = parent.getFlatListPosition(ExpandableListView.getPackedPositionForChild(groupPosition, childPosition));
parent.setItemChecked(index, true);
parent.setSelectedChild(groupPosition, childPosition, true);
parent.getChildAt(index);
notificar.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
class update extends TimerTask {
public void run() {
try {
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
final float latitude = mArrayList.get(groupPosition).getLatitude();
final float longitude = mArrayList.get(groupPosition).getLongitude();
LatLng latLng = new LatLng(latitude, longitude);
drawMarkerWithCircle(latLng);
GPSTracker gps = new GPSTracker(getActivity());
double latitudegps = gps.getLatitude();
double longitudegps = gps.getLongitude();
float[] distance = new float[2];
Location.distanceBetween(mCircle.getCenter().latitude, mCircle.getCenter().longitude, latitudegps, longitudegps, distance);
if (distance[0] > mCircle.getRadius()) {
Toast.makeText(getActivity(), "Outside", Toast.LENGTH_LONG).show();
}
else {
Toast.makeText(getActivity(), "Inside", Toast.LENGTH_LONG).show();
AlertRest mAlertRest = new AlertRest();
try {
List<Integer> myIdList = new ArrayList<Integer>();
for (int i = 0; i < mArrayList.get(groupPosition).getalunos().size(); i++) {
Integer Idalunos = mArrayList.get(groupPosition).getalunos().get(i).getId_aluno();
myIdList.add(Idalunos);
}
mAlertRest.getNotificacao(1, mArrayList.get(groupPosition).getId_escola(), String.valueOf(myIdList), latitudegps, longitudegps);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
});
}
catch (Exception e) {
e.printStackTrace();
}
}
}
Timer timer = new Timer();
timer.schedule(new update(), 0, 15000);
}
private void drawMarkerWithCircle(LatLng position) {
mCircle = new CircleOptions().center(position).radius(RaioEscola);
}
});
return false;
}
});
}
});
}
/* retorna um array de objetos */
}
else {
throw new Exception("[" + resposta[0] + "] ERRO: " + resposta[1]);
}
}
catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void cursor) {
if (pd.isShowing()) {
pd.dismiss();
}
}
}
}
AlertRest:
public class AlertRest extends WebService {
private String recurso = "notificacoes";
private String[] resposta;
private AlertModelo mAlertModelo;
public AlertModelo getNotificacao(Integer id_usuario, String token, Integer id_escola, String ids_aluno, Double latitude, Double longitude) throws Exception {
/* dispara a requisição para a API retornar os dados do "recurso" necessário */
resposta = new WebService().postToken(recurso, token, "{\"id_usuario\":" + id_usuario + "," + "\"id_escola\":" + id_escola + "," + "\"ids_aluno\":\"" + ids_aluno + "\"," + "\"latitude\":" + latitude + "," + "\"longitude\":" + longitude + "}");
JSONObject mJSONObject = new JSONObject(resposta[1]);
if (resposta[1].equals("201")) {
mAlertModelo = new AlertModelo();
mAlertModelo.setId_usuario(mJSONObject.getInt(String.valueOf(id_usuario)));
mAlertModelo.setId_escola(mJSONObject.getInt(String.valueOf(id_escola)));
mAlertModelo.setIds_aluno(mJSONObject.getInt(String.valueOf(ids_aluno)));
mAlertModelo.setLatitude(mJSONObject.getDouble(String.valueOf(latitude)));
mAlertModelo.setLongitude(mJSONObject.getDouble(String.valueOf(longitude)));
}
return mAlertModelo;
}
}
The code is difficult to follow due to few nested loops and running tasks.
Anyway, I suspect the code below is causing your app to save all (unselected) items in the list:
for (int i = 0; i < mArrayList.get(groupPosition).getalunos().size(); i++) {
Integer Idalunos = mArrayList.get(groupPosition).getalunos().get(i).getId_aluno();
myIdList.add(Idalunos);
}
Note: Iterating through the entire list is a suspect. It should pick a certain item or items in the list.
So...another set of relevant codes can help us determine the code fix. I am not certain if there is a bug here also.
parent.setItemChecked(index, true);
parent.setSelectedChild(groupPosition, childPosition, true);
parent.getChildAt(index);
Note: These codes may be fine. The key code, I think, is the index. I am not too familiar with ExpandableListView.
Finally, suggested code fix:
Integer Idalunos = mArrayList.get(groupPosition).getalunos().get(index).getId_aluno();
...
myIdList.add(Idalunos);
Notice the variable index is used to get the correct item, Idalunos.
You are using mArrayList variable for initializing adapter and for filling myIdList at the same time. Of course myIdList would contain full list of your adapter.
UPDATE
It would be better to define myIdList as field of your MainActivity class and initialize it in onCreateView method.
On click not just add the value - you should check if this value is allready in list:
if(myIdList.contains(Idalunos)) {
myIdList.remove(Idalunos);
} else {
myIdList.add(Idalunos);
}
I have been using google maps api v2 for around a month.
Aside from the other bugs reported in the issue tracker I came across this following odd bug.
java.lang.IllegalStateException: Camera moved during a cancellation
which happens inside a CancelableCallback that I use for the animateCamera method.
The exception is traced back to the user touch event.
I believe this happens because the user is performing an interaction with the map while the onFinish/onCancel is being called now this does not happen often however it is quite irritating.
Is there anyway around this issue? I would appreciate any help you can provide.
Here is a complete code:
public void moveMapToSearchMarker(
final T fmMarker,
final FriendlyMapGoogleMapMarkerClickListener fmMarkerClickListener,
float zoomLevel) {
CameraUpdate camUpdate = CameraUpdateFactory.newLatLngZoom(fmMarker
.getMarker().getPosition(), zoomLevel);
getGoogleMap().animateCamera(camUpdate, new CancelableCallback() {
#Override
public void onFinish() {
setMarkerOnSearchComplete(fmMarker, fmMarkerClickListener);
}
#Override
public void onCancel() {
setMarkerOnSearchComplete(fmMarker, fmMarkerClickListener);
}
});
}
private void setMarkerOnSearchComplete(T fmMarker,
FriendlyMapGoogleMapMarkerClickListener fmMarkerClickListener) {
if (!fmMarker.getMarker().isVisible())
fmMarker.getMarker().setVisible(true);
for (T lstFmMarker : this)
lstFmMarker.setSearched(false);
fmMarker.setSearched(true);
createOrUpdateSearchMarker(fmMarker.getMarker().getPosition());
fmMarkerClickListener.onFriendlyMapMarkerClick(fmMarker, this, true);
}
public void createOrUpdateSearchMarker(LatLng searchMarkerPos) {
if (searchRadiusCircle == null) {
CircleOptions cOpts = new CircleOptions();
int strokeColor = getSearchRadiusColor() + 0xEE000000;
cOpts.center(searchMarkerPos).fillColor(getSearchRadiusColor())
.strokeColor(strokeColor).radius(12).strokeWidth(2F);
searchRadiusCircle = getGoogleMap().addCircle(cOpts);
} else {
searchRadiusCircle.setVisible(true);
searchRadiusCircle.setCenter(searchMarkerPos);
}
}
public <T extends FriendlyMapMarker> boolean onFriendlyMapMarkerClick(
T fmMarker, FriendlyMapMarkerList fmMarkerList,
boolean isOnCancelableCallback) {
FriendlyMapMarkerAndList fmMapMarkerAndList = new FriendlyMapMarkerAndList<FriendlyMapMarker, FriendlyMapMarkerList>();
fmMapMarkerAndList.fmMarker = fmMarker;
fmMapMarkerAndList.fmMarkerList = fmMarkerList;
return handleMarkerClick(fmMapMarkerAndList, isOnCancelableCallback);
}
private boolean handleMarkerClick(
FriendlyMapMarkerAndList fmMapMarkerAndList,
boolean isOnCancelableCallback) {
if (fmMapMarkerAndList == null)
return false;
final FriendlyMapMarker fmMarker = fmMapMarkerAndList.fmMarker;
Marker marker = fmMarker.getMarker();
final FriendlyMapMarkerList fmMarkerList = fmMapMarkerAndList.fmMarkerList;
if (fmMarker != null) {
if (fmMarker.getClass().equals(FriendlyMapPlaceMarker.class)) {
balloonActions.setCurrentFmMarker(fmMarker);
balloonActions.setPlaceLikeButtonVisibility();
CancelableCallback onCameraCompleteMove = new CancelableCallback() {
#Override
public void onFinish() {
openActionBalloon(fmMarker, fmMarkerList);
}
#Override
public void onCancel() {
openActionBalloon(fmMarker, fmMarkerList);
}
};
LatLng camPos = Utils.getRoundedLatLng(fmMarkerList
.getGoogleMap().getCameraPosition().target, 1e5);
LatLng markerPos = Utils.getRoundedLatLng(marker.getPosition(),
1e5);
if (!Utils.latLngEqualsByCoords(camPos, markerPos)
&& !isOnCancelableCallback)
fmMarkerList.getGoogleMap()
.animateCamera(
CameraUpdateFactory.newLatLng(fmMarker
.getLatLng()), 350,
onCameraCompleteMove);
else
onCameraCompleteMove.onFinish();
fmMarker.getMarker().showInfoWindow();
LoadAsyncBalloonExtendedStatisticsResult loadAsyncBalloonStatisticsResult = new LoadAsyncBalloonExtendedStatisticsResult(
activity, marker,
(FriendlyMapPlaceMarkerList) fmMarkerList);
loadAsyncBalloonStatisticsResult
.execute(((FriendlyMapPlaceMarker) fmMarker)
.getKnownLocationID());
return true;
}
if (fmMarker.getClass().equals(FriendlyMapDiscussionMarker.class)) {
balloonActionsDiscussion.setCurrentFmMarker(fmMarker);
final FriendlyMapDiscussionMarker fmdMarker = (FriendlyMapDiscussionMarker) fmMarker;
LatLng camPos = Utils.getRoundedLatLng(fmMarkerList
.getGoogleMap().getCameraPosition().target, 1e5);
LatLng markerPos = Utils.getRoundedLatLng(fmdMarker.getMarker()
.getPosition(), 1e5);
if (!Utils.latLngEqualsByCoords(camPos, markerPos)
&& !isOnCancelableCallback) {
CameraUpdate camUpdate = CameraUpdateFactory
.newLatLng(fmdMarker.getMarker().getPosition());
fmMarkerList.getGoogleMap().animateCamera(camUpdate, 350,
new CancelableCallback() {
#Override
public void onFinish() {
openWindowInfoActionBalloon(fmMarkerList,
fmdMarker);
}
#Override
public void onCancel() {
openWindowInfoActionBalloon(fmMarkerList,
fmdMarker);
}
});
} else {
openWindowInfoActionBalloon(fmMarkerList, fmdMarker);
}
return true;
}
if (fmMarker.getClass().equals(FriendlyMapThoughtMarker.class)) {
balloonActionThought.setCurrentFmMarker(fmMarker);
balloonActionThought.setDeleteButtonVisiblity();
final FriendlyMapThoughtMarker fmtMarker = (FriendlyMapThoughtMarker) fmMarker;
LatLng camPos = Utils.getRoundedLatLng(fmMarkerList
.getGoogleMap().getCameraPosition().target, 1e5);
LatLng markerPos = Utils.getRoundedLatLng(fmtMarker.getMarker()
.getPosition(), 1e5);
if (!Utils.latLngEqualsByCoords(camPos, markerPos)
&& !isOnCancelableCallback) {
CameraUpdate camUpdate = CameraUpdateFactory
.newLatLng(fmtMarker.getMarker().getPosition());
fmMarkerList.getGoogleMap().animateCamera(camUpdate, 350,
new CancelableCallback() {
#Override
public void onFinish() {
openWindowInfoActionBalloon(fmMarkerList,
fmtMarker);
}
#Override
public void onCancel() {
openWindowInfoActionBalloon(fmMarkerList,
fmtMarker);
}
});
} else {
openWindowInfoActionBalloon(fmMarkerList, fmtMarker);
}
return true;
}
}
return false;
}
private void openWindowInfoActionBalloon(
FriendlyMapMarkerList fmMarkerList, FriendlyMapMarker fmMarker) {
Marker m = fmMarker.getMarker();
m.showInfoWindow();
openActionBalloon(fmMarker, fmMarkerList);
}
private void openActionBalloon(FriendlyMapMarker marker,
FriendlyMapMarkerList fmMarkerList) {
Projection proj = fmMarkerList.getGoogleMap().getProjection();
Point markerScreenPoint = proj.toScreenLocation(marker.getMarker()
.getPosition());
if (marker.getClass().equals(FriendlyMapPlaceMarker.class)) {
balloonActionsDiscussion.setVisibility(View.INVISIBLE);
balloonActionThought.setVisibility(View.INVISIBLE);
setBalloonDimension(balloonActions, markerScreenPoint);
} else if (marker.getClass().equals(FriendlyMapDiscussionMarker.class)) {
balloonActions.setVisibility(View.INVISIBLE);
balloonActionThought.setVisibility(View.INVISIBLE);
setBalloonDimension(balloonActionsDiscussion, markerScreenPoint);
} else if (marker.getClass().equals(FriendlyMapThoughtMarker.class)) {
balloonActionsDiscussion.setVisibility(View.INVISIBLE);
balloonActions.setVisibility(View.INVISIBLE);
setBalloonDimension(balloonActionThought, markerScreenPoint);
}
}
private void setBalloonDimension(View ballonActionView,
Point markerScreenPoint) {
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) ballonActionView
.getLayoutParams();
int marginX = markerScreenPoint.x - (ballonActionView.getWidth() / 2);
int marginY = markerScreenPoint.y;
params.setMargins(marginX, marginY, -marginX, -marginY);
params.gravity = Gravity.NO_GRAVITY;
ballonActionView.setLayoutParams(params);
ballonActionView.setVisibility(View.VISIBLE);
}
I'd suggest posting that bug with stacktrace to the tracker.
at com.google.android.gms.maps.GoogleMap.animateCamera(Unknown Source)
at com.saipex.friendly_map.map_view_related_v2.FriendlyMapGoogleMapMarkerClickListener.handleMarkerClick(FriendlyMapGoogleMapMarkerClickListener.java:259)
at com.saipex.friendly_map.map_view_related_v2.FriendlyMapGoogleMapMarkerClickListener.onFriendlyMapMarkerClick(FriendlyMapGoogleMapMarkerClickListener.java:133)
at com.saipex.friendly_map.map_view_related_v2.model.FriendlyMapMarkerList.setMarkerOnSearchComplete(FriendlyMapMarkerList.java:163)
at com.saipex.friendly_map.map_view_related_v2.model.FriendlyMapMarkerList.access$0(FriendlyMapMarkerList.java:155)
at com.saipex.friendly_map.map_view_related_v2.model.FriendlyMapMarkerList$1.onCancel(FriendlyMapMarkerList.java:181)
It looks like you are trying something forbidden: animating camera in onCancel. The code would show us more.
My code is following ...
public class NameListActivity extends Activity implements TextWatcher {
private Button add = null;
private AutoCompleteTextView editAuto = null;
private Button chfrlist = null;
private ImageView im = null;
String access_token = new String();
private ImageView infobtn = null;
private PopupWindow popupWindow;
private View view;
private ProgressDialog pd;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_name_list);
access_token = MainService.readToken();
add = (Button) findViewById(R.id.add_button);
editAuto = (AutoCompleteTextView) findViewById(R.id.editAuto);
chfrlist = (Button) findViewById(R.id.chfrlistbutton);
im = (ImageView) findViewById(R.id.helpact);
im.setOnClickListener(new ImageListener());
infobtn = (ImageView) findViewById(R.id.informbtn);
initPopupWindow();
infobtn.setOnClickListener(new infobtnListener());
editAuto.addTextChangedListener(this);
add.setOnClickListener(new addListener());
chfrlist.setOnClickListener(new ChfrListListener());
}
public class addListener implements OnClickListener {
public void onClick(View v) {
addTask task = new addTask();
task.execute();
editAuto.setText("");
}
}
public void afterTextChanged(Editable arg0) {
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
onTextChangedTask task = new onTextChangedTask();
task.execute();
}
public class onTextChangedTask extends AsyncTask<Void, Void, Void> {
ArrayAdapter<String> adapter = null;
String[] userName = null;
String q = null;
JSONArray jsonArray = new JSONArray();
JSONObject jsonObject = null;
ArrayList<String> userNameArrayList = new ArrayList<String>();
Weibo weibo = new Weibo();
#Override
protected void onPreExecute() {
weibo.setToken(access_token);
q = editAuto.getText().toString();
System.out.println("start onTextChanged");
}
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
if (q.length() != 0) {
System.out.println("q is " + q);
String s1 = "https://api.weibo.com/search/suggestions/users.json";
try {
jsonArray = Weibo.client.get(s1,
new PostParameter[] { new PostParameter("q", q) })
.asJSONArray();
} catch (Throwable e) {
System.out.println("这里有个神马异常呢 。。。" + e);
}
System.out.println("return length is " + jsonArray.length());
for (int i = 0; i < jsonArray.length(); i++) {
try {
jsonObject = jsonArray.getJSONObject(i);
String sname = jsonObject.getString("screen_name");
userNameArrayList.add(sname);
} catch (JSONException e) {
e.printStackTrace();
}
}
userName = (String[]) userNameArrayList
.toArray(new String[userNameArrayList.size()]);
adapter = new ArrayAdapter<String>(NameListActivity.this,
android.R.layout.simple_dropdown_item_1line, userName);
}
return null;
}
#Override
protected void onPostExecute(Void v) {
System.out.println("post");
editAuto.setAdapter(adapter);
}
}
void showToast(String s) {
Toast toast = Toast.makeText(getApplicationContext(), s,
Toast.LENGTH_LONG);
toast.show();
}
public class addTask extends AsyncTask<Void, Void, Void> {
String s = null;
boolean flag = false;
User user = null;
Weibo weibo = new Weibo();
String screen_name = null;
protected void onPreExecute() {
Toast tt = Toast.makeText(getApplicationContext(), "正在将用户添加到备份名单",
Toast.LENGTH_LONG);
tt.setGravity(Gravity.CENTER, 0, 0);
tt.show();
weibo.setToken(access_token);
screen_name = editAuto.getText().toString();
}
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
if (screen_name.length() != 0) {
Users um = new Users();
try {
user = new User(Weibo.client.get(
"https://api.weibo.com/users/show.json",
new PostParameter[] { new PostParameter(
"screen_name", screen_name) })
.asJSONObject());
} catch (Throwable e) {
e.printStackTrace();
flag = true;
s = new String("您输入的这个用户好像不存在唉");
}
if (user != null) {
ContentValues values = new ContentValues();
values.put("uid", user.getId());
values.put("user_name", user.getName());
SQLiteDatabase db = null;
try {
db = MainService.getDatabase();
} catch (Exception e) {
System.out.println("db error");
finish();
}
Cursor result = db.query("users", new String[] { "uid",
"user_name" }, "uid=?",
new String[] { user.getId() }, null, null, null);
if (result.getCount() == 0)
db.insert("users", null, values);
} else {
flag = true;
s = new String("网络存在问题,检查一下吧");
}
} else {
flag = true;
s = new String("框里输入点东西才能添加啊");
}
return null;
}
#Override
protected void onPostExecute(Void v) {
if (flag == true) {
System.out.println("要打印的是" + s);
showToast(s);
}
}
}
public class infobtnListener implements OnClickListener {
public void onClick(View v) {
// TODO Auto-generated method stub
System.out.println("点击了图片");
ColorDrawable cd = new ColorDrawable(-0000);
popupWindow.setBackgroundDrawable(cd);
// popupWindow.showAsDropDown(v);
popupWindow.showAtLocation(findViewById(R.id.informbtn),
Gravity.LEFT | Gravity.BOTTOM, 0, 100);
}
}
public class ImageListener implements OnClickListener {
public void onClick(View v) {
// TODO Auto-generated method stub
// Intent t = new Intent(NameListActivity.this,
// GridLayoutActivity.class);
// startActivity(t);
finish();
}
}
public class ChfrListListener implements OnClickListener {
public void onClick(View v) {
if ((haveInternet() == true)
&& (GridLayoutActivity.hasAccessToken() == true)) {
// TODO Auto-generated method stub
pd = ProgressDialog.show(NameListActivity.this, "",
"正在从服务器上获取数据,可能需要较长时间,请耐心等待 ...");
/* 开启一个新线程,在新线程里执行耗时的方法 */
new Thread(new Runnable() {
public void run() {
Intent t = new Intent(NameListActivity.this,
ChooseFromListActivity.class);
startActivity(t);
finish();
handler.sendEmptyMessage(0);// 执行耗时的方法之后发送消给handler
}
}).start();
} else {
Intent t = new Intent(NameListActivity.this,
WebViewActivity.class);
startActivity(t);
finish();
}
}
}
private void initPopupWindow() {
view = getLayoutInflater().inflate(R.layout.namewindow, null);
popupWindow = new PopupWindow(view, ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
// 这里设置显示PopuWindow之后在外面点击是否有效。如果为false的话,那么点击PopuWindow外面并不会关闭PopuWindow。
popupWindow.setOutsideTouchable(true);// 不能在没有焦点的时候使用
}
private boolean haveInternet() {
NetworkInfo info = ((ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE))
.getActiveNetworkInfo();
if (info == null || !info.isConnected()) {
return false;
}
if (info.isRoaming()) {
// here is the roaming option you can change it if you want to
// disable internet while roaming, just return false
return true;
}
return true;
}
Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {// handler接收到消息后就会执行此方法
pd.dismiss();// 关闭ProgressDialog
}
};
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_name_list, menu);
return true;
}
}
My question is : when I input words in the EditText, nothing happened. But when I press backspace did the AutoCompleteTextView show the suggestion list ... the problem is in the editAuto.setAdapter(adapter);
What is wrong?
make the following changes in your code
1) Instead of
private AutoCompleteTextView editAuto = null; JUST WRITE private AutoCompleteTextView editAuto;
2) Add this line to onCrate()
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, <your array name here>);
and remove this line from onTextChangedTask()
ArrayList<String> userNameArrayList = new ArrayList<String>();
3) Add this line to onCrate()
editAuto.setAdapter(adapter);
I know this is way late but for those who face similar problems here is the solution to show the autoCompleteTextView's drop down whenever you want i.e on button click or onTextChanged. After you set the ArrayAdapter for the autoCompleteTextView just put the following line.
autoCompleteTextView.showDropDown();