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();
}
}
Related
i am trying lazy loading with LruCache as shown here : Example using Androids lrucache.
public class TCImageLoader implements ComponentCallbacks2 {
private TCLruCache cache;
Context cv;
public TCImageLoader(Context context) {
ActivityManager am = (ActivityManager) context.getSystemService(
Context.ACTIVITY_SERVICE);
int maxKb = am.getMemoryClass() * 1024;
int limitKb = maxKb / 8; // 1/8th of total ram
cache = new TCLruCache(limitKb);
cv = context;
}
public void display(String url, ImageView imageview, int defaultresource) {
imageview.setImageResource(defaultresource);
Bitmap image = cache.get(url);
if (image != null) {
imageview.setImageBitmap(image);
}
else {
new SetImageTask(imageview).execute(url);
}
}
private class TCLruCache extends LruCache<String, Bitmap> {
public TCLruCache(int maxSize) {
super(maxSize);
}
#Override
protected int sizeOf(String key, Bitmap value) {
int kbOfBitmap = value.getByteCount() / 1024;
return kbOfBitmap;
}
}
private class SetImageTask extends AsyncTask<String, Void, Integer> {
private ImageView imageview;
private Bitmap bmp;
public SetImageTask(ImageView imageview) {
this.imageview = imageview;
}
#Override
protected Integer doInBackground(String... params) {
String url = params[0];
try {
//bmp = BitmapFactory.decodeResource(cv.getResources(), url);
bmp = getBitmapFromURL(url);
if (bmp != null) {
cache.put(url, bmp);
}
else {
return 0;
}
} catch (Exception e) {
e.printStackTrace();
return 0;
}
return 1;
}
#Override
protected void onPostExecute(Integer result) {
if (result == 1) {
imageview.setImageBitmap(bmp);
}
//super.onPostExecute(result);
}
private Bitmap getBitmapFromURL(String src) {
try {
URL url = new URL(src);
HttpURLConnection connection
= (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
return myBitmap;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
}
#Override
public void onLowMemory() {
}
#Override
public void onTrimMemory(int level) {
/* if (level >= TRIM_MEMORY_MODERATE) {
cache.evictAll();
}
else if (level >= TRIM_MEMORY_BACKGROUND) {
cache.trimToSize(cache.size() / 2);
}*/
}
}
the TCimageloader is as shown in above code. my getview is as shown below :
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
// if it's not recycled, initialize some attributes
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(200, 200));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
// imageView.setPadding(10,10,10,10);
} else {
imageView = (ImageView) convertView;
}
imagloader = new TCImageLoader(mContext);
imagloader.display(mThumbIds[position], imageView, R.drawable.ic_launcher);
//Picasso.with(mContext).load(mThumbIds[position]).placeholder(R.drawable.ic_launcher).into(imageView);
imageView.setImageResource(R.drawable.ic_launcher);
return imageView;
}
but the problem i am facing is that when I scroll fast the getView has already been called and display method is already called. so the image views keep changing until the last called is implemented.
i am trying to make a custom gallery and this will also help me in downloading images from urls. I will have to use same method . will just have to change the file address to url address
I need to load an image from the web in my app, I found a good example here, but I can't figure out how to use the returned Bitmap in my Main Activity :
the class :
public class GetImageFromServer extends AsyncTask<Void, Void, Bitmap {
private String sURL;
GetImageFromServer(String urlParam) {
sURL = urlParam;
}
#Override
protected Bitmap doInBackground(Void... urlParam) {
Bitmap bmp = null;
//ImageView img = (ImageView) findViewById(R.id.imageView1);
try {
URL url = new URL(sURL);
bmp = BitmapFactory.decodeStream(url.openConnection().getInputStream());
} catch (Exception ex) {
Log.println(1, "Profile:getImg", ex.getMessage());
}
return bmp;
}
#Override
protected void onPreExecute() {}
}
And the MainActivity code :
String urlImage = "http://www.xxxxxx.com/css/images/xxxxxx.png";
GetImageFromServer gifs = new GetImageFromServer(urlImage);
gifs.execute();
if(person.has("Avatar")) {Avatar.setImageBitmap( gifs.execute())}
The error is :
gifs.execute()
Thanks for your help !
Add :
I added this "cancel(true)" because I have connection problems to JSON webservices after severals start/debug/close, but I doesn't seem to work :
#Override
protected Bitmap doInBackground(String... urlParam) {
if (isCancelled())
this.cancel(true);
Bitmap b = null;........
and
#Override
protected void onPostExecute(Bitmap result) {
// use the result
mImageView.setImageBitmap(result);
this.cancel(true);
}
Could the assynctasks prevent my app to connect to my webservices ?
There is a good library for doing async image loadings, here is a link: https://github.com/square/picasso.
Or you could follow this approach:
public class LoadImageAsyncTask extends AsyncTask<String, Void, Bitmap> {
private ImageView mImageView;
public LoadImageAsyncTask(ImageView imageView) {
mImageView = imageView;
}
#Override
protected Bitmap doInBackground(String... params) {
Bitmap bitmap = null;
try {
URL url = new URL(params[0]);
bitmap = BitmapFactory.decodeStream(url.openConnection().getInputStream());
} catch (Exception ex) {
Log.println(1, "Profile:getImg", ex.getMessage());
}
return bitmap;
}
#Override
protected void onPostExecute(Bitmap bitmap) {
mImageView.setImageBitmap(bitmap);
}
}
In your activity call:
LoadImageAsyncTask task = new LoadImageAsyncTask(findViewById(R.id.yourImageId)).execute(stringUrl);
you have to implement a callback
your asynctask
public class GetImageFromServer extends AsyncTask<Void, Void, Bitmap> {
private String sURL;
private Bitmap b;
YourCallback mOwner;
GetImageFromServer(YourCallback owner, String urlParam) {
sURL = urlParam;
mOwner = owner;
}
#Override
protected Bitmap doInBackground(Void... urlParam) {
try {
URL url = new URL(sURL);
b = BitmapFactory.decodeStream(url.openConnection()
.getInputStream());
} catch (Exception ex) {
Log.println(1, "Profile:getImg", ex.getMessage());
}
return b;
}
#Override
protected void onPreExecute() {
}
#Override
protected void onPostExecute(Bitmap result) {
// use the result
super.onPostExecute(result);
if (mOwner != null)
mOwner.CallbackFunction(result);
}
public interface YourCallback {
void CallbackFunction(Bitmap result);
}
}
your MainActivity
public class MainActivity extends Activity implements YourCallback {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
GetImageFromServer gifs = new GetImageFromServer(urlImage, b);
gifs.execute();
}
#Override
public void CallbackFunction(Bitmap result) {
if (person.has("Avatar")) {
Avatar.setImageBitmap(result);
}
}
}
I'm trying to display an image from a url in a "InfoWindowAdapter" ,I have the following code, but does not show me the image. What is wrong please ?
public class ObjectInfoWindow implements GoogleMap.InfoWindowAdapter {
private Activity activity;
private HashMap<String, LostObject> markers;
private Marker markerShowingInfoWindow;
private boolean mRefreshingInfoWindow;
private View v = null;
ImageUrlView imgThumbnail;
public LostObjectInfoWindow(Activity activity, HashMap<String, LostObject> markers) {
this.activity = activity;
this.markers = markers;
}
#Override
public View getInfoContents(Marker marker) {
DebugLog.d("TAG", "getInfoContents mRefreshingInfoWindow "+mRefreshingInfoWindow);
if(v==null){
v = activity.getLayoutInflater().inflate(R.layout.lost_object_info_window, null);
}
LostObject lostObject = markers.get(marker.getId());
if (lostObject != null) {
String imgThumbnailPath = lostObject.getPhoto();
if(imgThumbnailPath==null || imgThumbnailPath.trim().length() == 0){
TextView title = (TextView) v.findViewById(R.id.title);
TextView description = (TextView) v.findViewById(R.id.description);
title.setText(lostObject.getType());
if (lostObject.getContact() != null) {
description.setText(activity.getResources().getString(R.string.lost_object_contact_info_window, lostObject.getContact()));
}
imgThumbnail = (ImageUrlView) v.findViewById(R.id.thumbnail);
imgThumbnail.setScaleType(ImageView.ScaleType.FIT_CENTER);
imgThumbnail.setImageResource(R.drawable.ic_ayn_list_grey);
} else {
if (!mRefreshingInfoWindow) {
TextView title = (TextView) v.findViewById(R.id.title);
TextView description = (TextView) v.findViewById(R.id.description);
title.setText(lostObject.getType());
if (lostObject.getContact() != null) {
description.setText(activity.getResources().getString(R.string.lost_object_contact_info_window, lostObject.getContact()));
}
imgThumbnail = (ImageUrlView) v.findViewById(R.id.thumbnail);
markerShowingInfoWindow = marker;
imgThumbnailPath = imgThumbnailPath.replace(".jpg", "_100_100.jpg");
imgThumbnail.setListener(listener);
imgThumbnail.load(imgThumbnailPath);
}else{
v.invalidate();
}
}
}
// Returning the view containing InfoWindow contents
return v;
}
This method is called after the bitmap has been loaded. It checks if the currently displayed
info window is the same info window which has been saved. If it is, then refresh the windown to display the newly loaded image.
private ImageUrlView.ImageUrlViewListener listener = new ImageUrlView.ImageUrlViewListener() {
#Override
public void imageAdded(ImageUrlView img) {
if (markerShowingInfoWindow != null ) {
mRefreshingInfoWindow = true;
markerShowingInfoWindow.showInfoWindow();
mRefreshingInfoWindow = false;
}
}
};
}
Firstly, I do not see any variable that is storing the URL path/address. Hence there is no way for the program to get the location of the image and display it on to the info window. There are two ways to do that:
One is by using Universal Image Loader which is a library that you can embed in your app project. Which is quite similar to what you are doing in your app code using custominfoadapter. Please refer to this link for the complete implementation of the code.
Another method is to use a separate thread (Async Task is the best option to do that). This will load the image from the URL in the background and glue it inside the custominfowindow in a synchronized manner.
Here is a code snippet for that, Put this method inside your ObjectInfoWindow class and pass in URL and marker as parameters:
protected void handleMarkerClicked(final Marker marker, final String url) {
new AsyncTask<Void, Void, Void>()
{
#Override
protected void onPreExecute()
{
super.onPreExecute();
_infoImageDrawable = null;
}
#Override
protected Void doInBackground(Void... params)
{
InputStream is;
try {
is = (InputStream) new URL(url).getContent();
_infoImageDrawable = Drawable.createFromStream(is, "");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result)
{
super.onPostExecute(result);
marker.showInfoWindow();
}
}.execute();
}
}
Hope this would Help!!
I have tried to fetch the profile picture of linkedin user by the following url
http://api.linkedin.com/v1/people/"+userID+"/picture-url
But i'm getting file not found exception.
Try this, hopefully it should work for you or at least give you an idea how to go about it.
//picUrl is your linkedin contact image url
BitmapWorkerTask task = new BitmapWorkerTask(picUrl,mContactPic);
task.execute();
/* Async task to download the image from URL and display it in imageView*/
class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap>{
/*contact bitmap url */
private final String mUrl;
/*contact image view*/
ImageView mView;
public BitmapWorkerTask(String aUrl, ImageView aView) {
mUrl = aUrl;
mView = aView;
}
#Override
protected Bitmap doInBackground(String... params) {
if(mBgTaskCancel) {
/*cancel the execution of this task if the mBgTaskCancel flag is true */
this.cancel(false);
} else {
/*else get the contact bitmap from the url */
final Bitmap bitmap = Utils.getBitmapFromURL(this.mUrl);
return bitmap;
}
return null;
}
#Override
protected void onPostExecute(Bitmap aBitmap) {
if (aBitmap != null) {
/*set the image bitmap if it is not null */
mView.setImageBitmap(aBitmap);
}
}
}
/**
* function to download the image from url
*/
public static Bitmap getBitmapFromURL(String aURL) {
URL lBitmapURL;
Bitmap lBitmap = null;
try {
lBitmapURL = new URL(aURL);
InputStream lInStream = lBitmapURL.openStream();
lBitmap = BitmapFactory.decodeStream(lInStream);
} catch (IOException e) {
e.printStackTrace();
return null;
}
return lBitmap;
}
I am writing a small android application that uses an asyncTask to display an image from a web service. The code works but it has been brought to my attention that I should recycle this bitmap.
My question is, is there a way to recycle this bitmap after I am done using it?
I attempted a solution using the onStop() and either the bitmap didn't get recycled or the image wouldn't display at all.
Here is my OnCreate
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Other unrelated things
Intent intent = getIntent();
Bundle bundle = intent.getExtras();
imageUrl = bundle.getString("imageUrl");
displayImage();
}
And here is my AsyncTask
private void displayImage() {
new AsyncTask<String, Void, Bitmap>() {
protected Bitmap doInBackground(String... params) {
try {
return loadBitmap(params[0]);
} catch (Exception e) {
Logger.e(TAG, getString(R.string.error_loading_image_bitmap));
return null;
}
}
protected Bitmap loadBitmap(String urlSpec) throws IOException {
InputStream is = new URL(urlSpec).openStream();
try {
return BitmapFactory.decodeStream(is);
} finally {
is.close();
}
}
protected void onPostExecute(Bitmap bitmap) {
if (bitmap != null) {
ImageView invoiceItemImageView = (ImageView) findViewById(R.id.some_id_here);
invoiceItemImageView.setImageBitmap(bitmap);
}
}
}.execute(imageUrl);
}
Override method View.onDetachedFromWindow() and recycle your Bitmap there.