android 获取相册列表的实现(一)

项目实现的功能如下:
获取手机相册,点击每个相册之后进入该相册的图片列表界面,在图片列表界面可以实现图片多选,然后进入所选择的图片界面,在该界面内可以实现所选图片的上传等功能。
该项目最大特色:
1、获取相册列表,目前网络上面介绍获取相册的项目很少,本文专门讲述相册的获取。
2、使用Android-Universal-Image-Loader集成框架-第三方jar包加载本地图片,熟悉这个jar的开发者肯定不陌生,该jar包十分强大,除了可以获取网络图片,本地图片也是可以的。同时,通过引用第三方jar可以有效解决OOM异常问题。
最近CSDN可能出现问题了,图片上传不了,所以没有办法给大家看效果图。
首先讲解获取手机相册的原理:
我们都知道获取手机图片要使用到ContentResolver这个类,但是通过这个类获取相册,是获取不到的,只能获取到相册的ID,相册封面图片无法获取(至少目前我在写本篇博文时,还不知道如何直接获取手机相册,如果大家知道如何直接获取相册的话勿怪哈,本人水平有限^_^,同时也请不吝赐教,请留言哈【握手】)。所以该项目在实现获取手机相册的时候,是通过先获取手机相册的ID,然后获取手机内容全部图片,通过比较图片所在的相册ID,把每一个图片归并到相应的相册中去。
现在给出获取相册以及相册内部图片的类,获取相册和图片在这一个类中完成。代码如下:

/**
* 异步线程类实现该功能
*/
public class PhotoUpAlbumHelper extends AsyncTask<Object, Object, Object>{

    final String TAG = getClass().getSimpleName();
    Context context;
    ContentResolver cr;
    // 缩略图列表
    HashMap<String, String> thumbnailList = new HashMap<String, String>();
    // 专辑列表
    List<HashMap<String, String>> albumList = new ArrayList<HashMap<String, String>>();
    HashMap<String, PhotoUpImageBucket> bucketList = new HashMap<String, PhotoUpImageBucket>();
    private GetAlbumList getAlbumList;
    //获取实例
    public static PhotoUpAlbumHelper getHelper() {
        PhotoUpAlbumHelper instance = new PhotoUpAlbumHelper();
        return instance;
    }

    /**
     * 初始化
     * @param context
     */
    public void init(Context context) {
        if (this.context == null) {
            this.context = context;
            cr = context.getContentResolver();
        }
    }

    /**
     * 得到缩略图,这里主要得到的是图片的ID值
     */
    private void getThumbnail() {
        String[] projection = { Thumbnails._ID, Thumbnails.IMAGE_ID,
                Thumbnails.DATA};
        Cursor cursor1 = Thumbnails.queryMiniThumbnails(cr, Thumbnails.EXTERNAL_CONTENT_URI,
                Thumbnails.MINI_KIND, projection);
        getThumbnailColumnData(cursor1);
        cursor1.close();
    }

    /**
     * 从数据库中得到缩略图
     * @param cur
     */
    private void getThumbnailColumnData(Cursor cur) {
        if (cur.moveToFirst()) {
            int image_id;
            String image_path;
            int image_idColumn = cur.getColumnIndex(Thumbnails.IMAGE_ID);
            int dataColumn = cur.getColumnIndex(Thumbnails.DATA);
            do {
                image_id = cur.getInt(image_idColumn);
                image_path = cur.getString(dataColumn);
                thumbnailList.put("" + image_id, image_path);
            } while (cur.moveToNext());
        }
    }
    /**
     * 是否创建了图片集
     */
    boolean hasBuildImagesBucketList = false;
    /**
     * 得到图片集
     */
    private void buildImagesBucketList() {
        // 构造缩略图索引
        getThumbnail();
        // 构造相册索引
        String columns[] = new String[] { Media._ID, Media.BUCKET_ID,
                Media.PICASA_ID, Media.DATA, Media.DISPLAY_NAME, Media.TITLE,
                Media.SIZE, Media.BUCKET_DISPLAY_NAME };
        // 得到一个游标
        Cursor cur = cr.query(Media.EXTERNAL_CONTENT_URI, columns, null, null,
                Media.DATE_MODIFIED+" desc");
        if (cur.moveToFirst()) {
            // 获取指定列的索引
            int photoIDIndex = cur.getColumnIndexOrThrow(Media._ID);
            int photoPathIndex = cur.getColumnIndexOrThrow(Media.DATA);
            int bucketDisplayNameIndex = cur.getColumnIndexOrThrow(Media.BUCKET_DISPLAY_NAME);
            int bucketIdIndex = cur.getColumnIndexOrThrow(Media.BUCKET_ID);
            /**
             * Description:这里增加了一个判断:判断照片的名
             * 字是否合法,例如.jpg .png等没有名字的格式
             * 如果图片名字是不合法的,直接过滤掉
             */
            do {
                if (cur.getString(photoPathIndex).substring(
                        cur.getString(photoPathIndex).lastIndexOf("/")+1,
                        cur.getString(photoPathIndex).lastIndexOf("."))
                        .replaceAll(" ", "").length()<=0)
                {
                    Log.d(TAG, "出现了异常图片的地址:cur.getString(photoPathIndex)="+cur.getString(photoPathIndex));
                }else {
                    String _id = cur.getString(photoIDIndex);
                    String path = cur.getString(photoPathIndex);
                    String bucketName = cur.getString(bucketDisplayNameIndex);
                    String bucketId = cur.getString(bucketIdIndex);
                    PhotoUpImageBucket bucket = bucketList.get(bucketId);
                    //这里完成图片归并到响应的相册里去
                    if (bucket == null) {
                        bucket = new PhotoUpImageBucket();
                        bucketList.put(bucketId, bucket);
                        bucket.imageList = new ArrayList<PhotoUpImageItem>();
                        bucket.bucketName = bucketName;
                    }
                    bucket.count++;
                    PhotoUpImageItem imageItem = new PhotoUpImageItem();
                    imageItem.setImageId(_id);
                    imageItem.setImagePath(path);
                    bucket.imageList.add(imageItem);
                }
            } while (cur.moveToNext());
        }
        cur.close();
        hasBuildImagesBucketList = true;
    }

    /**
     * 得到图片集
     * @param refresh
     * @return
     */
    private List<PhotoUpImageBucket> getImagesBucketList(boolean refresh) {
        if (refresh || (!refresh && !hasBuildImagesBucketList)) {
            buildImagesBucketList();
        }
        List<PhotoUpImageBucket> tmpList = new ArrayList<PhotoUpImageBucket>();
        Iterator<Entry<String, PhotoUpImageBucket>> itr = bucketList.entrySet().iterator();
        //将Hash转化为List
        while (itr.hasNext()) {
            Map.Entry<String, PhotoUpImageBucket> entry = (Map.Entry<String, PhotoUpImageBucket>) itr
                    .next();
            tmpList.add(entry.getValue());
        }
        return tmpList;
    }

    /**
     * 得到原始图像路径
     * @param image_id
     * @return
     */
    private String getOriginalImagePath(String image_id) {
        String path = null;
        String[] projection = { Media._ID, Media.DATA };
        Cursor cursor = cr.query(Media.EXTERNAL_CONTENT_URI, projection,
                Media._ID + "=" + image_id, null, Media.DATE_MODIFIED+" desc");
        if (cursor != null) {
            cursor.moveToFirst();
            path = cursor.getString(cursor.getColumnIndex(Media.DATA));
        }
        return path;
    }

    public void setGetAlbumList(GetAlbumList getAlbumList) {
        this.getAlbumList = getAlbumList;
    }
    //回调接口,当完成相册和图片的获取之后,调用该接口的方法传递数据,这种方法很常用,大家务必掌握
    public interface GetAlbumList{
        public void getAlbumList(List<PhotoUpImageBucket> list);
    }

    @Override
    protected Object doInBackground(Object... params) {
        return getImagesBucketList((Boolean)(params[0]));
    }
    @SuppressWarnings("unchecked")
    @Override
    protected void onPostExecute(Object result) {
        super.onPostExecute(result);
        getAlbumList.getAlbumList((List<PhotoUpImageBucket>)result);
    }
}

该类使用异步线程类实现,并通过回调接口传递数据,在执行异步线程完成之后,通过如下代码传递数据。

protected void onPostExecute(Object result) {
        super.onPostExecute(result);
        getAlbumList.getAlbumList((List<PhotoUpImageBucket>)result);
    }

在Activity中使用如下方式获取上面得到的数据:

private void loadData(){
        photoUpAlbumHelper = PhotoUpAlbumHelper.getHelper();//创建异步线程实例
        photoUpAlbumHelper.init(AlbumsActivity.this);//初始化实例
        //回调接口,创建匿名内部对象,实现接口中的方法,获取到PhotoUpAlbumHelper的接口GetAlbumList所传递的数据
        photoUpAlbumHelper.setGetAlbumList(new GetAlbumList() {
            @Override
            public void getAlbumList(List<PhotoUpImageBucket> list) {
                adapter.setArrayList(list);
                adapter.notifyDataSetChanged();//更新视图
                AlbumsActivity.this.list = list;
            }
        });
        photoUpAlbumHelper.execute(false);//异步线程执行
    }

下面两篇博文中会介绍相册界面和所选择的相册内图片列表界面。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。