I am trying to load marker icons from URL but it's not showing me the icons on a map.What thing I am doing wrong.When I am using Bitmap to load icons it's working.
Picasso image load is not working for me.
I got the item name in a log:
>
....
D/success: #+ Set bitmap for Duke Of Wellington PT size: #3
D/success: #+ Set bitmap for Dante Gabriel Rossetti PT size: #2
D/success: #+ Set bitmap for Pierre Teilhard de Chardin PT size: #1
Here is my complete code :
private class CreateProductListTask extends AsyncTask<Void, Void, List<Product>> {
private String serverUrl;
public CreateProductListTask(String url) {
super();
this.serverUrl = url;
}
#Override
protected List<Product> doInBackground(Void... params) {
.....
JSONObject response = new JSONObject(stringBuffer.toString());
List<Product> products = new ArrayList<>();
HashMap<String, Bitmap> iconsMap = new HashMap<>();
try {
JSONArray productsJSON = response.getJSONArray("all_products");
for (int ixProduct = 0; ixProduct < productsJSON.length(); ixProduct++) {
JSONObject productJSON = productsJSON.getJSONObject(ixProduct);
String mapIconStr = productJSON.getString("map_icon");
URI uri = new URI(mapIconStr);
String[] segments = uri.getPath().split("/");
String iconName = segments[segments.length - 1];
// percetn-encode URL
String mapIconPath = mapIconStr.substring(0, mapIconStr.indexOf(iconName));
String iconUrlString = mapIconPath + URLEncoder.encode(iconName, "UTF-8");
// replace "http:" with "https:"
iconUrlString = iconUrlString.replace("http:", "https:");
try {
Product product = new Product();
product.id = productJSON.getString("ID");
product.name = productJSON.getString("post_title");
product.lat = productJSON.getDouble("latitude");
product.lon = productJSON.getDouble("longitude");
id = product.id;
System.out.println("my Id stored" + id);
product.icons= iconUrlString;
products.add(product);
} catch (Exception ignore) {
}
}
} catch (JSONException ex) {
Log.e("App", "Failure", ex);
}
return products;
} catch (Exception ex) {
Log.e("App", "yourDataTask", ex);
return null;
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
#Override
protected void onPostExecute(List<Product> products) {
if (products != null) {
PoiTarget pt;
for (final Product product : products) {
Marker marker = googlemap.addMarker(new MarkerOptions()
.position(new LatLng(product.lat, product.lon))
.title(product.name)
/* .icon(BitmapDescriptorFactory.fromBitmap(product.icon))*/);
pt = new PoiTarget(marker);
poiTargets.add(pt);
Picasso.with(Frnt_mapActivity.this)
.load(product.icons)
.into(pt);
markerIds.put(marker, product.id);
}
}
}
}
//--------------------------------------------------------
// Inner class
//--------------------------------------------------------
class PoiTarget implements Target {
private Marker m;
public PoiTarget(Marker m) { this.m = m; }
#Override public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
m.setIcon(BitmapDescriptorFactory.fromBitmap(bitmap));
poiTargets.remove(this);
Log.d("success"," #+ Set bitmap for "+m.getTitle()+" PT size: #"+poiTargets.size());
}
#Override public void onBitmapFailed(Drawable errorDrawable) {
Log.e("Load Image Failed"," #+ [ERROR] Don't set bitmap for "+m.getTitle());
poiTargets.remove(this);
}
#Override public void onPrepareLoad(Drawable placeHolderDrawable) {
}
}
Use Glide for this purpose , it loads bitmap faster than picasso. Sometimes picasso throws error while loading but in Glide this thing does not happens.
also Dont forget to close and reopen the marker after loading the image. See code below.
if (marker.isInfoWindowShown()) {
marker.hideInfoWindow();
marker.showInfoWindow();
}
let me know if you still have confusion . i will post my full code.
Replace this code
#Override public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
m.setIcon(BitmapDescriptorFactory.fromBitmap(bitmap));
poiTargets.remove(this);
Log.d("success"," #+ Set bitmap for "+m.getTitle()+" PT size: #"+poiTargets.size());
}
with
#Override public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
poiTargets.remove(this);
m.setIcon(BitmapDescriptorFactory.fromBitmap(bitmap));
Log.d("success"," #+ Set bitmap for "+m.getTitle()+" PT size: #"+poiTargets.size());
}
Related
I get an xml with command html text and images. I want when I fetch the tag img generate the image inside the text. in IOS works correctly
namespace A.iOS.Renderer
{
public class CustomLabelRenderer : LabelRenderer
{
protected LineSpacingLabel LineSpacingLabel { get; private set; }
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
var attr = new NSAttributedStringDocumentAttributes();
var nsError = new NSError();
attr.DocumentType = NSDocumentType.HTML;
Control.AdjustsFontSizeToFitWidth = true;
var myHtmlData = NSData.FromString(Control.Text, NSStringEncoding.Unicode);
this.Control.AttributedText = new NSAttributedString(myHtmlData, attr, ref nsError);
this.Control.Font = UIFont.FromName("Lato", 20f);
Control.LineBreakMode = UILineBreakMode.Clip;
}
}
}
in android he even identifies the image, but just shows me a little square without image
namespace A.Droid.Renderer
{
public class CustomLabelRenderer : LabelRenderer
{
protected LineSpacingLabel LineSpacingLabel { get; private set; }
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
var label = (TextView)Control;
label.SetLineSpacing(11, 1);
label.TextFormatted = Html.FromHtml(Control.Text);
Control.MovementMethod = LinkMovementMethod.Instance; // Makes links clickable
this.UpdateLayout();
}
}
}
what I have to change in my command in android so that my images are displayed on the label ?
I hope it works for you.
onCreate()
Spanned spannedValue = Html.fromHtml("Your Html", getImageHTML(), null);
YourTextView.setText(spannedValue);
functions:
public Html.ImageGetter getImageHTML() {
Html.ImageGetter imageGetter = new Html.ImageGetter() {
public Drawable getDrawable(String source) {
DownloadImageTask task = new DownloadImageTask();
try {
return task.execute(new String[] { source }).get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
return null;
}
};
return imageGetter;
}
private class DownloadImageTask extends AsyncTask<String, Void, Drawable> {
protected Drawable doInBackground(String... urls) {
for(String s : urls) {
try {
Drawable drawable = Drawable.createFromStream(new URL(s).openStream(), "src name");
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
Integer width = size.x;
Integer height = size.y;
Integer heigtbol = height / 3;
drawable.setBounds(0, 0, width, heigtbol);
return drawable;
} catch (IOException exception) {
Log.v("IOException", exception.getMessage());
return null;
}
}
return null;
}
#Override
protected void onPostExecute(Drawable drawable) {
super.onPostExecute(drawable);
}
}
I'm trying to download multiple pictures using picasso. here's my code:
for(int i=1; i <=20; i++){
String url = img_url + i + "/profile.jpg";
String img_dir = img_dir + i;
Picasso.with(this).load(url).into(picassoImageTarget(getApplicationContext(),img_dir, img_name));
}
Url of the site looks like this:
site.com/img/equipment/1/profile.jpg,
site.com/img/equipment/2/profile.jpg,
site.com/img/equipment/3/profile.jpg
and so on ...
i tried
Picasso.with(this).load(url).into(picassoImageTarget(getApplicationContext(),img_dir, img_name));
without the for loop and it is working. images are not download when i place it inside the loop.
here's my Target
private Target picassoImageTarget(Context context, final String imageDir, final String imageName) {
Log.d("picassoImageTarget", " picassoImageTarget");
ContextWrapper cw = new ContextWrapper(context);
final File directory = cw.getDir(imageDir, Context.MODE_PRIVATE); // path to /data/data/yourapp/app_imageDir
return new Target() {
#Override
public void onBitmapLoaded(final Bitmap bitmap, Picasso.LoadedFrom from) {
new Thread(new Runnable() {
#Override
public void run() {
final File myImageFile = new File(directory, imageName); // Create image file
FileOutputStream fos = null;
try {
fos = new FileOutputStream(myImageFile);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Log.i("image", "image saved to >>>" + myImageFile.getAbsolutePath());
}
}).start();
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
if (placeHolderDrawable != null) {}
}
};
}
please help. thanks.
Targets are held in WeakReferences.
You need to hold a reference to the Targets you want to keep to prevent them from being garbage collected.
Maybe your code would look something like:
final class MyLoader {
final ArrayList<Target> targets = new ArrayList<>(20);
void load(...) {
for(...) {
Target target = picassoImageTarget(...);
targets.add(target);
picasso.load(...).into(target); // TODO: Maybe remove from list when complete.
}
}
}
The marker has an icon property and it contains a bitmap of the user's Facebook profile picture.
I'm not really sure why the first marker doesn't load. But if you post a second, third or 4th (etc...) it works completely fine!
I don't have any other markers being added in my code other than the block of code below.
EDIT: This is important. The 'bitmap' value seems to be null on the first try. So it seems the if statement with the condition 'bitmap!=null' is catching it and preventing it from posting the first marker...
static Bitmap bitmap = null;
private Target loadtarget;
globalMap.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() {
#Override
public void onMapLongClick(LatLng point) {
vibe.vibrate(100);
AccessToken accessToken = AccessToken.getCurrentAccessToken();
MarkerOptions marker = new MarkerOptions().position(
new LatLng(point.latitude, point.longitude))
.title("New Marker");
Log.e("TAG", accessToken.getUserId());
String imageURL = new String("https://graph.facebook.com/" + accessToken.getUserId() + "/picture?type=small");
loadBitmap(imageURL);
if(bitmap!=null) {
globalMap.addMarker(marker
.position(point)
.icon(BitmapDescriptorFactory.fromBitmap(bitmap))
.anchor(0.5f, 1));
}
}
});
}
public void loadBitmap(String url) {
if (loadtarget == null) loadtarget = new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
// do something with the Bitmap
handleLoadedBitmap(bitmap);
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
};
Picasso.with(getActivity()).load(url).into(loadtarget);
}
public void handleLoadedBitmap(Bitmap b) {
bitmap = b;
}
You are right, bitmap will be null on the first long click because there's no time to load bitmap. You are calling load() and immediately after that trying to show bitmap.
You can load bitmap not in the long click listener but before, may be in the same place of code where you're setting that listener.
String imageURL = new String("https://graph.facebook.com/" + accessToken.getUserId() + "/picture?type=small");
loadBitmap(imageURL);
globalMap.setOnMapLongClickListener(
// ...
// the same code without imageURL initialization and bitmap loading
);
Follow the Documentation
static Bitmap bitmap = null;
private Target loadtarget;
globalMap.setOnMapLoadedCallback(new OnMapLoadedCallback() {
#Override
public void onMapLoaded() {
globalMap.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() {
#Override
public void onMapLongClick(LatLng point) {
vibe.vibrate(100);
AccessToken accessToken = AccessToken.getCurrentAccessToken();
MarkerOptions marker = new MarkerOptions().position(
new LatLng(point.latitude, point.longitude))
.title("New Marker");
Log.e("TAG", accessToken.getUserId());
String imageURL = new String("https://graph.facebook.com/" + accessToken.getUserId() + "/picture?type=small");
loadBitmap(imageURL);
if(bitmap!=null) {
globalMap.addMarker(marker
.position(point)
.icon(BitmapDescriptorFactory.fromBitmap(bitmap))
.anchor(0.5f, 1));
}
}
});
}
});
public void loadBitmap(String url) {
if (loadtarget == null) loadtarget = new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
// do something with the Bitmap
handleLoadedBitmap(bitmap);
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
};
Picasso.with(getActivity()).load(url).into(loadtarget);
}
public void handleLoadedBitmap(Bitmap b) {
bitmap = b;
}
I found out why it wasn't posting on the first try. It's because I was calling my method loadBitmap(..) too late, I felt like the process of it retrieving the image and loading it into the target value was too long for the clickListener which instantly places the marker. I just assumed that so I called it earlier, in my method onMapReady(), and that did the job.
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'm trying to display an image from a URL in an InfoWindowAdapter, but it does not show me the image. I'm using Volley to load images.
Does anyone have an idea how to solve this problem?
Thanks for your help!
I got it solve the problem. It was necessary to download the image manually. How did the code:
private void loadImage(Marker marker) {
if (((BitmapDrawable) localImage
.getDrawable()) == null) {
new DownloadImage(localImage, marker).execute(urlImage);
}
private class DownloadImage extends AsyncTask<String, Void, Bitmap> {
private ImageView icone;
private Marker marker;
public DownloadImage(ImageView imageView, Marker marker) {
icone = imageView;
this.marker = marker;
}
#Override
protected Bitmap doInBackground(String... URL) {
String imageURL = URL[0];
Bitmap bitmap = null;
try {
// Download Image from URL
InputStream input = new java.net.URL(imageURL).openStream();
bitmap = BitmapFactory.decodeStream(input);
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
}
#Override
protected void onPostExecute(Bitmap result) {
if (result != null) {
icone.setImageBitmap(result);
} else {
icone.setBackgroundResource(R.drawable.ic_launcher);
}
marker.showInfoWindow();
}
}