Listview items duplicated on clicking notification - android

I am getting listView items duplicated if I play a song in the background and go back to the app on clicking the notification icon. While opening the app for the first time, items are not duplicated. What could be wrong? Posting below my adapter class.
Adapter:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
ViewHolder holder = null;
final int pos = position;
if (view == null) {
LayoutInflater inflater = (LayoutInflater) parent.getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = (RelativeLayout) inflater.inflate(R.layout.song, parent,
false);
holder = new ViewHolder();
holder.tvTitle = (TextView) view.findViewById(R.id.tv_song_title);
holder.tvArtist = (TextView) view.findViewById(R.id.tv_song_artist);
holder.imgAlbumArt = (ImageView) view
.findViewById(R.id.img_lv_album_art);
holder.tvArtist.setText(songs.get(position).getArtist());
holder.tvTitle.setText(songs.get(position).getTitle());
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
int id = (int) songs.get(position).getId();
if (bitmaps == null) {
Bitmap bm = MainActivity.getCachedArtwork(mContext,
id, MainActivity.getDefaultArtwork(mContext));
holder.imgAlbumArt.setImageBitmap(bm);
bitmaps.put(id, bm);
Log.d("inside null", "key=" + id + "bm=" + bm + "pos" + position);
} else if (bitmaps.containsKey(id)) {
Bitmap bm = bitmaps.get(id);
holder.imgAlbumArt.setImageBitmap(bm);
bitmaps.put(id, bm);
Log.d("inside contains key", "key=" + id + "bm=" + bm + "pos"
+ position);
} else {
Bitmap bm = MainActivity.getCachedArtwork(mContext,
id, MainActivity.getDefaultArtwork(mContext));
holder.imgAlbumArt.setImageBitmap(bm);
bitmaps.put(id, bm);
Log.d("inside else", "key=" + id + "bm=" + bm + "pos" + position);
}
return view;
}
MainActivity:
public static Bitmap getCachedArtwork(Context context, int artIndex,
Bitmap defaultArtwork) {
Bitmap d = null;
synchronized (sArtCache) {
d = sArtCache.get(artIndex);
}
if (d == null) {
d = defaultArtwork;
final Bitmap icon = defaultArtwork;
int w = icon.getWidth();
int h = icon.getHeight();
Bitmap b = getArtworkQuick(context, artIndex, w, h);
if (b != null) {
d = b;// new FastBitmapDrawable(b);
synchronized (sArtCache) {
// the cache may have changed since we checked
Bitmap value = sArtCache.get(artIndex);
if (value == null) {
sArtCache.put(artIndex, d);
} else {
d = value;
}
}
}
}
return d;
}
// Get album art for specified album. This method will not try to
// fall back to getting artwork directly from the file, nor will
// it attempt to repair the database.
private static Bitmap getArtworkQuick(Context context, int album_id, int w, int h) {
// NOTE: There is in fact a 1 pixel frame in the ImageView used to
// display this drawable. Take it into account now, so we don't have to
// scale later.
w -= 2;
h -= 2;
ContentResolver res = context.getContentResolver();
Uri uri = ContentUris.withAppendedId(sArtworkUri, album_id);
if (uri != null) {
ParcelFileDescriptor fd = null;
try {
fd = res.openFileDescriptor(uri, "r");
int sampleSize = 1;
// Compute the closest power-of-two scale factor
// and pass that to sBitmapOptionsCache.inSampleSize, which will
// result in faster decoding and better quality
sBitmapOptionsCache.inJustDecodeBounds = true;
BitmapFactory.decodeFileDescriptor(
fd.getFileDescriptor(), null, sBitmapOptionsCache);
int nextWidth = sBitmapOptionsCache.outWidth >> 1;
int nextHeight = sBitmapOptionsCache.outHeight >> 1;
while (nextWidth>w && nextHeight>h) {
sampleSize <<= 1;
nextWidth >>= 1;
nextHeight >>= 1;
}
sBitmapOptionsCache.inSampleSize = sampleSize;
sBitmapOptionsCache.inJustDecodeBounds = false;
Bitmap b = BitmapFactory.decodeFileDescriptor(
fd.getFileDescriptor(), null, sBitmapOptionsCache);
if (b != null) {
// finally rescale to exactly the size we need
if (sBitmapOptionsCache.outWidth != w || sBitmapOptionsCache.outHeight != h) {
Bitmap tmp = Bitmap.createScaledBitmap(b, w, h, true);
b.recycle();
b = tmp;
}
}
return b;
} catch (FileNotFoundException e) {
} finally {
try {
if (fd != null)
fd.close();
} catch (IOException e) {
}
}
}
return null;
}

Related

How to store and Retrieve images from the local device in android programmatically ?

My task is to take pictures and uploading it in cloud storage, In upload screen I have two buttons one is "Upload" and other is "Park",
i) if I select "Upload" it should upload the images on cloud.
ii) if I select "Park" it should save the entire data into a activity with a button Load1.
What is Park ?
park should have the entire user data's stored previously
On clicking this load button I need to show the previously stored images in the thumbnail, eg. If I am taking 10 images I am showing those 10 images in the thumbnail as shown in below screenshot, while i m selecting the load it is showing 10th image for the three default images it is not showing all the 10 images which i have taken. How can I make it work properly?
This is my CameraActivity code where I am saving the images:
private void saveAndShowImage(byte[] data) {
bmp1 = BitmapFactory.decodeByteArray(data, 0, data.length);
//rotate the image by 90degree.
bmp1 = RotateBitmap(bmp1, 90);
bmp1 = Singleton.getResizedBitmap(bmp1);
imageName = "img" + currentDateTimeString + ".png";
saveImage(this, imageName, bmp1);
LogEvent.Log(TAG,"bmp1"+bmp1);
boolean isObjectReplaced = false;
int size = 3;
if(bitmapArray.size() < 3) {
size = bitmapArray.size();
}
for (int i = 0; i < size; i++) {
if (bitmapArray.get(i).imageName == null) {
bitmapArray.set(i, new ImageNote("", currentDateTimeString, imageName));
isObjectReplaced = true;
break;
}
}
if (!isObjectReplaced) {
bitmapArray.add(new ImageNote("", currentDateTimeString, imageName));
}
Log.d(currentDateTimeString, "ss");
Log.i("imagesize", "ImageWidth = " + bmp1.getWidth() + "ImageHeight = " + bmp1.getHeight());
CameraActivity.this.runOnUiThread(new Runnable() {
public void run() {
if (imageCount > 2) {
gv.scrollTo(convertDpToPixel(590 * bitmapArray.size()) + 10);
}
adapter.notifyDataSetChanged();
}
});
}
//it is saving the image and show in the gridview .
private class ImageSaveAndShow extends AsyncTask<String, String, Boolean> {
private byte[] data;
public ImageSaveAndShow(byte[] data, Camera camera) {
this.data = data;
}
#Override
protected Boolean doInBackground(String... strings) {
saveAndShowImage(data);
return true;
}
}
public static void saveImage(Context context, String filename,
Bitmap bitmap) {
File cacheDir = context.getExternalFilesDir(null);
File backgroundImagesDir = new File(cacheDir.getAbsolutePath() + "/"
+ "LoadProof");
if (!backgroundImagesDir.isDirectory()) {
backgroundImagesDir.mkdir();
Log.i(TAG, "LoadProof Directory Created");
}
OutputStream out = null;
File file = null;
try {
file = new File(backgroundImagesDir.getAbsolutePath() + "/" + filename);
Log.i(TAG, "saved to " + file.toString());
// Storing the path to show the previously stored image
if(loadClickCount==1) {
SharedPreferences prefernces = context.getSharedPreferences("parkload", Context.MODE_APPEND);
SharedPreferences.Editor editor = prefernces.edit();
editor.putString("Path", String.valueOf(file));
editor.commit();
String old = prefernces.getString("Path",null);
LogEvent.Log(TAG,"llll" + " " + old + " " + path);
}
out = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
file = null;
Log.i(TAG, "File Written");
bitmap = null;
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
AdaperCode
public class Adapter extends ArrayAdapter<ImageNote> {
private final ArrayList<ImageNote> objects;
private Context context;
String TAG = "Adapter";
public Adapter(Context context, ArrayList<ImageNote> objects) {
super(context, 0, objects);
this.objects = objects;
this.context = context;
}
#Override public View getView(final int pos, View convertView, ViewGroup parent) {
ViewHolder holder = null;
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = inflater.inflate(R.layout.cell_image, null);
holder = new ViewHolder();
holder.ivCampic = (ImageView) convertView.findViewById(R.id.ivCampic);
holder.ivDeletion = (ImageView) convertView.findViewById(R.id.ivDeletion);
holder.tvPos = (TextView) convertView.findViewById(R.id.txt_number_camera);
convertView.setTag(holder);
} else {
convertView = inflater.inflate(R.layout.cell_image, null);
holder = new ViewHolder();
holder.ivCampic = (ImageView) convertView.findViewById(R.id.ivCampic);
holder.ivDeletion = (ImageView) convertView.findViewById(R.id.ivDeletion);
holder.tvPos = (TextView) convertView.findViewById(R.id.txt_number_camera);
}
if (objects.get(pos).imageName == null && pos < 3 && park1==false) {
holder.ivCampic.setImageResource(R.drawable.placeholder);
holder.ivDeletion.setVisibility(View.INVISIBLE);
holder.tvPos.setVisibility(View.INVISIBLE);
} else if (park1 == true) {
// Assigning previously stored path
SharedPreferences prefernces = context.getSharedPreferences("parkload", Context.MODE_APPEND);
String load1Path = prefernces.getString("Path", null);
LogEvent.Log(TAG,"lllll"+ " " + load1Path);
String path = load1Path;
Bitmap bmp = BitmapFactory.decodeFile(path);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (bmp != null) {
bmp.compress(Bitmap.CompressFormat.JPEG, 100, baos);
}
holder.ivCampic.setImageBitmap(bmp);
holder.ivDeletion.setVisibility(View.VISIBLE);
holder.tvPos.setVisibility(View.VISIBLE);
} else {
// Assigning path of the pictures from camera directly
String path = context.getExternalFilesDir(null).getAbsolutePath() + "/LoadProof/"
+ objects.get(pos).imageName;
Bitmap bmp = BitmapFactory.decodeFile(path);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (bmp != null) {
bmp.compress(Bitmap.CompressFormat.JPEG, 100, baos);
}
holder.ivCampic.setImageBitmap(bmp);
holder.ivDeletion.setVisibility(View.VISIBLE);
holder.tvPos.setVisibility(View.VISIBLE);
}
LogEvent.Log(TAG,"text1 /"+String.valueOf(pos + 1)+"pos "+pos);
holder.tvPos.setText(String.valueOf(pos+1));
final ViewHolder finalHolder = holder;
holder.ivDeletion.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
objects.remove(pos);
CameraActivity.imageCount--;
if (bitmapArray.size() < 3) {
bitmapArray.add(new ImageNote("", null, null));
finalHolder.ivCampic.setImageResource(R.drawable.placeholder);
finalHolder.ivDeletion.setVisibility(View.INVISIBLE);
if (pos == bitmapArray.size() - 1) {
//it is the last image which has been deleted when size()<=3.
finalHolder.ivCampic.setImageResource(R.drawable.placeholder);
finalHolder.ivDeletion.setVisibility(View.INVISIBLE);
finalHolder.tvPos.setVisibility(View.INVISIBLE);
} else {
//it is not the last image which has been deleted when size()<=3.
finalHolder.ivCampic.setImageResource(R.drawable.placeholder);
finalHolder.ivDeletion.setVisibility(View.INVISIBLE);
}
} else {
// when bitmapArray.size()>3
view.setVisibility(View.GONE);
}
notifyDataSetChanged();
}
});
return convertView;
}
private class ViewHolder {
public ImageView ivCampic;
public ImageView ivDeletion;
public TextView tvPos;
}
}
Since you are overwriting the path in the shared preference, only the latest path can be retrieved. It will be better if you could store it as an array in a file. so you can retrieve the path using the array index and no overwriting will happen.

fetch all photos from gallery and show it in grid view

i want to fetch all photos from gallery and display it in grid view ..all photos i get but the problem is it will not working smoothly like as gallery too mach mobile hang please give me solution if any one have my code is below.
public class getImageFromGallery extends AsyncTask<String,Void,ArrayList<String>> {
#Override
protected ArrayList<String> doInBackground(String... strings) {
Uri u = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
String[] projection = {MediaStore.Images.ImageColumns.DATA};
Cursor c = null;
SortedSet<String> dirList = new TreeSet<String>();
final ArrayList<String> resultIAV = new ArrayList<String>();
String[] directories = null;
if (u != null)
{
String sortOrder ="_id asc limit 1";
c = managedQuery(u, projection, null, null, null);
}
if ((c != null) && (c.moveToFirst()))
{
do
{
String tempDir = c.getString(0);
tempDir = tempDir.substring(0, tempDir.lastIndexOf("/"));
try{
dirList.add(tempDir);
}
catch(Exception e)
{
}
}
while (c.moveToNext());
directories = new String[dirList.size()];
dirList.toArray(directories);
}
for(int i=0;i<dirList.size();i++)
{
File imageDir = new File(directories[i]);
File[] imageList = imageDir.listFiles();
if(imageList == null)
continue;
for (File imagePath : imageList) {
try {
if(imagePath.isDirectory())
{
imageList = imagePath.listFiles();
}
if ( imagePath.getName().contains(".jpg")|| imagePath.getName().contains(".JPG")
|| imagePath.getName().contains(".jpeg")|| imagePath.getName().contains(".JPEG")
|| imagePath.getName().contains(".png") || imagePath.getName().contains(".PNG")
|| imagePath.getName().contains(".gif") || imagePath.getName().contains(".GIF")
|| imagePath.getName().contains(".bmp") || imagePath.getName().contains(".BMP")
)
{
String path= imagePath.getAbsolutePath();
resultIAV.add(path);
}
}
// }
catch (Exception e) {
e.printStackTrace();
}
}
}
ShareMoment.this.runOnUiThread(new Runnable() {
#Override
public void run() {
shareMomentAdapter = new ShareMomentAdapter(ShareMoment.this,resultIAV);
sharemomentList.setAdapter(shareMomentAdapter);
}
});
return resultIAV;
}
}
public class ShareMomentAdapter extends RecyclerView.Adapter<ShareMomentAdapter.ShareMomentViewHolder> {
private Context context;
private ArrayList<String> shareMomentList;
ByteArrayOutputStream bytearrayoutputstream;
public ShareMomentAdapter(Context context, ArrayList<String> shareMomentList) {
this.shareMomentList = shareMomentList;
// shareMomentList = new ArrayList<>();
// for (int i = 0; i < 10; i++) {
// shareMomentList.add("" + i);
// }
this.context = context;
bytearrayoutputstream = new ByteArrayOutputStream();
}
#Override
public ShareMomentAdapter.ShareMomentViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_sharemoments, parent, false);
return new ShareMomentViewHolder(itemView);
}
#Override
public void onBindViewHolder(final ShareMomentAdapter.ShareMomentViewHolder holder, int position) {
Bitmap yourSelectedImage = BitmapFactory.decodeFile(shareMomentList.get(position));
final Bitmap resizedImage = Bitmap.createScaledBitmap(yourSelectedImage, 150, 150, true);
Glide.with(context).load(shareMomentList.get(position)).diskCacheStrategy(DiskCacheStrategy.RESULT).crossFade().into(holder.shareMomentImage);
}
#Override
public int getItemCount() {
return shareMomentList.size();
}
public class ShareMomentViewHolder extends RecyclerView.ViewHolder {
#Bind(R.id.shareMomentImage)
ImageView shareMomentImage;
// #Bind(R.id.nameTextview)
// TextView nameTextview;
// #Bind(R.id.descriptionTextView)
// TextView descriptionTextView;
private View view;
public ShareMomentViewHolder(View view) {
super(view);
this.view = view;
ButterKnife.bind(this, view);
}
}
public Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth) {
int width = bm.getWidth();
int height = bm.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height,
matrix, false);
return resizedBitmap;
}
}
Try using LoadMoreView instead of loading all images at once. Load 10-20 images at a time, and then load more when user scrolls down. This will save a lot of memory.

Custom adapter refresh in gridview android

i have a grid view with 6 cells loading in adapter. when i click each cell,i am going to add image either from taking photos or choosing images from gallery.after selecting images, the grid view is showing empty only. though i set image in one cell,when go for another cell,the previous selection is gone. how to make it done?.. plea help me. if i am anything wrong , please guide me.
if (convertView == null) {
grid = new View(mContext);
grid = inflater.inflate(R.layout.fpc_document_view, null);
TextView textView = (TextView) grid.findViewById(R.id.grid_text);
imageView = (ImageView) grid.findViewById(R.id.grid_image);
if (fileList.size() == 0) {
textView.setText(DOCUMENT_NAME_LIST[position].toString());
for (int i = 0; i <= 6; i++) {
imageView.setImageResource(R.mipmap.ic_add_document);
}
} else {
Bitmap bitmapResized = null;
for (int i = 0; i < fileList.size(); i++) {
if (!fileList.get(i).equals("")) {
System.out.println("fileList here ,,,," + fileList.get(i).toString());
Drawable drawable = mContext.getResources().getDrawable(R.mipmap.ic_add_document);
bitmapResized = ((BitmapDrawable) drawable).getBitmap();
} else {
Uri selectedImageUri = Uri.fromFile(fileList.get(i));
bitmapResized = ImageRelatedStuff.convertURIToBitmap(selectedImageUri, mContext);
if (bitmapResized != null) {
Bitmap bitmapTemp = bitmapResized;
bitmapResized = null;
bitmapResized = ImageRelatedStuff.getResizedBitmap(bitmapTemp, 500, 500, 0);
}
}
imageView.setImageBitmap(ImageRelatedStuff.getRoundedCornerBitmap(bitmapResized, 15));
}
}
} else {
grid = convertView;
imageView = (ImageView) grid.findViewById(R.id.grid_image);
}
Change your code like this:
if (convertView == null) {
grid = new View(mContext);
grid = inflater.inflate(R.layout.fpc_document_view, null);
TextView textView = (TextView) grid.findViewById(R.id.grid_text);
imageView = (ImageView) grid.findViewById(R.id.grid_image);
} else {
grid = convertView;
imageView = (ImageView) grid.findViewById(R.id.grid_image);
}
if (fileList.size() == 0) {
textView.setText(DOCUMENT_NAME_LIST[position].toString());
for (int i = 0; i <= 6; i++) {
imageView.setImageResource(R.mipmap.ic_add_document);
}
} else {
Bitmap bitmapResized = null;
for (int i = 0; i < fileList.size(); i++) {
if (!fileList.get(i).equals("")) {
System.out.println("fileList here ,,,," + fileList.get(i).toString());
Drawable drawable = mContext.getResources().getDrawable(R.mipmap.ic_add_document);
bitmapResized = ((BitmapDrawable) drawable).getBitmap();
} else {
Uri selectedImageUri = Uri.fromFile(fileList.get(i));
bitmapResized = ImageRelatedStuff.convertURIToBitmap(selectedImageUri, mContext);
if (bitmapResized != null) {
Bitmap bitmapTemp = bitmapResized;
bitmapResized = null;
bitmapResized = ImageRelatedStuff.getResizedBitmap(bitmapTemp, 500, 500, 0);
}
}
imageView.setImageBitmap(ImageRelatedStuff.getRoundedCornerBitmap(bitmapResized, 15));
}
}
Problem is when your convertView is not equals null you are not setting anything image on imageView. That is why on 2nd cell where convertView is null you are getting image while on previous cell which is not null you are getting nothing.
public class MyAdapter extends BaseAdapter{
private final int GRID_COUNT = 6;
// you need an array save bitmap with position
Bitmap[] bitmapArray;
public MyAdapter(){
bitmapArray = new Bitmap[GRID_COUNT];
}
#Override
public int getCount() {
return 6;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null){
// inflater your layout
}
ImageView imageView = (ImageView) convertView.findViewById(R.id.grid_image);
// get the bitmap in array by position
Bitmap bitmap = bitmapArray[position];
// when bitmap is null ,show default picture
if (bitmap == null){
imageView.setBackgroundResource(R.drawable.ic_default);
}else{
imageView.setImageBitmap(bitmap);
}
return convertView;
}
// activity or fragment use this method call adapter refresh
public void setBitmap(int position, Bitmap bitmap){
bitmapArray[position] = bitmap;
notifyDataSetChanged();
}
}
update my answer, hope help you

Using Picasso to solve OutOfMemoryError

I have seen many answers on this issue which has not worked so far for me, the best option I got was using a Picasso to solve this, I have imported the .jar but am getting an error on the code I was told to use, I get an error on this(context) in the following line of code, say (context) cannot be resolved to a variable
Picasso.with(context).load(myBitmap).into(imageView);
This is the lines of code that generates the error, which I intend solving using Picasso
File imgFile = new File(data.get(position).get("path"));
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
imageView.setImageBitmap(myBitmap);
This is my full code below
public class WidgetActivity extends Activity {
GridView grid;
Matrix matrix = new Matrix();
Bitmap rotateimage;
ArrayList<HashMap<String, String>> maplist = new ArrayList<HashMap<String,String>>();
LocalStorageHandler notedb;
ImageView iv_notes;
EditText content;
LinearLayout grid_layout;
AppWidgetManager appWidgetManager;
int n;
Intent i;
int s;
String[] tcolor;
public String path = "", name = "", color = "";
public void onCreate(Bundle os) {
super.onCreate(os);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.dialog_shownotes);
notedb = new LocalStorageHandler(WidgetActivity.this);
grid = (GridView) findViewById(R.id.grid);
iv_notes = (ImageView) findViewById(R.id.iv_note);
content = (EditText) findViewById(R.id.content);
grid_layout = (LinearLayout) findViewById(R.id.grid_layout);
i = getIntent();
n = i.getIntExtra("currentWidgetId", 1);
new getlist().execute();
}
class getlist extends AsyncTask<String, String, String> {
ArrayList<HashMap<String, String>> maplist = new ArrayList<HashMap<String, String>>();
#Override
public void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... arg) {
ArrayList<String> filepaths = new ArrayList<String>();
ArrayList<String> filenames = new ArrayList<String>();
Cursor dbCursor = notedb.get();
if (dbCursor.getCount() > 0) {
int noOfScorer = 0;
dbCursor.moveToFirst();
while ((!dbCursor.isAfterLast())
&& noOfScorer < dbCursor.getCount()) {
noOfScorer++;
try {
HashMap<String, String> items = new HashMap<String, String>();
filepaths.add(Environment.getExternalStorageDirectory()
+ "/360notes/" + dbCursor.getString(2));
filenames.add(dbCursor.getString(3));
items.put("path",
Environment.getExternalStorageDirectory()
+ "/360notes/" + dbCursor.getString(2));
items.put("name", dbCursor.getString(3));
items.put("time", dbCursor.getString(1));
items.put("id", dbCursor.getString(0));
items.put("color", dbCursor.getString(4));
maplist.add(items);
} catch (Exception e) {
e.printStackTrace();
}
dbCursor.moveToNext();
}
}
return null;
}
#Override
protected void onPostExecute(String unused) {
if (maplist.size() > 0) {
grid.setAdapter(new GridViewImageAdapter(WidgetActivity.this,
maplist));
}
}
}
public class GridViewImageAdapter extends BaseAdapter {
private Activity _activity;
ArrayList<String> _filenames = new ArrayList<String>();
private ArrayList<HashMap<String, String>> data = new ArrayList<HashMap<String, String>>();
public GridViewImageAdapter(Activity activity,
ArrayList<HashMap<String, String>> items) {
this._activity = activity;
data = items;
}
#Override
public int getCount() {
return data.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView,
ViewGroup parent) {
LayoutInflater inflate = (LayoutInflater) _activity
.getSystemService(_activity.LAYOUT_INFLATER_SERVICE);
convertView = inflate.inflate(R.layout.show_image, null);
ImageView imageView = (ImageView) convertView
.findViewById(R.id.imgScreen);
TextView title = (TextView) convertView.findViewById(R.id.title);
try {
String[] tcolor = data.get(position).get("name").split(" / ");
title.setText(tcolor[0].trim());
title.setTextColor(Color.parseColor(tcolor[1].trim()));
if (tcolor[2].trim().equals("0")) {
String text = title.getText().toString();
SpannableString span = new SpannableString(text);
span.setSpan(new UnderlineSpan(), 0, span.length(), 0);
// title.setText(span);
} else if (tcolor[2].trim().equals("3")) {
// title.setTypeface(null, Typeface.BOLD);
String text = title.getText().toString();
SpannableString span = new SpannableString(text);
span.setSpan(new UnderlineSpan(), 0, span.length(), 0);
// title.setText(span);
} else if (tcolor[2].trim().equals("4")) {
// title.setTypeface(null, Typeface.ITALIC);
String text = title.getText().toString();
SpannableString span = new SpannableString(text);
span.setSpan(new UnderlineSpan(), 0, span.length(), 0);
// title.setText(span);
} else if (tcolor[2].trim().equals("1")) {
// title.setTypeface(null, Typeface.BOLD);
String text = title.getText().toString();
SpannableString span = new SpannableString(text);
span.removeSpan(text);
} else if (tcolor[2].trim().equals("2")) {
// title.setTypeface(null, Typeface.ITALIC);
String text = title.getText().toString();
SpannableString span = new SpannableString(text);
span.removeSpan(text);
} else {
String text = title.getText().toString();
SpannableString span = new SpannableString(text);
span.removeSpan(text);
}
} catch (IndexOutOfBoundsException e) {
// TODO: handle exception
}
// TODO: handle exception
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4;
File imgFile = new File(data.get(position).get("path"));
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
imageView.setImageBitmap(myBitmap);
/*if (myBitmap != null && !myBitmap.isRecycled()) {
myBitmap.recycle();
myBitmap = null;
}*/
//myBitmap.recycle();
//myBitmap = null;
Picasso.with(context).load(myBitmap).into(imageView);
grid.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
grid.setVisibility(View.GONE);
// grid_layout.setVisibility(View.VISIBLE);
s = position;
path = data.get(position).get("path");
try {
tcolor = data.get(position).get("name").split(" / ");
name = tcolor[0].trim();
color = tcolor[1].trim();
} catch (IndexOutOfBoundsException e) {
name = "";
color = "#000000";
}
appWidgetManager = AppWidgetManager
.getInstance(WidgetActivity.this);
UnreadWidgetProvider.updateWidget(WidgetActivity.this,
appWidgetManager, n, path,
data.get(position).get("name"), color, s);
finish();
}
});
return convertView;
}
}
public void images(String path, String name, String color) {
try {
Bitmap bm;
try {
bm = decodeSampledBitmapFromResource(path);
ExifInterface exifReader = new ExifInterface(path);
int orientation = exifReader.getAttributeInt(
ExifInterface.TAG_ORIENTATION, -1);
if (orientation == ExifInterface.ORIENTATION_NORMAL) {
matrix.postRotate(360);
} else if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {
// matrix.postRotate(90);
} else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) {
// matrix.postRotate(180);
} else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {
// matrix.postRotate(270);
} else if (orientation == ExifInterface.ORIENTATION_UNDEFINED) {
// matrix.postRotate(90);
} else {
}
rotateimage = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(),
bm.getHeight(), matrix, true);
iv_notes.setImageBitmap(rotateimage);
content.setText(name);
content.setFocusable(false);
try {
String[] tcolor = name.split(" / ");
content.setText(tcolor[0].trim());
content.setTextColor(Color.parseColor(tcolor[1].trim()));
if (tcolor[2].trim().equals("0")) {
String text = content.getText().toString();
SpannableString span = new SpannableString(text);
span.setSpan(new UnderlineSpan(), 0, span.length(), 0);
// content.setText(span);
} else if (tcolor[2].trim().equals("3")) {
// content.setTypeface(null, Typeface.BOLD);
String text = content.getText().toString();
SpannableString span = new SpannableString(text);
span.setSpan(new UnderlineSpan(), 0, span.length(), 0);
// content.setText(span);
} else if (tcolor[2].trim().equals("4")) {
// content.setTypeface(null, Typeface.ITALIC);
String text = content.getText().toString();
SpannableString span = new SpannableString(text);
span.setSpan(new UnderlineSpan(), 0, span.length(), 0);
// content.setText(span);
} else if (tcolor[2].trim().equals("1")) {
// content.setTypeface(null, Typeface.BOLD);
String text = content.getText().toString();
SpannableString span = new SpannableString(text);
span.removeSpan(text);
} else if (tcolor[2].trim().equals("2")) {
// content.setTypeface(null, Typeface.ITALIC);
String text = content.getText().toString();
SpannableString span = new SpannableString(text);
span.removeSpan(text);
} else {
String text = content.getText().toString();
SpannableString span = new SpannableString(text);
span.removeSpan(text);
}
} catch (IndexOutOfBoundsException e) {
// TODO: handle exception
}
grid_layout.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
int i = grid.getCount();
Intent intentAlarm = new Intent(WidgetActivity.this,
WriteNotesActivity.class);
intentAlarm.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_SINGLE_TOP);
intentAlarm.putExtra("max", s);
startActivity(intentAlarm);
finish();
}
});
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} catch (Exception e) {
// finish();
}
}
public static Bitmap decodeSampledBitmapFromResource(String resId) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, 400, 300);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(resId, options);
}
public static int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and
// keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
|| (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
}
This might help someone out there after several hours without an answer to this. I found a way of solving this without using Picasso in handling the outOfMemoryError. I added this line of code in my Manifest file.
android:largeHeap="true"
I added this to the entire application here as below:-
<application
android:icon="#drawable/ic_launcher"
android:largeHeap="true"
android:label="#string/app_name" >
android:largeHeap is the instrument for increasing your allocated memory to app.
EDIT:
well, you are using too much memory. remove those 3 lines of code :
File imgFile = new File(data.get(position).get("path"));
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
imageView.setImageBitmap(myBitmap);
simply, you are assigning too much space to these instances and your phone runs out of memory. Just use my response and consider logging the file path so you can possibly use that without creating another file.
i think you used wrong implementation. Probably the context is not adressing correctly and therefore, i would personally use "this" instead. And for loading resources, their guide provides us with three implementations, see below:
pass drawable
Picasso.with(context).load(R.drawable.landing_screen).into(imageView1);
pass uri
Picasso.with(context).load("file:///android_asset/DvpvklR.png").into(imageView2);
pass file
Picasso.with(context).load(new File(...)).into(imageView3);
so therefore i would decode the image using this code:
Picasso.with(this).load(new File(data.get(position).get("path"))).into(imageView);

Get the LinearLayout inside a ListView from an Async Task onRetainNonConfigurationInstance()

I hope the title is not mis-leading. I am trying to implement onRetainNonConfigurationInstance() of an AsyncTask of loading images and am getting this error "Java.lang.RuntimeException:Unable to retain Activity". Here is my code for onRetainNonConfigurationInstance():
public Object onRetainNonConfigurationInstance(){
//final ListView listview = list;
final int count = list.getChildCount();
final LoadedImage[] mylist = new LoadedImage[count];
for(int i = 0; i < count; i++){
final ImageView v = (ImageView)list.getChildAt(i); // getting error here
mylist[i] = new LoadedImage(((BitmapDrawable) v.getDrawable()).getBitmap());
}
return mylist;
}
Here is the Logcat:
05-18 08:43:15.385: E/AndroidRuntime(28130): java.lang.RuntimeException: Unable to retain activity {com.MyApps.ImageGen/com.MyApps.ImageGen.Wallpapers}: java.lang.ClassCastException: android.widget.LinearLayout
05-18 08:43:15.385: E/AndroidRuntime(28130): at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:2989)
05-18 08:43:15.385: E/AndroidRuntime(28130): at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3100)
05-18 08:43:15.385: E/AndroidRuntime(28130): at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3216)
05-18 08:43:15.385: E/AndroidRuntime(28130): at android.app.ActivityThread.access$1600(ActivityThread.java:132)
Here is my layout with the ListView:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:cacheColorHint="#00000000"
android:listSelector="#android:color/transparent" >
</ListView>
</LinearLayout>
Here is how I setup the ListView:
private void setupViews() {
list = (ListView)findViewById(android.R.id.list);
list.setDivider(null);
list.setDividerHeight(0);
imageAdapter = new ImageAdapter(getApplicationContext());
list.setAdapter(imageAdapter);
list.setOnItemClickListener(this);
}
my async task and Item Adapter:
class LoadImagesFromSDCard extends AsyncTask<Object, LoadedImage, Object> {
#Override
protected Object doInBackground(Object... params) {
Bitmap bitmap = null;
Bitmap newbitmap = null;
Uri uri = null;
String [] img = {MediaStore.Images.Media._ID};
String state = Environment.getExternalStorageState();
if(Environment.MEDIA_MOUNTED.equals(state)){
cursor = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, img, null, null, null);
} else {
// cursor = getContentResolver().query(MediaStore.Images.Media.INTERNAL_CONTENT_URI, img, null, null, null);
inInternalStorage = true;
}
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID);
int size = cursor.getCount();
if(size == 0){
//Toast.makeText(getApplicationContext(), "There are no Images on the sdcard", Toast.LENGTH_SHORT).show();
//System.out.println("size equals zero");
Wallpaper.this.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(), "There are no Images on the sdcard", Toast.LENGTH_SHORT).show();
}
});
return params;
}else {
}
for(int i = 0; i < size; i++){
cursor.moveToPosition(i);
int ImageId = cursor.getInt(column_index);
if(inInternalStorage == true){
uri = Uri.withAppendedPath(MediaStore.Images.Media.INTERNAL_CONTENT_URI, "" + ImageId);
}else {
uri = Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "" + ImageId);
}
try {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(getContentResolver().openInputStream(uri), null, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;
Log.i(TAG, "imageheight = " + imageHeight);
Log.i(TAG, "imagewidth = " + imageWidth);
Log.i(TAG, "imageType = " + imageType);
//options.inSampleSize=4;
options.inSampleSize = calculateInSampleSize(options, imageWidth, imageHeight);
options.inJustDecodeBounds = false;
//bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri));
bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri), null, options);
if(bitmap != null){
newbitmap = Bitmap.createScaledBitmap(bitmap, 180, 180, true);
bitmap.recycle();
}
if(newbitmap != null){
publishProgress(new LoadedImage(newbitmap));
}
}catch(IOException e){
}
//cursor.close();
}
cursor.close();
return null;
}
#Override
public void onProgressUpdate(LoadedImage... value){
addImage(value);
}
#Override
protected void onPostExecute(Object result) {
setProgressBarIndeterminateVisibility(false);
}
}
private static class LoadedImage {
Bitmap mBitmap;
LoadedImage(Bitmap bitmap) {
mBitmap = bitmap;
}
public Bitmap getBitmap() {
return mBitmap;
}
}
/*Image Adapter to populate grid view of images*/
public class ImageAdapter extends BaseAdapter {
private Context mContext;
private ArrayList<LoadedImage> photos = new ArrayList<LoadedImage>();
public ImageAdapter(Context context){
this.mContext = context;
}
public void addPhotos(LoadedImage photo){
photos.add(photo);
}
#Override
public int getCount() {
return photos.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView image;
ViewHolder holder;
if(convertView == null){
LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//convertView = inflater.inflate(R.layout.image_list,null);
convertView = inflater.inflate(R.layout.media_view, null);
holder = new ViewHolder();
holder.image = (ImageView)convertView.findViewById(R.id.media_image_id);
//holder.item_name = (TextView)convertView.findViewById(R.id.media_image_id);
convertView.setTag(holder);
} else{
holder = (ViewHolder)convertView.getTag();
}
//holder.image.setLayoutParams(new GridView.LayoutParams(100, 100));
//String item_name = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME));
holder.image.setImageBitmap(photos.get(position).getBitmap());
//holder.item_name.setText(item_name);
return convertView;
}
}
static class ViewHolder {
ImageView image;
TextView item_name;
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Cursor cursor = null;
int image_column_index = 0;
String[] proj = {MediaStore.Images.Media.DATA};
String state = Environment.getExternalStorageState();
if(Environment.MEDIA_MOUNTED.equals(state)){
cursor = managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,proj,null, null,null);
}else{
cursor = managedQuery(MediaStore.Images.Media.INTERNAL_CONTENT_URI,proj,null, null,null);
}
cursor.moveToPosition(position);
image_column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
String info = cursor.getString(image_column_index);
Intent imageviewer = new Intent(getApplicationContext(), ViewImage.class);
imageviewer.putExtra("pic_name", info);
startActivity(imageviewer);
cursor.close();
}
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 2;
if (height > reqHeight || width > reqWidth) {
if (width > height) {
inSampleSize = Math.round((float)height / (float)reqHeight);
} else {
inSampleSize = Math.round((float)width / (float)reqWidth);
}
}
/*final int REQUIRED_SIZE = 180;
int scale = 1;
if(reqWidth > REQUIRED_SIZE || reqHeight > REQUIRED_SIZE){
scale = (int)Math.pow(2, (int)Math.round(Math.log(REQUIRED_SIZE/(double)Math.max(reqHeight, reqWidth)) / Math.log(0.5)));
}*/
return inSampleSize;
}
other Methods within Async Task:
private void loadImages() {
final Object data = getLastNonConfigurationInstance();
if(data == null){
new LoadImagesFromSDCard().execute();
}else {
final LoadedImage[] photos = (LoadedImage[])data;
if(photos.length == 0){
new LoadImagesFromSDCard().execute();
}
for(LoadedImage photo:photos){
addImage(photo);
}
}
}
private void addImage(LoadedImage... value) {
for(LoadedImage photo: value){
imageAdapter.addPhotos(photo);
imageAdapter.notifyDataSetChanged();
}
}
I am assuming I should first get the root element before I get the ListView from the logcat error, but I don't know how, I can't seem to find a suitable method from the documentation.
P.S: I am using an Activity and not a ListActivity.
The exception tells you that you try to do an invalid cast. My guess is that your row layout isn't a simple ImageView like you assume with the cast in the onRetainNonConfigurationInstance(), instead your row layout probably has a parent Linearlayout that wraps the ImageView(and other views?!). When you call the method getChildAt you get that parent Linearlayout which you try to cast to a ImageView. Instead you should do this:
//...
for(int i = 0; i < count; i++){
LinearLayout parent = (LinearLayout)list.getChildAt(i);
final ImageView v = (ImageView) parent.findViewById(R.id.the_id_of_the_imageview_from_theRow_layout);
mylist[i] = new LoadedImage(((BitmapDrawable) v.getDrawable()).getBitmap());
}
Note: The getChildAt method returns the rows views for the visible rows only so if you try to access the View for a row that isn't currently visible you'll most likely end up with a NullPointerException(you should get the drawables directly from the adapter and not from parsing all the rows Views).
Edit based on the comments:
If I understood your problem, the behavior you see it's normal. You didn't say how you ended up getting the bitmaps in the onRetainNonConfigurationInstance but my guess is that you just save the images from the ListView rows that are currently visible to the user. When it's time to restore the adapter with the images from getLastNonConfigurationInstance() you end up getting only those images which were previously visible. This will get worse if you rotate the phone again as, most likely, there are fewer images visible in landscape orientation then in the portrait orientation.
I don't know if this will work but you could try to modify the LoadedImage class to store the id of the image from MediaStore.Images.Media. When it's time to save the configuration, stop the LoadImagesFromSDCard task and nullify all the images(remove the Bitmap to which LoadedImage points)from the LoadedImages ArrayList(in the adapter) except the ones that are currently visible to the user. Send the photos ArrayList from your adapter through
onRetainNonConfigurationInstance.
When it's time to restore the adapter set the photos ArrayList of your new adapter to the one you got back and put the ListView to the position of the visible images(so the user sees the sent images). In the getView method of your adapter you'll put a default image(like loading...) when you have a null value for the Bitmap in the associated LoadedImage class. Start a new LoadImagesFromSDCard task to get the images and parse them again. When you get the id from MediaStore.Images.Media you'll check if a LoadedImage with this id exists in the adapter and if it has a Bitmap set to it. If it doesn't exist(or it doesn't have a Bitmap associated) then load the image and put it in the adapter, if not the image already exists and move to the next one.
I don't know if the solution above will work or if it's efficient. I would recommend you to modify the code and load images on demand instead of loading all up in a big task.

Categories

Resources