I'm downloading some text and images from the server using AsyncTask. I'm storing the texts and images in sq-lite database. I'm storing in the form of byte array.
In post Execute method of AsyncTask I store the convert the images in byte array and store them in database using for loop.
Problem is when I display data in List View from database sometimes it displays the correct images but some times it displays wrong images. I'm using a handler to delay the information into List View by 8 seconds. I've no idea why sometimes it shows the correct images and sometimes it shows wrong images.
What I'm doing wrong? How can I display the correct image every time. Moreover Can anyone help me how can I avoid the log cat message :
"Skipped XXX frames. The application is doing to much work in main thread."
I'm using fragments. As the application starts it will get data from server and which includes URL to Image. I'm using that URL to download images. Storing both the texts and images in database and showing it in List View in onPostExecute method.
Below are the codes I've used:
// convert from bitmap to byte array
public static byte[] getBytes(Bitmap bitmap) {
ByteArrayOutputStream byteArrayOutputStream =
new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 0, byteArrayOutputStream);
return byteArrayOutputStream.toByteArray();
}
In adapter class where I'm extending CursorAdapter class. I'm getting byte array from sq-lite database and converting it in image and display it to List View.
Code to convert from byte array to bitmap is below:
private static Bitmap getImage(byte[] image) {
return BitmapFactory.decodeByteArray(image, 0, image.length);
}
I'm setting it to list View item like this:
byte [] image = cursor.getBlob(imageColumnIndex);
if(image == null)
{
}else{
Bitmap bitmap = getImage(image);
imageView.setImageBitmap(bitmap);
}
Related
Does it store the data in memory or in the disk?
Asked this because I am planning to convert my parse file into an image thumbnail in which i set it to my list items. If it's in memory there would be no need to decode it in a background thread and since the file is in memory it would be garbage collected say when the activity is closed right?
ParseFile imageFile = event.getThumbnailFile();
final ParseImageView imageView = (ParseImageView) convertView.findViewById(R.id.event_thumbnail);
imageView.setPlaceholder(getResources().getDrawable(R.drawable.ic_report_problem_black_48dp));
imageFile.getDataInBackground(new GetDataCallback() {
#Override
public void done(byte[] bytes, ParseException e) {
Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length); // will replace this to convert bigger images into small ones
imageView.setImageBitmap(bitmap);
}
});
It seems that if the getDataInBackground is successful it apparently stores the the ParseFile in a disk cache. Subsequent calls to the method updates the disk cache when the file is updated on the cloud.
I'm a little bit confused about the caching procedure when the images are stored into a custom ArrayAdapter....
As far as I know you can use LruCache only on Activities, so how to cache images in an adapter?
A Cache is just a data structure that keeps track of Objects. You can create your own cache, then save, for example, bitmaps using URLs as keys. For example, take this Object:
public static Map<String, Object> cache = new HashMap<String, Object>();
This is your cache. You can now save images by their urls. For example, say you get a bitmap from http://www.example.com/img.png. A simple method like this will get the cached image if it exists, or get a new one if it does not:
public Bitmap getImage(String url)
{
synchronized(cache) {
Object o = cache.get(url);
if (o != null)
return (Bitmap) o;
//here, get the bitmap from the URL using whatever method you want, then save it and return it:
Bitmap bmp = getBitmapForURL(url);
cache.put(url, bmp);
return bmp;
}
}
So you just call:
myImageView.setImageBitmap(getImage("http://www.example.com/img.png"));
Store only image URIs in adapter not the images.
I am developing an offline application and I'm not getting any picture from user's gallery.
But I want to display the images to the users that I inserted manually.
The only solution I can think of is to put those images into drawable, then save it to the sqlite database (which I not sure how). Can this be done?
Thank you.
If you're willing to store the images in the drawable folders, you can store a reference to them in your database. Just store a string like com.example.yourapp:drawable/imagefilename and use this to display the image, where yourString contains the string from the database..
int imageResource = this.getResources().getIdentifier(yourString, null, null);
yourimageview.setImageResource(imageResource);
You can Use insert blob for this
public void insertImg(int id , Bitmap img ) {
byte[] data = getBitmapAsByteArray(img); // this is a function
insertStatement_logo.bindLong(1, id);
insertStatement_logo.bindBlob(2, data);
insertStatement_logo.executeInsert();
insertStatement_logo.clearBindings() ;
}
public static byte[] getBitmapAsByteArray(Bitmap bitmap) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.PNG, 0, outputStream);
return outputStream.toByteArray();
}
I'm trying to share from my app to Hyves using share intent. If I have hyves app installed and share from gallery it switch to hyves app, and upload image correctly to hyves, so it should work.
Problem is, I can't find it documented how should proper intent for hyves work, but I assume that gallery uploads images only, so I have this:
Bitmap image = BitmapFactory.decodeFile(MyGlobals.INSTANCE.activeSetting.f_image_path);
It's line of code where I pull my "active" or "selected" image within my app. At this point image is saved to SD Card, so I might read uri instead of decoding file, but I want it this way to have same approach for both hyves and facebook.
Then I call:
Intent hyvesIntent = new Intent(Intent.ACTION_SEND);
hyvesIntent.setPackage("com.hyves.android.application");
hyvesIntent.setType("image/jpeg");
hyvesIntent.putExtra("image", image);
startActivityForResult(hyvesIntent, 666);
First of all, I'm not sure if setPackage is OK to be used here, but I'm checking if this package exist to enable / disable share, and this is package name that is visible.
I need Activity result to then notify that Image is shared or not.
What happens here it starts the Hyves app, but I get full white screen, and then the Hyves app times out.
So, Can I use Bitmap in intent, and is it OK to setPackage or should I setClass?
Tnx
Maybe you can not put the bitmap directly in the intent.
First convert the bitmap into a byte array than send another side and convert into bitmap
//convert bitmap to bytearray
public static byte[] getBitmapAsByteArray(Bitmap bitmap, boolean type) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
if (type) {
bitmap.compress(CompressFormat.PNG, 0, outputStream);
} else {
bitmap.compress(CompressFormat.JPEG, 0, outputStream);
}
return outputStream.toByteArray();
}
//convert bitmap to bytearray
public static Bitmap getBitmap(byte[] imgByte){
Bitmap bm = BitmapFactory.decodeByteArray(imgByte, 0, imgByte.length);
return bm;
}
//than intent
Intent hyvesIntent = new Intent(Intent.ACTION_SEND);
hyvesIntent.setPackage("com.hyves.android.application");
hyvesIntent.setType("image/jpeg");
hyvesIntent.putExtra("image", getBitmapAsByteArray(image,true));
startActivityForResult(hyvesIntent, 666);
I hope that is right way to put image
My data are stored in html format on db.
The image are stored in base64 format (as a string in db).
I am trying to show this data.
My textView is setted like this:
setText(Html.fromHtml(content));
all html tags in 'content' are being displayed correctly. Except 'img' tag (which contains a base64 encode image).
So, my question is:
the tag 'img' of 'Html.fromHtml' can decode a string with base64 image?
p.s: The place where the tag is show just a little gray square. No got errors.
thx.
Use Html.fromHtml combined with your own implementation of Html.ImageGetter.
See here.
When overriding Html.ImageGetter.getDrawable, convert the Base64 string into a byte array (you can use android.util.Base64) and feed it into BitmapFactory.decodeByteArray to produce a Bitmap which you can then pass into the constructor of a BitmapDrawable to return.
For example:
Html.fromHtml(content, new Html.ImageGetter() {
#Override
public Drawable getDrawable(String source) {
byte[] data = Base64.decode(source, Base64.DEFAULT);
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
return new BitmapDrawable(getResources(), bitmap);
}
}, null);