Chat listview stop refreshing image views - java

So the problem is
1. We are using listView for chat application
2 . each time a chat is sent or rec we update the arrayList and update the adapter and do notifydatasetAdaper() for refreshing the list view.
3. So if we send 10 images in chat and then send 11th chat msg(let say text chtat) and then call notifydatasetadapter() in this case all the 10 images are refreshing.
4. So i need to stop this refreshing of images.
5. ListView must be refreshed without refreshing the images
So any idea how can i achieve this.. or may be m on the wrong path please show me the correct way of doing it.....!!!
I also tried using picaso but the library is conflicting with okhttp library ....!!!
Also this is the way i am showing the images
public class ImageFromSd extends AsyncTask<Object, Bitmap, Bitmap> {
ImageView im;
// int targetWidth = 200;
// int targetHeight = 200;
#Override
protected Bitmap doInBackground(Object... params) {
// TODO Auto-generated method stub
Bitmap bitmap = null;
try {
im = (ImageView) params[0];
String path = (String) im.getTag();
Log.d("ankit", "image path :::::" + path);
bitmap = BitmapFactory.decodeFile(path);
// bitmap.compress(CompressFormat.JPEG, 100, new
// FileOutputStream(
// path));
//
// bitmap = Bitmap.createScaledBitmap(bitmap, targetWidth,
// targetHeight, false);
}
// catch (FileNotFoundException e) {
// e.printStackTrace();
// bitmap = null;
// }
catch (OutOfMemoryError e) {
e.printStackTrace();
bitmap = null;
} catch (NullPointerException e) {
e.printStackTrace();
bitmap = null;
} catch (Exception e) {
e.printStackTrace();
bitmap = null;
}
return bitmap;
}
#Override
protected void onPostExecute(Bitmap result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
if (result != null) {
im.setScaleType(ScaleType.FIT_CENTER);
im.setImageBitmap(result);
}
}
}
and then calling it like this
im.setTag(items.get(i).getTextChat());
new ImageFromSd().execute(im);

Firstly, You have to refresh listview as any data updates within listview.
Secondly, the method you using for loading image is not good.
try this library to load remote or local image. it maintains cache automatically and very efficient for image loading.
Universal Image Loader
https://github.com/nostra13/Android-Universal-Image-Loader

I am not checking for the bitmap is already cached or not.
Everytime when a imageView is passed to AsynTask, i am decoding from the path. Which is wrong.
I shouuld LRUCache or DiskCache and store the bitmap in cache with the path as key.
http://developer.android.com/reference/android/util/LruCache.html
http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html

Related

How to load a captcha image in image view? (Hotlinking the Captcha)

I'm trying to create a login form which loads the captcha from a specific url "http://evarsity.srmuniv.ac.in/srmsip/" into image view. But I'm unable to do so... What would be the best way to achieve this?
This is the code of the Java Class File below:
Document document = null;
try {
document = Jsoup.connect("http://evarsity.srmuniv.ac.in/srmsip/").ignoreContentType(true).get();
} catch (IOException e) {
e.printStackTrace();
}
Element captchaElement = document.select("#divmain img").first();
String captchaImgSrc = captchaElement.attr("src");
InputStream inputStream = null;
try {
inputStream = new URL("http://evarsity.srmuniv.ac.in/srmsip/" + captchaImgSrc).openStream();
} catch (IOException e) {
e.printStackTrace();
}
Bitmap captcha = BitmapFactory.decodeStream(inputStream);
ImageView captchaImage = (ImageView) findViewById(R.id.image);
captchaImage.setImageBitmap(captcha);
The image view either crashes showing nullPointer or with white colour background and in the last second line of the code the (ImageView) shows Casting is redundant.

Thumbnail for video from server not getting displayed in ImageView

Need to generate thumbnail from video stored in server, below is my code but "path" variable is giving problem, how to get it resolved. If i remove path parameter with url parameter then i am getting the thumbnails but not in proper order or sometimes same thumbnail is generated for 2 or 3 videos, below is my code -
Video video = mVideos.get(position);
//play video using android api, when video view is clicked.
url = video.getVideoUrl(); // your URL here
Uri videoUri = Uri.parse(url);
new DownloadImage(holder.videothumbView).execute(url);
public class DownloadImage extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;
public DownloadImage(ImageView bmImage) {
this.bmImage = (ImageView ) bmImage;
}
protected Bitmap doInBackground(String... urls) {
Bitmap myBitmap = null;
MediaMetadataRetriever mMRetriever = null;
try {
mMRetriever = new MediaMetadataRetriever();
if (Build.VERSION.SDK_INT >= 14)
mMRetriever.setDataSource(path, new HashMap<String, String>());
else
mMRetriever.setDataSource(path);
myBitmap = mMRetriever.getFrameAtTime();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (mMRetriever != null) {
mMRetriever.release();
}
}
return myBitmap;
}
protected void onPostExecute(Bitmap result) {
bmImage.setImageBitmap(result);
}
}
All the network related task must be done in a separate thread. You can't do it in main thread. You can use Picasso image library. It is open source and you can show different image for different state like loading, error etc.
Picasso.with(context) // your activity of other context referance
.load(video.getVideoUrl())
.placeholder(R.drawable.user_placeholder) // this will show during image loading from network
.error(R.drawable.user_placeholder_error) // error image to display
.into(holder.videothumbView);

Use glide to load bitmap to ImageView

I would like to use Glide to load bitmap to ImageView after cropping and re-sizing a bitmap.
I don't want to use ImageView.setImageBitmap(bitmap); because I am loading lots of images and it might be taking up some memory, although the images are small in size, I just need to use Glide because I know it optimises image caching.
I read this post, but I didn't quite understand his solution when I tried implementing it. So maybe someone has a cleaner and more easily understandable solution.
This is my code which picks up an image and creates a bitmap out of it.
I need to use glide instead of ImageView.setImageBitmap(bitmap);.
new AsyncTask<String, Void, Void>() {
Bitmap theBitmap = null;
Bitmap bm = null;
#Override
protected Void doInBackground(String... params) {
String TAG = "Error Message: ";
try {
//Load the image into bitmap
theBitmap = Glide.
with(mContext).
load("http://example.com/imageurl").
asBitmap().
into(-1, -1).
get();
//resizes the image to a smaller dimension out of the main image.
bm = Bitmap.createBitmap(theBitmap, 0, 0, 210, 80);
} catch (final ExecutionException e) {
Log.e(TAG, e.getMessage());
} catch (final InterruptedException e) {
Log.e(TAG, e.getMessage());
} catch (final NullPointerException e) {
//
}
return null;
}
#Override
protected void onPostExecute(Void dummy) {
if (null != theBitmap) {
//Set image to imageview.
**// I would like to Use Glide to set the image view here Instead of .setImageBitmap function**
holder.mImageView.setImageBitmap(bm);
holder.mImageView.setAdjustViewBounds(true);
holder.mImageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
}
}
}.execute();
You don't need AsyncTask to load image with Glide. Glide load image asynchronys.
Try to use this code:
Glide.with(mContext)
.load("http://example.com/imageurl")
.asBitmap()
.into(new SimpleTarget<Bitmap>() {
#Override
public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
// you can do something with loaded bitmap here
// .....
holder.mImageView.setImageBitmap(resource);
}
});

Detecting the Image Size to be displayed and use it by the Lazy Loading Image

I'd like to customized the size of the image used to cover up the real image to be displayed. In the UIL(Universal-Image-Loader) config, we can have .showStubImage(R.drawable.temp_drawable) as a display option.
My problem is, I am implementing a pinterest like view. By the time I scroll from the images, there is this unstable positions of the images because they are still being downloaded and covered up by a temp drawable. For example, the temporary drawable is 45 X 45, then the image to be displayed is 100 x 50. By the time the real image is showed there is this displacement effect of the images while scrolling because the temp image being replaced by the real one. Is there any way that we can detect the real image height and width to be displayed while is it still being downloaded, and using the width and height this can be used by the temp image to temporarily display the image size?
options = new DisplayImageOptions.Builder()
.showStubImage(R.drawable.ic_stub)
.showImageForEmptyUri(R.drawable.ic_empty)
.showImageOnFail(R.drawable.ic_error)
.cacheInMemory(true)
.cacheOnDisc(true)
imageLoader.displayImage(imageUrls[position], hold.image, options);
Update Code from the Universal-Image-Loader.jar
public void displayImage(String uri, ImageView imageView, DisplayImageOptions options, ImageLoadingListener listener) {
checkConfiguration();
if (imageView == null) {
throw new IllegalArgumentException(ERROR_WRONG_ARGUMENTS);
}
if (listener == null) {
listener = emptyListener;
}
if (options == null) {
options = configuration.defaultDisplayImageOptions;
}
if (TextUtils.isEmpty(uri)) {
engine.cancelDisplayTaskFor(imageView);
listener.onLoadingStarted(uri, imageView);
if (options.shouldShowImageForEmptyUri()) {
imageView.setImageResource(options.getImageForEmptyUri());
} else {
imageView.setImageDrawable(null);
}
listener.onLoadingComplete(uri, imageView, null);
return;
}
ImageSize targetSize = ImageSizeUtils.defineTargetSizeForView(imageView, configuration.maxImageWidthForMemoryCache, configuration.maxImageHeightForMemoryCache);
String memoryCacheKey = MemoryCacheUtil.generateKey(uri, targetSize);
engine.prepareDisplayTaskFor(imageView, memoryCacheKey);
listener.onLoadingStarted(uri, imageView);
Bitmap bmp = configuration.memoryCache.get(memoryCacheKey);
if (bmp != null && !bmp.isRecycled()) {
if (configuration.writeLogs) L.d(LOG_LOAD_IMAGE_FROM_MEMORY_CACHE, memoryCacheKey);
if (options.shouldPostProcess()) {
ImageLoadingInfo imageLoadingInfo = new ImageLoadingInfo(uri, imageView, targetSize, memoryCacheKey, options, listener, engine.getLockForUri(uri));
ProcessAndDisplayImageTask displayTask = new ProcessAndDisplayImageTask(engine, bmp, imageLoadingInfo, options.getHandler());
engine.submit(displayTask);
} else {
options.getDisplayer().display(bmp, imageView, LoadedFrom.MEMORY_CACHE);
listener.onLoadingComplete(uri, imageView, bmp);
}
} else {
if (options.shouldShowStubImage()) {
imageView.setImageResource(options.getStubImage());
} else {
if (options.isResetViewBeforeLoading()) {
imageView.setImageDrawable(null);
}
}
ImageLoadingInfo imageLoadingInfo = new ImageLoadingInfo(uri, imageView, targetSize, memoryCacheKey, options, listener, engine.getLockForUri(uri));
LoadAndDisplayImageTask displayTask = new LoadAndDisplayImageTask(engine, imageLoadingInfo, options.getHandler());
engine.submit(displayTask);
}
}
I like to have `.showStubImage(getImageDimension())'
Additional
new DownloadFilesTask().execute(imageUrls[position]);
private class DownloadFilesTask extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
URL uri = null;
try {
uri = new URL(params[0].toString());
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
InputStream in=null;
try
{
//URL oracle = new URL(url);
URLConnection urlConnection = uri.openConnection();
in = new BufferedInputStream(urlConnection.getInputStream());
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(in , null, options);
//return options;
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
if(in!=null)
IoUtils.closeSilently(in);
}
return null;
}
}
This is not really related to Android. It's about design of your app.
If it's your server, you should decide on the sizes of the images and how to manage them, and put the correct placeholder accordingly.
If it's not your server, you can't know the size of the images without contacting the server in any way, so you will either have to set a static size that images will fit into, or get the sizes of the images before even showing the placeholders.
getting the image resolution is done with server files the same way as with other files, using inJustDecodeBounds while decoding.
EDIT:here's a sample code of how to get the size of a bitmap from the internet:
public static BitmapFactory.Options getBitmapOptions(final String url)
{
InputStream in=null;
try
{
URLConnection urlConnection = url.openConnection();
in = new BufferedInputStream(urlConnection.getInputStream());
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(in , null, options);
return options;
}
finally
{
if(in!=null)
IOUtils.closeQuietly(in);
}
return null;
}
Usually you are allowed to give only resource id as per the library like below.
options = new DisplayImageOptions.Builder().showStubImage(R.drawable.stubImage)....
If at all you need to put your dynamically changing sized stub image, you need to tweak in the source code such that your options should accept sized bitmap rather than int. To do that I have just looked into the source code. Below are the steps:
Fist thing you need to do is to include it as library project instead of adding .jar in the libs folder.
In the ImageLoader class and then in the public void displayImage(String uri, ImageView imageView, DisplayImageOptions options, ImageLoadingListener listener) method, replace this line imageView.setImageResource(options.getImageForEmptyUri()); with imageView.setImageBitmap(sizedBitmap);
In the showStubImage(int stubImageRes) in DisplayImageOptions class, change the paramater as Bitmap and do necessary changes in that class.
Take care of all the things that need to be changed at where this feature gets reflected in different parts.
Changing the size of Bitmap:
Bitmap icon = BitmapFactory.decodeResource(context.getResources(),
R.drawable.stub_image);
bitmap = Bitmap.createScaledBitmap(stub, width, height, false);

Create NinePatch at Runtime

I have a business need to create the NinePatchDrawable objects at runtime, this is, an exterior .png image is received from a server and it has to be applied in a button's background (for example) as a nine patch.
I have tried to create the NinePatchDrawable object, but the constructor asks me for a "byte[] chunck" that describes the patch. The thing is, I have no idea on how to build this chunk from a bitmap that does not have the 9patch information in it.
Any ideas on this topic? Am I seeing the problem from a wrong perspective?
See my answer for Create a NinePatch/NinePatchDrawable in runtime
I develop a tool to create NinePatchDrawable from (uncompiled) NinePatch bitmap.
See https://gist.github.com/knight9999/86bec38071a9e0a781ee .
The method
NinePatchDrawable createNinePatchDrawable(Resources res, Bitmap bitmap)
helps you.
For example,
ImageView imageView = (ImageView) findViewById(R.id.imageview);
Bitmap bitmap = loadBitmapAsset("my_nine_patch_image.9.png", this);
NinePatchDrawable drawable = NinePatchBitmapFactory.createNinePatchDrawable(getResources(), bitmap);
imageView.setBackground( drawable );
where
public static final Bitmap loadBitmapAsset(String fileName,Context context) {
final AssetManager assetManager = context.getAssets();
BufferedInputStream bis = null;
try {
bis = new BufferedInputStream(assetManager.open(fileName));
return BitmapFactory.decodeStream(bis);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
bis.close();
} catch (Exception e) {
}
}
return null;
}
In this case, the my_nine_patch_image.9.png is under the assets directory.
I've answered this over at question 5519768. Keep in mind the differences between "source" and "compiled" ninepatch images.

Categories

Resources