Jade Byfield
Jade Byfield

Reputation: 4816

loading images from SD card directory in GridView

I've created an app that allows the user to create a photo album(Folder) on External Storage. Now I am trying to retrieve the images from said directory and display them inside a GridView. I'm using an AsyncTask to iterate through the directory of files using listFiles() and then creating a bitmap once I grab each image, recycle it, and then use it again. My problem is that nothing is showing up in my GridView. I've set up a few Log breaks and LogCat shows me that the iteration does happen and the images are retrieved. This leads me to think that I made a mistake somewhere in my Adapter class that binds the bitmaps to the Grid, possibly in getView? Or maybe I'm wrong. Any help on what I'm doing wrong? I tried to comment the code as much as possible and I've left out the unecessary pieces. Thanks

public class AlbumGridView extends Activity implements OnItemClickListener {

private GridView sdcardImages;
private ImageAdapter imageAdapter;

private Display display;

private Bitmap bitmap;
private Bitmap b;

File[] imageList;
private static final String TAG = "AlbumGridView";
String path;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
    setContentView(R.layout.album_view);

    //display = 
    //((Object) getSystemService(Context.WINDOW_SERVICE))).getDefaultDisplay();

    path = getIntent().getStringExtra("key");
    Toast.makeText(this, path, Toast.LENGTH_SHORT).show();
    setupViews();
    setProgressBarIndeterminateVisibility(true);
    loadImages();



}

protected void onDestroy() {
    super.onDestroy();
    final GridView grid = sdcardImages;
    final int count = grid.getCount();
    ImageView v = null;
    for (int i = 0; i < count; i++) {
        v = (ImageView) grid.getChildAt(i);
        ((BitmapDrawable) v.getDrawable()).setCallback(null);
    }
}

// Set up the GridView

private void setupViews() {
    sdcardImages = (GridView) findViewById(R.id.gvAlbumView);
    // sdcardImages.setNumColumns(display.getWidth()/95);
    sdcardImages.setClipToPadding(false);
    sdcardImages.setOnItemClickListener(AlbumGridView.this);
    imageAdapter = new ImageAdapter(getApplicationContext());
    // imageAdapter.setImageList(path);
    sdcardImages.setAdapter(imageAdapter);
}

private void addImage(LoadedImage... value) {
    for (LoadedImage image : value) {
        imageAdapter.addPhoto(image);
        imageAdapter.notifyDataSetChanged();
    }
}

// Save Bitmap images to a list and return that list
@Override
public Object onRetainNonConfigurationInstance() {
    final GridView grid = sdcardImages;
    final int count = grid.getChildCount();
    final LoadedImage[] list = new LoadedImage[count];

    for (int i = 0; i < count; i++) {
        final ImageView v = (ImageView) grid.getChildAt(i);
        list[i] = new LoadedImage(
                ((BitmapDrawable) v.getDrawable()).getBitmap());
    }

    return list;
}

private void loadImages() {
    // TODO Auto-generated method stub
    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);
        }
    }
}

public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
    // TODO Auto-generated method stub

}

/-------------------------------------------------------------------------------------/

//Adapter for the GridView

public class ImageAdapter extends BaseAdapter {

    private Context mContext;
    private ArrayList<LoadedImage> photos = new ArrayList<LoadedImage>();

    private String path;
    private Bitmap bitmap;

    public ImageAdapter(Context context) {
        mContext = context;
    }

    public void addPhoto(LoadedImage photo) {
        photos.add(photo);
    }

    public int getCount() {
        return photos.size();
    }

    public Object getItem(int position) {
        return photos.get(position);
    }

    public long getItemId(int position) {
        return position;
    }

    /*
     * public File[] setImageList(String path) {
     * 
     * //this.path = path; //this.imageList = imageList; //File imagesDir =
     * new File(path); //imageList = imagesDir.listFiles();
     * 
     * File imagesDir = new File(path); imageList = imagesDir.listFiles();
     * for (File image : imageList) try { bitmap =
     * BitmapFactory.decodeStream(image.toURL().openStream()); //use bitmap
     * and recycle afterwards LoadedImage lm = new LoadedImage(bitmap);
     * this.addPhoto(lm); bitmap.recycle();
     * 
     * } catch (IOException e) { e.printStackTrace(); } return imageList;
     * 
     * }
     */

    public View getView(int position, View convertView, ViewGroup parent) {
        final ImageView imageView;
        if (convertView == null) {
            imageView = new ImageView(mContext);
        } else {
            imageView = (ImageView) convertView;
        }
        imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
        imageView.setPadding(2, 2, 2, 2);
        // imageView.setImageBitmap(photos.get(position).getBitmap());
        try {
            imageView
                    .setImageBitmap(BitmapFactory
                            .decodeStream(imageList[position].toURL()
                                    .openStream()));
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return imageView;
    }
}

/*-------------------------------------------------------------------------*/

//AsyncTask to get the images

class LoadImagesFromSDCard extends AsyncTask<Object, LoadedImage, Object> {

    @Override
    protected Object doInBackground(Object... arg0) {
        // Load images from SD card in Background
        // Display each image on the screen

        File imagesDir = new File(path);
        imageList = imagesDir.listFiles();

        for (File image : imageList)

            try {

                if (bitmap != null) {
                    bitmap.recycle();
                    bitmap = null;
                }
                bitmap = BitmapFactory.decodeStream(image.toURL()
                        .openStream());
                Log.e(TAG, "Grabbed Image " + image.getName());
                // use bitmap then recycle after

                LoadedImage lm = new LoadedImage(bitmap);
                // addImage(lm);
                // imageAdapter.addPhoto(lm);
                // imageAdapter.setImageList(path);
                // imageAdapter.addPhoto(lm);
                // imageAdapter.setImageList(path);
                // bitmap.recycle();
                // addImage(lm);
                // imageAdapter.addPhoto(lm);
                Log.e(TAG, "Added Image " + lm.toString());

                // imageAdapter.setImageList(path);
                addImage(lm);

                // bitmap.recycle();

                // bitmap.recycle();

            } catch (Exception e) {
                e.printStackTrace();
            }

        return null;
    }

Upvotes: 2

Views: 5848

Answers (1)

Jade Byfield
Jade Byfield

Reputation: 4816

Here's the solution btw, sorry It took so long to I wasn't aware that others were waiting for the answer. Sorry. The relevant code is below.

This is AsyncTask that will query the device's MediaStore and retrieve all the photos. Note that this is retrieving the thumbnails and not the full size images, and more specifically it's the MICRO_KIND. There is also a Thumbnail.MINI_KIND as well.

/*----------------------------ASYNC TASK TO LOAD THE     PHOTOS--------------------------------------------------------*/

public class LoadPhotos extends AsyncTask<Object, Object, Object> {

    @Override
    protected Object doInBackground(Object... params) {
        try {
            final String[] columns = { MediaStore.Images.Media._ID };
            final String orderBy = MediaStore.Images.Media._ID;

            Cursor imagecursor = managedQuery(
                    MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns,
                    null, null, orderBy);

            int image_column_index = imagecursor
                    .getColumnIndex(MediaStore.Images.Media._ID);

            AllPhotosActivity.count = imagecursor.getCount();
            AllPhotosActivity.windows = new Bitmap[AllPhotosActivity.count];

            for (int i = 0; i < AllPhotosActivity.count; i++) {
                imagecursor.moveToPosition(i);
                // i = index;
                int id = imagecursor.getInt(image_column_index);
                windows[i] = MediaStore.Images.Thumbnails.getThumbnail(
                        getApplicationContext().getContentResolver(), id,
                        MediaStore.Images.Thumbnails.MICRO_KIND, null);
            }

            imagecursor.close();
        } catch (Exception e) {
            e.printStackTrace();
            Log.d("AllPhotosActivity",
                    "Error occured while fetching all photos on device.");
        }
        return null;

    }

    @Override
    protected void onPostExecute(Object result) {
        // TODO Auto-generated method stub
        super.onPostExecute(result);
        Handler mHandler = new Handler();

        mHandler.post(new Runnable() {

            public void run() {

                pd.dismiss();
                // imageAdapter.notifyDataSetChanged();
                // sdcardImages.setAdapter(imageAdapter);

            }

        });

        // pd.dismiss();
        imagegrid.setAdapter(imageAdapter);
        // pd.dismiss();

    }

    @Override
    protected void onProgressUpdate(Object... values) {
        // TODO Auto-generated method stub
        super.onProgressUpdate(values);
    }

}

Here's the adapter for the GridView that's going to bind your thumbnails to the gridview. My issue was simply in the getView method of my ImageAdapter, notice I'm setting my ImageView resources from different indexes of an array of Bitmaps I called windows.

public class ImageAdapter extends BaseAdapter {
    private Context mContext;

    public ImageAdapter(Context c) {
        mContext = c;
    }

    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return position;
    }

    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return position;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        ImageView i = (ImageView) convertView;
        if (i != null) {
            i.setImageBitmap(windows[position]);
        } else {
            i = new ImageView(mContext.getApplicationContext());
            // i.setPadding(3, 3, 3, 3);
            // i.setScaleType(ImageView.ScaleType.FIT_CENTER);
            i.setAdjustViewBounds(true);
            // i.setMaxHeight(200);
            // i.setMaxWidth(200);
            i.setPadding(3, 3, 3, 3);
            i.setLayoutParams(new GridView.LayoutParams(92, 92));
            i.setImageBitmap(windows[position]);

        }
        return i;
    }

    public int getCount() {
        // TODO Auto-generated method stub
        return count;
    }
}

Upvotes: 1

Related Questions