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;
}
Related
I'm downloading multiple images through AsyncTask. It is working well when there are 2-3 images; but, when there are more images, many AsyncTask instances are created, and are causing errors. Do anyone have an idea how to overcome this problem?
Can you add your code here?
Maybe you can try to use onPostExecute function of your Asynctask to start a new one like:
protected void onPostExecute() {
doInBackground();
}
or you can trigger an activity function by your onPostExecute() function to start download " next picture " so it will only create one asynctask for one time.
From Android Doc: Common view components such as ListView and GridView
introduce another issue when used in conjunction with the AsyncTask as
demonstrated in the previous section. In order to be efficient with
memory, these components recycle child views as the user scrolls. If
each child view triggers an AsyncTask, there is no guarantee that when
it completes, the associated view has not already been recycled for
use in another child view. Furthermore, there is no guarantee that the
order in which asynchronous tasks are started is the order that they
complete.
Handle Concurrency
http://android-developers.blogspot.in/2010/07/multithreading-for-performance.html
public class ImageDownloader {
private static final String LOG_TAG = "ImageDownloader";
public enum Mode { NO_ASYNC_TASK, NO_DOWNLOADED_DRAWABLE, CORRECT }
private Mode mode = Mode.NO_ASYNC_TASK;
/**
* Download the specified image from the Internet and binds it to the provided ImageView. The
* binding is immediate if the image is found in the cache and will be done asynchronously
* otherwise. A null bitmap will be associated to the ImageView if an error occurs.
*
* #param url The URL of the image to download.
* #param imageView The ImageView to bind the downloaded image to.
*/
public void download(String url, ImageView imageView) {
resetPurgeTimer();
Bitmap bitmap = getBitmapFromCache(url);
if (bitmap == null) {
forceDownload(url, imageView);
} else {
cancelPotentialDownload(url, imageView);
imageView.setImageBitmap(bitmap);
}
}
/*
* Same as download but the image is always downloaded and the cache is not used.
* Kept private at the moment as its interest is not clear.
private void forceDownload(String url, ImageView view) {
forceDownload(url, view, null);
}
*/
/**
* Same as download but the image is always downloaded and the cache is not used.
* Kept private at the moment as its interest is not clear.
*/
private void forceDownload(String url, ImageView imageView) {
// State sanity: url is guaranteed to never be null in DownloadedDrawable and cache keys.
if (url == null) {
imageView.setImageDrawable(null);
return;
}
if (cancelPotentialDownload(url, imageView)) {
switch (mode) {
case NO_ASYNC_TASK:
Bitmap bitmap = downloadBitmap(url);
addBitmapToCache(url, bitmap);
imageView.setImageBitmap(bitmap);
break;
case NO_DOWNLOADED_DRAWABLE:
imageView.setMinimumHeight(156);
BitmapDownloaderTask task = new BitmapDownloaderTask(imageView);
task.execute(url);
break;
case CORRECT:
task = new BitmapDownloaderTask(imageView);
DownloadedDrawable downloadedDrawable = new DownloadedDrawable(task);
imageView.setImageDrawable(downloadedDrawable);
imageView.setMinimumHeight(156);
task.execute(url);
break;
}
}
}
/**
* Returns true if the current download has been canceled or if there was no download in
* progress on this image view.
* Returns false if the download in progress deals with the same url. The download is not
* stopped in that case.
*/
private static boolean cancelPotentialDownload(String url, ImageView imageView) {
BitmapDownloaderTask bitmapDownloaderTask = getBitmapDownloaderTask(imageView);
if (bitmapDownloaderTask != null) {
String bitmapUrl = bitmapDownloaderTask.url;
if ((bitmapUrl == null) || (!bitmapUrl.equals(url))) {
bitmapDownloaderTask.cancel(true);
} else {
// The same URL is already being downloaded.
return false;
}
}
return true;
}
/**
* #param imageView Any imageView
* #return Retrieve the currently active download task (if any) associated with this imageView.
* null if there is no such task.
*/
private static BitmapDownloaderTask getBitmapDownloaderTask(ImageView imageView) {
if (imageView != null) {
Drawable drawable = imageView.getDrawable();
if (drawable instanceof DownloadedDrawable) {
DownloadedDrawable downloadedDrawable = (DownloadedDrawable)drawable;
return downloadedDrawable.getBitmapDownloaderTask();
}
}
return null;
}
Bitmap downloadBitmap(String url) {
final int IO_BUFFER_SIZE = 4 * 1024;
// AndroidHttpClient is not allowed to be used from the main thread
final HttpClient client = (mode == Mode.NO_ASYNC_TASK) ? new DefaultHttpClient() :
AndroidHttpClient.newInstance("Android");
final HttpGet getRequest = new HttpGet(url);
try {
HttpResponse response = client.execute(getRequest);
final int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
Log.w("ImageDownloader", "Error " + statusCode +
" while retrieving bitmap from " + url);
return null;
}
final HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream inputStream = null;
try {
inputStream = entity.getContent();
// return BitmapFactory.decodeStream(inputStream);
// Bug on slow connections, fixed in future release.
return BitmapFactory.decodeStream(new FlushedInputStream(inputStream));
} finally {
if (inputStream != null) {
inputStream.close();
}
entity.consumeContent();
}
}
} catch (IOException e) {
getRequest.abort();
Log.w(LOG_TAG, "I/O error while retrieving bitmap from " + url, e);
} catch (IllegalStateException e) {
getRequest.abort();
Log.w(LOG_TAG, "Incorrect URL: " + url);
} catch (Exception e) {
getRequest.abort();
Log.w(LOG_TAG, "Error while retrieving bitmap from " + url, e);
} finally {
if ((client instanceof AndroidHttpClient)) {
((AndroidHttpClient) client).close();
}
}
return null;
}
/*
* An InputStream that skips the exact number of bytes provided, unless it reaches EOF.
*/
static class FlushedInputStream extends FilterInputStream {
public FlushedInputStream(InputStream inputStream) {
super(inputStream);
}
#Override
public long skip(long n) throws IOException {
long totalBytesSkipped = 0L;
while (totalBytesSkipped < n) {
long bytesSkipped = in.skip(n - totalBytesSkipped);
if (bytesSkipped == 0L) {
int b = read();
if (b < 0) {
break; // we reached EOF
} else {
bytesSkipped = 1; // we read one byte
}
}
totalBytesSkipped += bytesSkipped;
}
return totalBytesSkipped;
}
}
/**
* The actual AsyncTask that will asynchronously download the image.
*/
class BitmapDownloaderTask extends AsyncTask<String, Void, Bitmap> {
private String url;
private final WeakReference<ImageView> imageViewReference;
public BitmapDownloaderTask(ImageView imageView) {
imageViewReference = new WeakReference<ImageView>(imageView);
}
/**
* Actual download method.
*/
#Override
protected Bitmap doInBackground(String... params) {
url = params[0];
return downloadBitmap(url);
}
/**
* Once the image is downloaded, associates it to the imageView
*/
#Override
protected void onPostExecute(Bitmap bitmap) {
if (isCancelled()) {
bitmap = null;
}
addBitmapToCache(url, bitmap);
if (imageViewReference != null) {
ImageView imageView = imageViewReference.get();
BitmapDownloaderTask bitmapDownloaderTask = getBitmapDownloaderTask(imageView);
// Change bitmap only if this process is still associated with it
// Or if we don't use any bitmap to task association (NO_DOWNLOADED_DRAWABLE mode)
if ((this == bitmapDownloaderTask) || (mode != Mode.CORRECT)) {
imageView.setImageBitmap(bitmap);
}
}
}
}
/**
* A fake Drawable that will be attached to the imageView while the download is in progress.
*
* <p>Contains a reference to the actual download task, so that a download task can be stopped
* if a new binding is required, and makes sure that only the last started download process can
* bind its result, independently of the download finish order.</p>
*/
static class DownloadedDrawable extends ColorDrawable {
private final WeakReference<BitmapDownloaderTask> bitmapDownloaderTaskReference;
public DownloadedDrawable(BitmapDownloaderTask bitmapDownloaderTask) {
super(Color.BLACK);
bitmapDownloaderTaskReference =
new WeakReference<BitmapDownloaderTask>(bitmapDownloaderTask);
}
public BitmapDownloaderTask getBitmapDownloaderTask() {
return bitmapDownloaderTaskReference.get();
}
}
public void setMode(Mode mode) {
this.mode = mode;
clearCache();
}
/*
* Cache-related fields and methods.
*
* We use a hard and a soft cache. A soft reference cache is too aggressively cleared by the
* Garbage Collector.
*/
private static final int HARD_CACHE_CAPACITY = 10;
private static final int DELAY_BEFORE_PURGE = 10 * 1000; // in milliseconds
// Hard cache, with a fixed maximum capacity and a life duration
private final HashMap<String, Bitmap> sHardBitmapCache =
new LinkedHashMap<String, Bitmap>(HARD_CACHE_CAPACITY / 2, 0.75f, true) {
#Override
protected boolean removeEldestEntry(LinkedHashMap.Entry<String, Bitmap> eldest) {
if (size() > HARD_CACHE_CAPACITY) {
// Entries push-out of hard reference cache are transferred to soft reference cache
sSoftBitmapCache.put(eldest.getKey(), new SoftReference<Bitmap>(eldest.getValue()));
return true;
} else
return false;
}
};
// Soft cache for bitmaps kicked out of hard cache
private final static ConcurrentHashMap<String, SoftReference<Bitmap>> sSoftBitmapCache =
new ConcurrentHashMap<String, SoftReference<Bitmap>>(HARD_CACHE_CAPACITY / 2);
private final Handler purgeHandler = new Handler();
private final Runnable purger = new Runnable() {
public void run() {
clearCache();
}
};
/**
* Adds this bitmap to the cache.
* #param bitmap The newly downloaded bitmap.
*/
private void addBitmapToCache(String url, Bitmap bitmap) {
if (bitmap != null) {
synchronized (sHardBitmapCache) {
sHardBitmapCache.put(url, bitmap);
}
}
}
/**
* #param url The URL of the image that will be retrieved from the cache.
* #return The cached bitmap or null if it was not found.
*/
private Bitmap getBitmapFromCache(String url) {
// First try the hard reference cache
synchronized (sHardBitmapCache) {
final Bitmap bitmap = sHardBitmapCache.get(url);
if (bitmap != null) {
// Bitmap found in hard cache
// Move element to first position, so that it is removed last
sHardBitmapCache.remove(url);
sHardBitmapCache.put(url, bitmap);
return bitmap;
}
}
// Then try the soft reference cache
SoftReference<Bitmap> bitmapReference = sSoftBitmapCache.get(url);
if (bitmapReference != null) {
final Bitmap bitmap = bitmapReference.get();
if (bitmap != null) {
// Bitmap found in soft cache
return bitmap;
} else {
// Soft reference has been Garbage Collected
sSoftBitmapCache.remove(url);
}
}
return null;
}
/**
* Clears the image cache used internally to improve performance. Note that for memory
* efficiency reasons, the cache will automatically be cleared after a certain inactivity delay.
*/
public void clearCache() {
sHardBitmapCache.clear();
sSoftBitmapCache.clear();
}
/**
* Allow a new delay before the automatic cache clear is done.
*/
private void resetPurgeTimer() {
purgeHandler.removeCallbacks(purger);
purgeHandler.postDelayed(purger, DELAY_BEFORE_PURGE);
}
}
you can use Vinci android Library its testet and support Concurrency and its build on top
Builder Pattern
Singleton Pattern
Callback Pattern
and its handle downloading multi Images by her self and its easy to use .
if you wanna get a result of every download request :
Vinci
.base(context)
.process()
.load(uri,
new Request() {
#Override
public void onSuccess(Bitmap bitmap) {
viewHolder.Writer.setImageBitmap(bitmap);
//or
//do some thing with bitmap
}
#Override
public void onFailure(Throwable e) {
Log.e(e.getClass().getSimpleName(), e.getMessage());
}
});
if you wanna show image in ImageView you can use it like this
Vinci
.base(context)
.process()
.load(uri)
.view(imageView);
for use it in RecycleView see this wiki page
Simply use the Picasso library, to load the images into the ImageViews, as this is very simple to use and also supports concurrency very easily.
Example:
Picasso.with(this.context).load(url_of_image).into(imageView);
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 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();
}
}
I'm using UrlImageViewHelper library and it works fine.
It caches the images on internal storage and it's bad for me because I've about lots of images and if I want to cache them it's horrible.
How can I save these downloaded files and store them in SD card instead of internal storage?
Please check your whether your URL is valid or not by putting into browser. If image size is large then please use placeholder image which still displays your URL, not load image available, like this:
UrlImageViewHelper.setUrlDrawable(imageView, "http://example.com/image.png", R.drawable.placeholder);
Use this class
public class DemoHelper {
private static final String TAG = DemoMainActivity.TAG;
public static class RemoteImageTask extends AsyncTask<Void, Void, Bitmap> {
ImageView _image;
String _imageSource;
TaskCallback _callback;
public RemoteImageTask(ImageView image, String imageSource) {
this(image, imageSource, null);
}
public RemoteImageTask(ImageView image, String imageSource, TaskCallback callback) {
_image = image;
_imageSource = imageSource;
_callback = callback;
}
protected Bitmap doInBackground(Void... params) {
URL url;
Bitmap bmp = null;
try {
url = new URL(_imageSource);
bmp = BitmapFactory.decodeStream(url.openConnection().getInputStream());
} catch (Exception ignored) {
Log.e(TAG, "Exception", ignored);
}
return bmp;
}
protected void onPostExecute(Bitmap bmp) {
_image.setImageBitmap(bmp);
if (_callback != null)
_callback.onTaskFinished(bmp);
}
}
public interface TaskCallback {
public void onTaskFinished(final Bitmap bmp);
}
}
i have an galleyview which loads images from server album. but my album has many images [more than 500]. so once i scroll the galleyview more fast the number of background task is getting high so the app is getting crashed.so i am planning to kill [cancel] some old tasks based on the position in the galleryview. so please suggest some solution.The source code is provided below.
Task invoking:
DownloadImageTask downloadTask = new DownloadImageTask(
ShowGallery.this, view,position);
// cancel some task to avoid the crash - need to implement
// cancelPotentialDownload(position);
downloadTask.execute( THUMB_PREFIX + picture.getFileName(),
picture.getForceExtension(), thumbUrl,albumName, bitmapsCache, position, picture,null);
private static boolean cancelPotentialDownload(int position) {
// need to implement.
}
Downloadimage task
public class DownloadImageTask extends AsyncTask<Object, Void, Bitmap> {
Context activity;
private ImageView view;
public int position;
public DownloadImageTask(Context context, ImageView imageView, int imagePosition) {
super();
activity = context;
view = imageView;
position = imagePosition;
}
#Override
protected Bitmap doInBackground(Object... parameters) {
String fileName = (String) parameters[0];
String extension = (String) parameters[1];
String thumbUrl = (String) parameters[2];
Integer currentAlbumName = (Integer) parameters[3];
Map<Integer, Bitmap> bitmapsCache = (Map<Integer, Bitmap>) parameters[4];
Integer position = (Integer) parameters[5];
Picture picture = (Picture) parameters[6];
Album album = (Album) parameters[7];
Bitmap downloadImage = null;
File imageFileOnExternalDirectory = null;
try {
imageFileOnExternalDirectory = FileUtils.getInstance()
.getFileFromGallery(activity, fileName, extension,
thumbUrl, true, currentAlbumName);
downloadImage = BitmapFactory
.decodeFile(imageFileOnExternalDirectory.getPath());
if (picture != null) {
// only for showgallery activity
picture.setThumbImageCachePath(imageFileOnExternalDirectory
.getPath());
bitmapsCache.put(position, downloadImage);
} else if (album != null) {
// only for albumadapter
album.setAlbumCoverCachePath(imageFileOnExternalDirectory
.getPath());
}
} catch (GalleryConnectionException e) {
// Log.v(TAG, e.getMessage());
} catch (FileHandlingException e) {
// Log.v(TAG, e.getMessage());
}
return downloadImage;
}
#Override
protected void onPostExecute(Bitmap downloadImage) {
if (downloadImage != null) {
view.setImageBitmap(downloadImage);
}
}
}
Look at the example on this link. You are not downloading images from the web, so just replace this functionality with reading the image from gallery