How to resolve out of memory error in asynctask - android

i have used asynctask to insert images of sd card in listview. At around 229th image logcat shows OUT OF MEMORY error. I have used MediaStore.Images to retreive images from sd card into a cursor. Below is my code:
CursorLoader cursorLoader = new CursorLoader(MainActivity.this,
sourceUri, null, null, null, MediaStore.Images.Media.TITLE);
Cursor cursor = cursorLoader.loadInBackground();
new MyTask().execute(cursor);
MyTask extends AsyncTask. Here i have used do-while to retreive image using cursor and used for loop to correct the orientation of each image by using ExifInterface:
class MyTask extends AsyncTask<Cursor, Bitmap, Void> {
MyAdapter adap;
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
adap = (MyAdapter) listviewPic.getAdapter();
}
#Override
protected Void doInBackground(Cursor... cursor) {
// TODO Auto-generated method stub
ThumbImage = new Bitmap[cursor[0].getCount()];
cursor[0].moveToFirst();
int count = 0;
do {
String _id = cursor[0].getString(cursor[0]
.getColumnIndex(MediaStore.Images.Media._ID));
fileURI = Uri.withAppendedPath(sourceUri, _id);
fileURI = Uri.parse("file://"
+ getRealPathFromUri(getApplicationContext(), fileURI));
file = new File(fileURI.getPath());
Log.d("Fahad", "Value of pathURi is = " + fileURI);
try {
ThumbImage[count] = ThumbnailUtils.extractThumbnail(
BitmapFactory.decodeFile(file.getAbsolutePath()), 100,
100);
} catch (OutOfMemoryError e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.d("Fahad", "Error at = " + cursor[0].getPosition());
}
++count;
} while (cursor[0].moveToNext());
for (int i = 0; i < ThumbImage.length; i++) {
try {
ExifInterface exif = new ExifInterface(file.getName());
int orientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION, 1);
if (orientation == exif.ORIENTATION_ROTATE_90) {
Matrix matrix = new Matrix();
matrix.postRotate(90);
Log.d("Fahad", "Changing orientation. ThumbImage id " + i);
ThumbImage[i] = Bitmap.createBitmap(ThumbImage[i], 0, 0,
ThumbImage[i].getWidth(),
ThumbImage[i].getHeight(), matrix, true);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
publishProgress(ThumbImage);
return null;
}
#Override
protected void onProgressUpdate(Bitmap... bmp) {
// TODO Auto-generated method stub
MyAdapter adapter = new MyAdapter(getApplicationContext(),
R.layout.row, null, bmp);
listviewPic.setAdapter(adapter);
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
}
}
I have made custom adapter to display image:
class MyAdapter extends ArrayAdapter<String> {
Bitmap[] bmp = null;
Context context;
public MyAdapter(Context context, int resource, List<String> objects,
Bitmap[] bmp) {
super(context, resource, objects);
// TODO Auto-generated constructor stub
this.bmp = bmp;
this.context = context;
}
class MyViewHolder {
ImageView imageView;
public MyViewHolder(View v) { // TODO Auto-generated constructor
// stub
imageView = (ImageView) v.findViewById(R.id.imageView_row);
}
}
#Override
public int getCount() { // TODO Auto-generated method stub
return bmp.length;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Log.d("Fahad", "Inside getView");
View row = convertView;
MyViewHolder holder = null;
if (row == null) {
LayoutInflater layout = (LayoutInflater) context
.getSystemService(LAYOUT_INFLATER_SERVICE);
row = layout.inflate(R.layout.row, parent, false);
holder = new MyViewHolder(row);
row.setTag(holder);
} else {
holder = (MyViewHolder) row.getTag();
}
holder.imageView.setBackground(new BitmapDrawable(getResources(),
bmp[position]));
return row;
}
}

When you decode all bitmap at once, OOM will occur.
It's good idea to load bitmap in getView.
(and you can use loader that have async and caching system like Piccaso)

Related

Album Art Drawable Not Showing Up in ListView [Android]

I have been trying to figure this out for days, but can't seem to find the solution.
The problem is that even after getting the album art bitmap from MediaStore, and converting it to a drawable, it is assigned to an ImageView in a custom ListView layout via HashMap (String, Object), but finally after running on actual device and emulator, no album art is shown.
No LogCat error either. The ImageView of the custom listview layout does not show the album art.
public class AllSongs extends Fragment
{
Bitmap bitmap = null;
BitmapDrawable drawable = null;
private ArrayList<HashMap<String,Object>> list = new ArrayList<HashMap<String,Object>>();
private HashMap<String, Object> item;
private SimpleAdapter sa;
private ListView listview;
...
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState)
{
...
AsyncTaskRunner runner = new AsyncTaskRunner();
runner.execute("500");
}
private class AsyncTaskRunner extends AsyncTask<String, String, String>
{
#Override
protected String doInBackground(String... params) {
getAllMusicFiles();
return "Done!";
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
listview.setAdapter(sa); //Set all the file in the list.
}
}
private void getAllMusicFiles() {
// TODO Auto-generated method stub
//Some audio may be explicitly marked as not being music
String selection = MediaStore.Audio.Media.IS_MUSIC + " != 0";
String[] projection = {
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media.ALBUM,
MediaStore.Audio.Media.ALBUM_ID
};
Cursor cursor = getActivity().getApplicationContext().getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
projection,
selection,
null,
null);
while(cursor.moveToNext()){
item = new HashMap<String,Object>();
String title = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE));
String artist = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));
String album = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM));
long albumId = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID));
final Uri ART_CONTENT_URI = Uri.parse("content://media/external/audio/albumart");
Uri albumArtUri = ContentUris.withAppendedId(ART_CONTENT_URI, albumId);
ContentResolver res = context.getContentResolver();
InputStream in;
try { // Yes, the album art has been found. I am sure of this.
if(bitmap != null)
{
bitmap.recycle();
bitmap = null;
if(drawable != null)
{
drawable = null;
}
}
in = res.openInputStream(albumArtUri);
bitmap = BitmapFactory.decodeStream(in);
drawable = new BitmapDrawable(getResources(), bitmap);
} catch (FileNotFoundException e) { // Album not found so set default album art
e.printStackTrace();
drawable = (BitmapDrawable) getActivity().getResources().getDrawable(R.drawable.default_albumart);
}
item.put("icon", drawable);
item.put("title", title);
item.put("artist", artist);
list.add(item);
if(cursor.isLast())
{
sa = new SimpleAdapter(getActivity(), list,
R.layout.custom_listview_layout,
new String[] {"icon", "title","artist" },
new int[] {R.id.icon,R.id.title, R.id.artist});
}
}
}
I have detected that the drawable may be the one causing the image to not be shown because if I replace -
item.put("icon", drawable);
with -
item.put("icon", R.drawable.default_albumart);
it shows the default album art.
Any idea what's causing this?
It's your adapter implementation is causing the problems, not the Drawable.
Look at these two lines of code:
item.put("icon", drawable) - this puts a Drawable object to your hashmap
item.put("icon", R.drawable.default_albumart) - this puts an int value to your map, but as map only works with objects, it is autoboxed before being put there
Thus, the problem is that your adapter works fine with integer identifiers of drawables, but not the drawables themselves. These are the constraints of SimpleAdapter
To solve this issue I would suggest you to implement your custom CursorAdapter. Its implementation is simply straightforward, and will save you from unnecessary steps, such as creating unnecessary lists, hashmaps etc, wasting app memory.
Feel free to ask anything else in comments, good luck!
The answer was given correctly by Drew but here is how it was finally implemented. Here are the changes -
private void getAllMusicFiles() {
// TODO Auto-generated method stub
//Some audio may be explicitly marked as not being music
String selection = MediaStore.Audio.Media.IS_MUSIC + " != 0";
String[] projection = {
MediaStore.Audio.Media._ID, // this is required acc to documentation
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.ARTIST,
MediaStore.Audio.Media.ALBUM,
MediaStore.Audio.Media.ALBUM_ID
};
cursor = getActivity().getApplicationContext().getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
projection,
selection,
null,
null);
getActivity().startManagingCursor(cursor);
listview.setAdapter(new CustomCursorAdapter(context, cursor));
}
#Override
public void onDestroy() {
// TODO Auto-generated method stub
if(cursor != null)
{
getActivity().stopManagingCursor(cursor);
cursor.close();
}
super.onDestroy();
}
removed the AsyncTask as it wasn't here required anymore.
#Override
public void onViewCreated(View view, Bundle savedInstanceState)
{
...
AsyncTaskRunner runner = new AsyncTaskRunner();
runner.execute("500");
}
CustomCursorAdapter.java -
public class CustomCursorAdapter extends CursorAdapter {
#SuppressWarnings("deprecation")
public CustomCursorAdapter(Context context, Cursor c) {
super(context, c);
// TODO Auto-generated constructor stub
}
private Bitmap bitmap = null;
private BitmapDrawable drawable = null;
#Override
public void bindView(View view, Context context, Cursor cursor) {
// TODO Auto-generated method stub
TextView title1 = (TextView) view.findViewById(R.id.title);
TextView artist1 = (TextView) view.findViewById(R.id.artist);
ImageView album1 = (ImageView) view.findViewById(R.id.icon);
String title = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE));
String artist = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));
String album = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM));
long albumId = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID));
StringBuilder titleBuild = new StringBuilder();
titleBuild.append(title);
if(titleBuild.length() > 35)
{
titleBuild.setLength(32);
title = titleBuild.toString()+"...";
}
else
{
title = titleBuild.toString();
}
StringBuilder artistBuild = new StringBuilder();
artistBuild.append(artist);
if(artistBuild.length() > 35)
{
artistBuild.setLength(32);
artist = artistBuild.toString()+"...";
}
else
{
artist = artistBuild.toString();
}
final Uri ART_CONTENT_URI = Uri.parse("content://media/external/audio/albumart");
Uri albumArtUri = ContentUris.withAppendedId(ART_CONTENT_URI, albumId);
ContentResolver res = context.getContentResolver();
InputStream in;
try {
if(bitmap != null)
{
bitmap = null;
if(drawable != null)
{
drawable = null;
}
}
in = res.openInputStream(albumArtUri);
bitmap = BitmapFactory.decodeStream(in);
// bitmap = MediaStore.Images.Media.getBitmap(context.getContentResolver(), albumArtUri);
drawable = new BitmapDrawable(context.getResources(), bitmap);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
drawable = (BitmapDrawable) context.getResources().getDrawable(R.drawable.default_albumart);
}
album1.setImageDrawable(drawable);
title1.setText(title);
artist1.setText(artist);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
// TODO Auto-generated method stub
LayoutInflater inflater = (LayoutInflater)context.getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
return inflater.inflate(R.layout.custom_listview_layout, parent, false);
}
}

GetView method from ArrayAdapter getting called onScroll up and down

I have a Custom ArrayAdapter that has a getview method, the thing is that method is being called for different views if i scroll down and up, and this make this views load again (e.g. downloading an image).
In my ListActivity class, i only call adapter = new Adapter... and list.setAdapter() , after i download and parse a json (im using AQuery library).
public class AdapterPostagem extends ArrayAdapter<Postagem>{
Context context;
LayoutInflater inflater;
boolean memCache = false;
boolean fileCache = true;
String BASE_URL = "https://graph.facebook.com/";
public AdapterPostagem(Context context, int textViewResourceId,
List<Postagem> objects) {
super(context, textViewResourceId, objects);
// TODO Auto-generated constructor stub
inflater = (LayoutInflater)context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
this.context = context;
}
public class ViewHolder{
TextView postagem;
TextView likes;
ImageView foto;
View view;
TextView like;
TextView share;
ProgressBar pb;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder holder = null;
Postagem p = new Postagem();
p = getItem(position);
AQuery aq;
UrlImageViewHelper uHelper = new UrlImageViewHelper();
uHelper.setUseBitmapScaling(false);
if (convertView == null){
convertView = inflater.inflate(R.layout.postagem, parent, false);
Log.d("conv", "convertView_null");
Postagens posts = new Postagens();
Postagens.EndlessScrollListener end = posts.new EndlessScrollListener();
aq = new AQuery(convertView);
aq.scrolled(end);
holder = new ViewHolder();
holder.foto = (ImageView)convertView.findViewById(R.id.foto);
holder.postagem = (TextView)convertView.findViewById(R.id.postagem);
holder.like = (TextView)convertView.findViewById(R.id.likes);
holder.share = (TextView)convertView.findViewById(R.id.shares);
//holder.pb = (ProgressBar)convertView.findViewById(R.id.progress);
if (!p.getUrl_foto().equals("")){
getUrlPhoto(holder.foto, uHelper,p.getId(), aq, R.id.foto);
}else{
holder.foto.setVisibility(View.GONE);
}
holder.postagem.setText(p.getPostagem());
convertView.setTag(holder);
}else{
Log.d("conv", "convertView");
holder = (ViewHolder)convertView.getTag();
Postagens posts = new Postagens();
Postagens.EndlessScrollListener end = posts.new EndlessScrollListener();
aq = new AQuery(convertView);
aq.scrolled(end);
holder.foto = (ImageView)convertView.findViewById(R.id.foto);
holder.postagem = (TextView)convertView.findViewById(R.id.postagem);
if (!p.getId().equals("")){
getUrlPhoto(holder.foto, uHelper,p.getId(), aq, R.id.foto);
}else{
holder.foto.setVisibility(View.GONE);
}
//uHelper.setUrlDrawable(holder.foto, p.getUrl_foto());
setTextWithURL(holder.postagem, p.getPostagem());
//holder.postagem.setText(p.getPostagem());
//holder.likes.setText(Integer.toString(p.getLikes()));
}
return convertView;
}
public void setTextWithURL(TextView t, String s){
String [] parts = s.split("\\s");
String finals = "";
for( String item : parts ) try {
URL url = new URL(item);
// If possible then replace with anchor...
finals = finals + (""+ url + " " );
} catch (MalformedURLException e) {
// If there was an URL that was not it!...
finals = finals + item + " ";
System.out.print( item + " " );
}
t.setClickable(true);
t.setPaintFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
t.setMovementMethod(LinkMovementMethod.getInstance());
t.setText(Html.fromHtml(finals));
}
public void setPhoto(ImageView img, UrlImageViewHelper uHelper, AQuery aq, JSONObject json, int id){
String URL = "";
try {
URL = json.getJSONArray("images").getJSONObject(1).getString("source");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//uHelper.setUrlDrawable(img, URL);
// File file = aq.getCachedFile(URL);
// Bitmap bp = BitmapFactory.decodeFile(file.getPath());
// if (bp != null){
//
// img.setImageBitmap(bp);
//
// }else{
aq.id(img).image(URL, memCache, fileCache, 0, 0, null, 0, AQuery.RATIO_PRESERVE);
//
// }
}
public void getUrlPhoto(final ImageView img, final UrlImageViewHelper uHelper, String id, final AQuery aq, final int id_photo){
aq.ajax(BASE_URL + id, JSONObject.class, new AjaxCallback<JSONObject>() {
#Override
public void callback(String url, JSONObject json, AjaxStatus status) {
Log.d("url", url);
if(json != null){
setPhoto( img, uHelper, aq, json, id_photo);
}else{
Toast.makeText(aq.getContext(), "Error:" + status.getCode(), Toast.LENGTH_LONG).show();
}
}
});
}
}

ListView Shows Recent Image taken from camera

In my code when i take image from camera it shows correctly in imageview. But when i take second image, both listview items shows same picture..Old picture replaces with new one..when i take third picture then all of three items show same result.and so on..Please can anyone solve my problem.
public class CustomerRegistrationL0 extends Activity {
int take_image;
int UploadFile;
static SimpleAdapter Adapter;
static Bitmap thumbnail;
static String encodedImageString;
Bitmap image2;
LayoutInflater mInflater;
Uri selectedImage ;
static ListView listviewattachment;
public ArrayList<ListItem> myItems = new ArrayList<ListItem>();
private MyAdapter myAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cr_l0);
//declare fields
final EditText textcnic=(EditText)findViewById(R.id.EditTextCNIC);
final String cnic=textcnic.getText().toString();
final EditText textmobile=(EditText)findViewById(R.id.editTextMob);
final String mobileNo=textmobile.getText().toString();
final EditText textname=(EditText)findViewById(R.id.editTextName);
final String name=textname.getText().toString();
final EditText textaddress=(EditText)findViewById(R.id.EditTextAdd);
final String address=textaddress.getText().toString();
final EditText textkin=(EditText)findViewById(R.id.EditTextKin);
final String nextkin=textkin.getText().toString();
listviewattachment=(ListView)findViewById(R.id.listView1);
//////////////////////////////////////////////////////////
//make listview scrollable manuallly(shit)
listviewattachment.setOnTouchListener(new ListView.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent arg1) {
// TODO Auto-generated method stub
int action = arg1.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
// Disallow ScrollView to intercept touch events.
v.getParent().requestDisallowInterceptTouchEvent(true);
break;
case MotionEvent.ACTION_UP:
// Allow ScrollView to intercept touch events.
v.getParent().requestDisallowInterceptTouchEvent(false);
break;
}
// Handle ListView touch events.
v.onTouchEvent(arg1);
return true;
}
});
//////////////// // //////////////////////////////////////////////////////////////
Button buttonCamera=(Button)findViewById(R.id.buttonCamera);
Button buttonFromGallery=(Button)findViewById(R.id.buttonAttach);
Button formSubmit=(Button)findViewById(R.id.buttonSubmit);
buttonCamera.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View view) {
Intent i = new Intent( android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(i, take_image);
}
});
buttonFromGallery.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(
Intent.createChooser(intent, "Select a File to Upload"),
UploadFile);
}
});
formSubmit.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
validate(textcnic,textmobile,textname,textaddress,textkin);
//decoding bytes
String attachedImage=encodedImageString;
JSONObject jsonObj = new JSONObject();
try {
jsonObj.put("CNIC Number", cnic);
jsonObj.put("Mobile Number", mobileNo);
jsonObj.put("Name", name);
jsonObj.put("Address", address);
jsonObj.put("Next Kin", nextkin);
jsonObj.put("Image",attachedImage);
String jsonString=jsonObj.toString();
File sdcard = Environment.getExternalStorageDirectory();
try {
File myfile = new File(sdcard,"JSONCache.json");
myfile.createNewFile();
Writer myOutWriter = new BufferedWriter(new FileWriter(myfile));
myOutWriter.write(jsonString);
myOutWriter.close();
Toast.makeText(v.getContext(), "File Created", Toast.LENGTH_LONG).show();
} catch (Exception e) {
e.getStackTrace();
Toast.makeText(v.getContext(), "COuld not create file", Toast.LENGTH_LONG).show();
}
//end of write json object
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//write json object
}
});
}
private void validate(EditText cnic, EditText mobile,
EditText name, EditText address, EditText kin) {
// TODO Auto-generated method stub
if(name.getText().toString().trim().equals("")){
name.setError("Please Enter Name");
}
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == Activity.RESULT_OK )
{
if (requestCode==UploadFile){
// Uri selectedImage = data.getData();
// if ("content".equalsIgnoreCase(selectedImage.getScheme())) {
// String[] filePathColumn = { "_data" };
//Cursor cursor = getContentResolver().query(selectedImage,
// filePathColumn, null, null, null);
//cursor.moveToFirst();
//int columnIndex = cursor.getColumnIndex("_data");}
// String picturePath = cursor.getString(columnIndex);
// cursor.close();
// }
// else if ("file".equalsIgnoreCase(selectedImage.getScheme())) {
// String path= selectedImage.getPath();}
/* Uri selectedImage = data.getData();
String[] filePathColumn = { "data"};
Cursor cursor = getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
cursor.close();*/
}
if (requestCode == take_image) {
//get image
thumbnail = (Bitmap) data.getExtras().get("data");
BitmapFactory.Options factoryOptions = new BitmapFactory.Options();
factoryOptions.inJustDecodeBounds = true;
int imageWidth = factoryOptions.inDensity=50;
int imageHeight = factoryOptions.inDensity=50;
image2 = Bitmap.createScaledBitmap(thumbnail, imageWidth , imageHeight, true);
//////listview work
listviewattachment.setItemsCanFocus(true);
myAdapter = new MyAdapter();
ListItem listItem = new ListItem();
myItems.add(listItem);
listviewattachment.setAdapter(myAdapter);
myAdapter.notifyDataSetChanged();
////////////////////end of listview work
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
thumbnail.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
//encode image
byte[] b = bytes.toByteArray();
encodedImageString = Base64.encodeToString(b, Base64.DEFAULT);
}
}
}
public class MyAdapter extends BaseAdapter {
private LayoutInflater mInflater;
public MyAdapter() {
mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public int getCount() {
return myItems.size();
}
public ListItem getItem(int position) {
return myItems.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(final int position, View convertView,
ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.imageview2, null);
holder.image = (ImageView) convertView
.findViewById(R.id.imageView2);
holder.Delete=(Button)convertView.findViewById(R.id.buttonClose);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.image.setImageBitmap(image2);
holder.image.setTag(position);
holder.Delete.setTag(position);
holder.image.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
// TODO Auto-generated method stub
final Dialog imgDialog = new Dialog(view.getContext(),android.R.style.Theme_Translucent_NoTitleBar_Fullscreen);
imgDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
imgDialog.setCancelable(false);
// layout imageview2 is used because when i use simple imageview layout dialogue with imageview and closebutton,
// every taken image at instancewill not be shown in dialogue.
imgDialog.setContentView(R.layout.imageview);
Button btnClose = (Button)imgDialog.findViewById(R.id.btnIvClose);
ImageView ivPreview = (ImageView)imgDialog.findViewById(R.id.image1);
BitmapFactory.Options factoryOptions = new BitmapFactory.Options();
int imageWidth = factoryOptions.inDensity=400;
int imageHeight = factoryOptions.inDensity=500;
//thumbnail is selected coz if we select bm to enlarge it will give poor quality(bm is small sized image)
Bitmap Scaled = Bitmap.createScaledBitmap(CustomerRegistrationL0.thumbnail, imageWidth, imageHeight, true);
ivPreview.setImageBitmap(Scaled);
btnClose.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
imgDialog.dismiss();
}
});
imgDialog.show();
// ListItem listItem = new ListItem();
//myItems.add(listItem);
myAdapter.notifyDataSetChanged();
//listviewattachment.setSelection(myAdapter.getCount()+1 );
}
});
holder.Delete.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
// TODO Auto-generated method stub
int tag = (Integer) view.getTag();
if (tag != (myItems.size() )) {
myItems.remove(tag);
Log.d("GCM", "Item removed from " + tag);
myAdapter.notifyDataSetChanged();
}
}
});
return convertView;
}
}
class ViewHolder {
ImageView image;
Button Delete;
}
}
This is because in your getView() you do not consider the position. You always set the bitmap to image2 which is the most recent bitmap: holder.image.setImageBitmap(image2);
I think you misunderstood how get view works. The getView() method is called for each item in the list when you notifyDataSetChanged().
The solution is to keep reference to the different bitmaps in a list (or elsewhere.. i am just giving a possible solution),
List<Bitmap> images = new ArrayList<>();
When you get the image from the result, add it to the images list.
image2 = Bitmap.createScaledBitmap(thumbnail, imageWidth , imageHeight, true);
images.add(image2)
Finally, setImageBitmap based on the position of the item during getView()
holder.image.setImageBitmap(images.get(position));

Gif not animated in custom listview

I want to display animated GIF images in my custom listview.my GIF image is get in web service url.GIF image displayed but not animated.
public class NewsScreenAdapter extends BaseAdapter {
LayoutInflater inflater;
public GifDecoderView webview1;
public static viewholder holder;
View view = null;
public static Context context;
public ImageLoader IL;
public String imgUrl;
public static String addurl;
public Activity activity;
String image;
public static Date parsed;
public static String ac, cat_id;
public NewsScreenAdapter(Activity a) {
// TODO Auto-generated constructor stub
context = a.getApplicationContext();
this.activity = a;
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
IL = new ImageLoader(activity.getApplicationContext());
}
#Override
public int getCount() {
// TODO Auto-generated method stub
// return NewsScreenActivity.arrayList_header.size();
return NewsScreenActivity.TotalDataArray.size();
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public int getItemViewType(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public int getViewTypeCount() {
// TODO Auto-generated method stub
return NewsScreenActivity.TotalDataArray.size();
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View vi = convertView;
holder = new viewholder();
vi = inflater.inflate(R.layout.newsscren_row, null);
holder.news_header_title = (TextView) vi.findViewById(R.id.header_title);
holder.ll_data = (LinearLayout) vi.findViewById(R.id.data);
vi.setTag(holder);
holder.news_header_title.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
cat_id = NewsScreenActivity.arrayList_header.get(position);
ac = ((NewsScreenActivity.MainData) NewsScreenActivity.TotalDataArray.get(position)).catId;
activity.startActivity(new Intent(activity,CategoryActivity.class).putExtra("id", ac));
}
});
holder.ll_data.removeAllViews();
int storyLenght = ((NewsScreenActivity.MainData) NewsScreenActivity.TotalDataArray.get(position)).storyArr.size();
Log.d("Adapter ", " story Lenght " + storyLenght);
for (int i = 0; i < storyLenght; i++) {
view = LayoutInflater.from(activity).inflate(R.layout.sub_row, null);
holder.short_text = (TextView) view.findViewById(R.id.short_text);
holder.image = (ImageView) view.findViewById(R.id.image);
holder.des = (TextView) view.findViewById(R.id.des);
holder.date_time = (TextView) view.findViewById(R.id.date_time);
holder.llAdd = (LinearLayout) view.findViewById(R.id.llAdd);
holder.imgAdd = (ImageView) view.findViewById(R.id.imgAdd);
try {
holder.image.setTag(NewsScreenActivity.arrayList_image.get(i));
IL.DisplayImage(
((NewsScreenActivity.ImagesData) ((NewsScreenActivity.StoryData) ((NewsScreenActivity.MainData) NewsScreenActivity.TotalDataArray
.get(position)).storyArr.get(i)).imageArr.get(0)).smallurl, activity, holder.image);
notifyDataSetChanged();
} catch (Exception e) {
// TODO: handle exception
}
holder.short_text.setText(((NewsScreenActivity.StoryData) ((NewsScreenActivity.MainData) NewsScreenActivity.TotalDataArray
.get(position)).storyArr.get(i)).title);
holder.des.setText(((NewsScreenActivity.StoryData) ((NewsScreenActivity.MainData) NewsScreenActivity.TotalDataArray
.get(position)).storyArr.get(i)).description);
String st = ((NewsScreenActivity.StoryData) ((NewsScreenActivity.MainData) NewsScreenActivity.TotalDataArray
.get(position)).storyArr.get(i)).date;
parsed = new Date(Long.parseLong(st.substring(6, st.length() - 2)));
SimpleDateFormat sdf = new SimpleDateFormat("MMM dd,yyyy hh:mmaa");
System.out.println(sdf.format(parsed));
String concat = sdf.format(parsed);
String data = concat;
String half1 = data.substring(0, 11);
Log.e("1st date", "" + half1);
SimpleDateFormat display_date = new SimpleDateFormat("dd.MM.yyyy");
Date d_date = new Date();
String dis_date = display_date.format(parsed);
String half2 = data.substring(11, 19);
Log.e("2st time", "" + half2);
SimpleDateFormat currentdate = new SimpleDateFormat("MMM dd,yyyy");
Date currunt = new Date();
String day = currentdate.format(currunt);
if (half1.equalsIgnoreCase(day) == true) {
holder.date_time.setText(half2);
Log.v("if condition", "" + half2);
} else {
half1 = dis_date;
holder.date_time.setText(half1);
Log.v("else condition", "" + half1);
}
Log.e("currunt time", "" + day);
holder.news_header_title.setText(((NewsScreenActivity.MainData) NewsScreenActivity.TotalDataArray
.get(position)).catDisplay);
if (!((NewsScreenActivity.StoryData) ((NewsScreenActivity.MainData) NewsScreenActivity.TotalDataArray
.get(position)).storyArr.get(i)).advertising
.equalsIgnoreCase("null")) {
holder.short_text.setVisibility(view.GONE);
holder.date_time.setVisibility(view.GONE);
holder.des.setVisibility(view.GONE);
imgUrl = ((NewsScreenActivity.StoryData) ((NewsScreenActivity.MainData) NewsScreenActivity.TotalDataArray
.get(position)).storyArr.get(i)).adData.imageurl;
// TODO Auto-generated method stub
addurl = ((NewsScreenActivity.StoryData) ((NewsScreenActivity.MainData) NewsScreenActivity.TotalDataArray
.get(position)).storyArr.get(i)).adData.targeturl;
//-----------------GIF Image view ------------
holder.imgAdd.setImageBitmap(IL.getBitmap(imgUrl));
/* InputStream is = null;
try {
is = (InputStream) new URL(imgUrl).getContent();
webview1 = new GifDecoderView(context, is);
activity.setContentView(webview1);
} catch (Exception e) {
return null;
}*/
holder.imgAdd.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
activity.startActivity(new Intent(activity, AdvertismentActivity.class));
}
});
Log.i("---", "---------" + imgUrl);
holder.llAdd.setVisibility(View.VISIBLE);
}
holder.ll_data.addView(view);
Log.i("Set Tag", position+"OK"+i);
view.setTag(position+"OK"+i);
view.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
String tag = (String) v.getTag();
String[] arr = tag.split("OK");
int p = Integer.parseInt(arr[0]);
int i = Integer.parseInt(arr[1]);
Log.i("Pos and I", p + " " + i );
String str = ((NewsScreenActivity.StoryData) ((NewsScreenActivity.MainData) NewsScreenActivity.TotalDataArray .get(p)).storyArr.get(i)).storyid;
Log.i("Pos and I and STR", p + " " + i + " " + str);
Intent intent = new Intent(context,ShowFullDescriprion.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("id", str);
intent.putExtra("cat", p);
intent.putExtra("pos",i);
context.startActivity(intent);
}
});
}
return vi;
}
public static String getDate(long milliSeconds, String dateFormat) {
// Create a DateFormatter object for displaying date in specified
// format.
DateFormat formatter = new SimpleDateFormat(dateFormat);
// Create a calendar object that will convert the date and time value in
// milliseconds to date.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(milliSeconds);
return formatter.format(calendar.getTime());
}
public static class viewholder {
TextView news_header_title, short_text, des, date_time;
LinearLayout ll_data, llAdd;
public ImageView image, imgAdd;
}
}
You can use Android Movie class that is able to decode gifs.
Movie.decodeStream(InputStream is);
Use WebView rather then ImageView and loadUrl in WebView.
you have to use gif decorder class for that and set it in inflact view so you can set two view in single activity or screen.
Use the Glide image loading library, it has built-in support for GIFs and the syntax is the same loading a JPEG file:
Glide.with(this).load("http://.../anim.gif").into(imageView);
See the wiki for more and run the Gihpy sample to be amazed :)
//-----------------GIF Image view ------------
holder.imgAdd.getSettings().setJavaScriptEnabled(true);
holder.imgAdd.setWebChromeClient(new WebChromeClient() {
public void onProgressChanged(WebView view, int progress)
{
activity.setTitle("Loading...");
activity.setProgress(progress * 100);
if(progress == 100)
activity.setTitle(R.string.app_name);
}
});
holder.imgAdd.setWebViewClient(new WebViewClient() {
#Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl)
{
// Handle the error
}
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url)
{
view.loadUrl(url);
return true;
}
});
holder.imgAdd.loadUrl(imgUrl);

multiple attachments but only selected ones

I have my main view with images and checkboxes associated with them and a send email button. When I click on the checkboxes and select send email button I should be redirected to the email page where the selected images must be attached. Here is my code.
please help me out
public class GridcheckboxActivity extends Activity {
GridView mygrid;
String[] imagepaths;
Uri[] myUris;
boolean[] ticking;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mygrid=(GridView)findViewById(R.id.gridView1);
String folderpath=Environment.getExternalStorageDirectory().getAbsolutePath()+"/New Folder/";
File myfile=new File(folderpath);
File[] imageslist=myfile.listFiles(new FilenameFilter() {
#Override
public boolean accept(File dir, String filename) {
// TODO Auto-generated method stub
return (filename.toLowerCase().endsWith("jpg")||filename.toLowerCase().endsWith("png")||filename.toLowerCase().endsWith("jpeg"));
}
});
int imgCount=imageslist.length;
imagepaths=new String[imgCount];
for(int i=0;i<imgCount;i++){
imagepaths[i]=imageslist[i].getAbsolutePath();
System.out.println("my image's paths are::::::::"+imagepaths[i]);
}
this.ticking=new boolean[imgCount];
ImageAdapter imgad=new ImageAdapter();
mygrid.setAdapter(imgad);
Button select=(Button)findViewById(R.id.button1);
select.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
final int len = ticking.length;
int cnt = 0;
String selectImages = "";
ArrayList<String> myarray=new ArrayList<String>();
for (int i =0; i<len; i++)
{
if (ticking[i]){
cnt++;
selectImages = selectImages + imagepaths[i] + "|";
myarray.add(imagepaths[i]);
}
}
Log.d("myarray","myarray size==="+myarray.size());
if (cnt == 0){
Toast.makeText(getApplicationContext(),"Please select at least one image",Toast.LENGTH_LONG).show();
}
else {
Toast.makeText(getApplicationContext(), "You've selected Total " + cnt + " image(s).",Toast.LENGTH_LONG).show();
Log.d("SelectedImages", selectImages);
try{
Intent emailintent=new Intent(android.content.Intent.ACTION_SEND_MULTIPLE);
emailintent.setType("application/octet-stream");
String[] addressvalue=new String[]{"user#domain.example"};
emailintent.putExtra(android.content.Intent.EXTRA_EMAIL, addressvalue);
emailintent.putExtra(android.content.Intent.EXTRA_SUBJECT, "subjectvalue");
String bccvalue[]={"bcc address"};
emailintent.putExtra(android.content.Intent.EXTRA_BCC, bccvalue);
String ccvalue[]={"cc address"};
emailintent.putExtra(android.content.Intent.EXTRA_CC,ccvalue );
ArrayList<Uri> newone=new ArrayList<Uri>();
for(int j=0;j<myarray.size();j++){
Uri u=Uri.parse("file:/"+myarray.get(j));
Log.d("uris", "myuris are:::::::"+u);
newone.add(u);
}
System.out.println("my uri array has values------->"+newone);
emailintent.putExtra(android.content.Intent.EXTRA_STREAM, newone);
GridcheckboxActivity.this.startActivity( Intent.createChooser(emailintent, "sending email using:"));
}catch(Exception e){
e.printStackTrace();
Log.d("error", "cannot start activity");
}
}
}
});
}
Check with your xml & this attribute to the list android:choiceMode="multipleChoice" and see.
I tried a lot and found out the answer for my problem as
public class GridcheckboxActivity extends Activity {
GridView mygrid;
String[] imagepaths;
Uri[] myUris;
boolean[] ticking;
ArrayList<String> myarray=new ArrayList<String>();
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mygrid=(GridView)findViewById(R.id.gridView1);
String folderpath=Environment.getExternalStorageDirectory().getAbsolutePath()+"/New Folder/";
File myfile=new File(folderpath);
File[] imageslist=myfile.listFiles(new FilenameFilter() {
#Override
public boolean accept(File dir, String filename) {
// TODO Auto-generated method stub
return (filename.toLowerCase().endsWith("jpg")||filename.toLowerCase().endsWith("png")||filename.toLowerCase().endsWith("jpeg"));
}
});
int imgCount=imageslist.length;
imagepaths=new String[imgCount];
for(int i=0;i<imgCount;i++){
imagepaths[i]=imageslist[i].getAbsolutePath();
System.out.println("my image's paths are::::::::"+imagepaths[i]);
}
this.ticking=new boolean[imgCount];
ImageAdapter imgad=new ImageAdapter();
mygrid.setAdapter(imgad);
Button select=(Button)findViewById(R.id.button1);
select.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
final int len = ticking.length;
int cnt = 0;
String selectImages = "";
for (int i =0; i<len; i++)
{
if (ticking[i]){
cnt++;
selectImages = selectImages + imagepaths[i] + "|";
myarray.add(imagepaths[i]);
}
}
Log.d("myarray","myarray size==="+myarray.size());
if (cnt == 0){
Toast.makeText(getApplicationContext(),"Please select at least one image",Toast.LENGTH_LONG).show();
}
else {
Toast.makeText(getApplicationContext(), "You've selected Total " + cnt + " image(s).",Toast.LENGTH_LONG).show();
Log.d("SelectedImages", selectImages);
try{
Intent emailintent=new Intent(android.content.Intent.ACTION_SEND_MULTIPLE);
emailintent.setType("application/octet-stream");
String[] addressvalue=new String[]{"user#domain.example"};
emailintent.putExtra(android.content.Intent.EXTRA_EMAIL, addressvalue);
emailintent.putExtra(android.content.Intent.EXTRA_SUBJECT, "subjectvalue");
String bccvalue[]={"bcc address"};
emailintent.putExtra(android.content.Intent.EXTRA_BCC, bccvalue);
String ccvalue[]={"cc address"};
emailintent.putExtra(android.content.Intent.EXTRA_CC,ccvalue );
ArrayList<Uri> axn=getUriListForImages();
emailintent.putExtra(android.content.Intent.EXTRA_STREAM, axn);
GridcheckboxActivity.this.startActivity( Intent.createChooser(emailintent, "sending email using:"));
}
catch(Exception e){
e.printStackTrace();
Log.d("error", "cannot start activity");
}
}
}
});
}
private ArrayList<Uri> getUriListForImages() throws Exception {
ArrayList<Uri> myList = new ArrayList<Uri>();
String imageDirectoryPath = Environment.getExternalStorageDirectory().getAbsolutePath()+ "/New Folder/";
if(myarray.size() != 0) {
for(int i=0; i<myarray.size(); i++)
{
try
{
ContentValues values = new ContentValues(7);
values.put(Images.Media.TITLE, myarray.get(i));
values.put(Images.Media.DISPLAY_NAME, myarray.get(i));
values.put(Images.Media.DATE_TAKEN, new Date().getTime());
values.put(Images.Media.MIME_TYPE, "image/jpeg");
values.put(Images.ImageColumns.BUCKET_ID, imageDirectoryPath.hashCode());
values.put(Images.ImageColumns.BUCKET_DISPLAY_NAME, myarray.get(i));
values.put("_data", myarray.get(i));
ContentResolver contentResolver = getApplicationContext().getContentResolver();
Uri uri = contentResolver.insert(Images.Media.EXTERNAL_CONTENT_URI, values);
myList.add(uri);
} catch (Exception e) {
e.printStackTrace();
}
}
}
return myList;
}
public class ImageAdapter extends BaseAdapter{
private LayoutInflater mInflater;
//Context mycontext;
public ImageAdapter() {
// TODO Auto-generated constructor stub
mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return imagepaths.length;
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return imagepaths[position];
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public View getView(int position, View conview, ViewGroup arg2) {
// TODO Auto-generated method stub
viewholder myholder;
if(conview== null){
myholder=new viewholder();
conview=mInflater.inflate(R.layout.inflatexml,null);
myholder.img=(ImageView) conview.findViewById(R.id.imageView1);
myholder.cbox=(CheckBox) conview.findViewById(R.id.checkBox1);
conview.setTag(myholder);
}else{
myholder=(viewholder) conview.getTag();
}
myholder.img.setId(position);
myholder.cbox.setId(position);
myholder.cbox.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
CheckBox cb=(CheckBox)v;
int id=cb.getId();
if(ticking[id]){
cb.setChecked(false);
ticking[id]=false;
}else{
cb.setChecked(true);
ticking[id]=true;
}
}
});
myholder.img.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
int id=v.getId();
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse("file:/"+imagepaths[id]), "image/*");
startActivity(intent);
}
});
Bitmap bm=BitmapFactory.decodeFile(""+imagepaths[position]);
Bitmap bm1=Bitmap.createScaledBitmap(bm, 140, 200, true);
myholder.img.setImageBitmap(bm1);
myholder.cbox.setChecked(ticking[position]);
myholder.cbox.setGravity(Gravity.TOP);
myholder.id=position;
return conview;
}
}
class viewholder{
ImageView img;
CheckBox cbox;
int id;
}
}

Categories

Resources