Android 根據相冊預覽內存中的圖片和視屏

前言: 在開發中有個需求需要訪問本地圖片和視屏進行上傳,所以嘗試了以下訪問本地的圖片和視屏并利用gridView展示出來。

正文

一、先創建一個異步任務用于查詢數據庫中圖片、相冊、視屏等數據,代碼如下:

package com.example.test1.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import com.example.test1.R;
import com.example.test1.bean.PhotoUpImageBucket;
import com.example.test1.bean.PhotoUpImageItem;

import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.os.AsyncTask;
import android.provider.MediaStore;
import android.provider.MediaStore.Audio.Albums;
import android.provider.MediaStore.Images.Media;
import android.provider.MediaStore.Images.Thumbnails;
import android.util.Log;

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

    final String TAG = "PhotoUpAlbumHelper";
    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;
    //視屏列表
    List<HashMap<String, String>> videoList = new ArrayList<HashMap<String,String>>();
    
    private PhotoUpAlbumHelper() {}
    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();
        }
    }

    /**
     * 得到縮略圖
     */
    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());
        }
    }

    /**
     * 得到原圖-n
     */
    void getAlbum() {
        String[] projection = { Albums._ID, Albums.ALBUM, Albums.ALBUM_ART,
                Albums.ALBUM_KEY, Albums.ARTIST, Albums.NUMBER_OF_SONGS };
        Cursor cursor1 = cr.query(Albums.EXTERNAL_CONTENT_URI, projection, null,
                null, Albums.ALBUM_ID+" desc");
        getAlbumColumnData(cursor1);
        cursor1.close();
    }

    /**
     * 從本地數據庫中得到原圖
     * @param cur
     */
    private void getAlbumColumnData(Cursor cur) {
        if (cur.moveToFirst()) {
            int _id;
            String album;
            String albumArt;
            String albumKey;
            String artist;
            int numOfSongs;
            int _idColumn = cur.getColumnIndex(Albums._ID);
            int albumColumn = cur.getColumnIndex(Albums.ALBUM);
            int albumArtColumn = cur.getColumnIndex(Albums.ALBUM_ART);
            int albumKeyColumn = cur.getColumnIndex(Albums.ALBUM_KEY);
            int artistColumn = cur.getColumnIndex(Albums.ARTIST);
            int numOfSongsColumn = cur.getColumnIndex(Albums.NUMBER_OF_SONGS);
            do {
                _id = cur.getInt(_idColumn);
                album = cur.getString(albumColumn);
                albumArt = cur.getString(albumArtColumn);
                albumKey = cur.getString(albumKeyColumn);
                artist = cur.getString(artistColumn);
                numOfSongs = cur.getInt(numOfSongsColumn);
                HashMap<String, String> hash = new HashMap<String, String>();
                hash.put("_id", _id + "");
                hash.put("album", album);
                hash.put("albumArt", albumArt);
                hash.put("albumKey", albumKey);
                hash.put("artist", artist);
                hash.put("numOfSongs", numOfSongs + "");
                albumList.add(hash);
            } while (cur.moveToNext());
        }
    }

    /**
     * 是否創建了圖片集
     */
    boolean hasBuildImagesBucketList = false;
    /**
     * 得到圖片集
     */
    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));
                    Log.d(TAG, "出現了異常圖片的地址:cur.getString(photoPathIndex).substring="+cur.getString(photoPathIndex)
                            .substring(cur.getString(photoPathIndex).lastIndexOf("/")+1,cur.getString(photoPathIndex).lastIndexOf(".")));
                }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);
                    imageItem.setPhoto(true);
//                  imageItem.setThumbnailPath(thumbnailList.get(_id));
                    bucket.imageList.add(imageItem);
                    Log.i(TAG, "PhotoUpAlbumHelper類中 的——》path="+thumbnailList.get(_id));
                }
            } while (cur.moveToNext());
        }
        cur.close();
        hasBuildImagesBucketList = true;
    }

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

    /**
     * 得到原始圖像路徑
     * @param image_id
     * @return
     */
    String getOriginalImagePath(String image_id) {
        String path = null;
        Log.i(TAG, "---(^o^)----" + image_id);
        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;
    }
    
    private PhotoUpImageBucket getVideoes(){
        PhotoUpImageBucket videoes = new PhotoUpImageBucket();
        List<PhotoUpImageItem> videoList = new ArrayList<PhotoUpImageItem>();
        int count = 0;
        String[] params = new String[]{MediaStore.Video.Media._ID
                ,MediaStore.Video.Media.DISPLAY_NAME,MediaStore.Video.Media.DATA};
        //獲取游標
        Cursor cursor = cr.query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, params, null, null, null);
        //獲取制定索引值
        int _id = cursor.getColumnIndexOrThrow(MediaStore.Video.Media._ID);
        int _name = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DISPLAY_NAME);
        int _path = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA);
        if (cursor.moveToFirst()) {
            do {
                if (cursor.getString(_path).substring(
                        cursor.getString(_path).lastIndexOf("/")+1,
                        cursor.getString(_path).lastIndexOf("."))
                        .replaceAll(" ", "").length()<=0)
                {
                    Log.d(TAG, "出現了異常視屏的地址:cur.getString(photoPathIndex)="+cursor.getString(_path));
                    Log.d(TAG, "出現了異常視屏的地址:cur.getString(photoPathIndex).substring="+cursor.getString(_path)
                            .substring(cursor.getString(_path).lastIndexOf("/")+1,cursor.getString(_path).lastIndexOf(".")));
                }else {
                    String id = cursor.getString(_id);
                    String path = cursor.getString(_path);
                    
                    PhotoUpImageItem video = new PhotoUpImageItem();
                    video.setImageId(id);
                    video.setImagePath(path);
                    video.setPhoto(false);
                    videoList.add(video);
                    count++;
                }
            } while (cursor.moveToNext());
            videoes.setCount(count);
            videoes.setBucketName(context.getString(R.string.video_file_name));
            videoes.setImageList(videoList);
        }
        return videoes;
    }
    public void destoryList()
    {
        thumbnailList.clear();
        thumbnailList = null;
        albumList.clear();
        albumList = null;
        bucketList.clear();
        bucketList = null;
    }

    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);
    }
    
}

其中用到了兩個工具實體類:
PhotoUpImageBucket類

package com.example.test1.bean;

import java.io.Serializable;
import java.util.List;


/**
 * 一個目錄下的相冊對象
 */
public class PhotoUpImageBucket implements Serializable{
    
    public int count = 0;//相冊中的圖片數量
    public String bucketName;//相冊名
    public List<PhotoUpImageItem> imageList;//相冊中的圖片集合
    public int getCount() {
        return count;
    }
    public void setCount(int count) {
        this.count = count;
    }
    public String getBucketName() {
        return bucketName;
    }
    public void setBucketName(String bucketName) {
        this.bucketName = bucketName;
    }
    public List<PhotoUpImageItem> getImageList() {
        return imageList;
    }
    public void setImageList(List<PhotoUpImageItem> imageList) {
        this.imageList = imageList;
    }
    
}

PhotoUpImageItem類

package com.example.test1.bean;

import java.io.Serializable;

/**
 * 相冊下的圖片或視屏對象
 */
public class PhotoUpImageItem implements Serializable {

    //圖片ID
    private String imageId;
    //原圖路徑
    private String imagePath;
    //是否被選擇
    private boolean isSelected = false;
    //圖片還是視屏     true為圖片   false為視屏
    private boolean isPhoto = true;
    
    public String getImageId() {
        return imageId;
    }
    public void setImageId(String imageId) {
        this.imageId = imageId;
    }
    public String getImagePath() {
        return imagePath;
    }
    public void setImagePath(String imagePath) {
        this.imagePath = imagePath;
    }
    public boolean isSelected() {
        return isSelected;
    }
    public void setSelected(boolean isSelected) {
        this.isSelected = isSelected;
    }
    public boolean isPhoto() {
        return isPhoto;
    }
    public void setPhoto(boolean isPhoto) {
        this.isPhoto = isPhoto;
    }
    
    
}

二、新建一個activity,在其中放置一個GridView用于存放相冊集合

package com.example.test1;

import java.util.HashMap;
import java.util.List;

import com.example.test1.adpater.AlbumsAdapter;
import com.example.test1.bean.PhotoUpImageBucket;
import com.example.test1.util.PhotoUpAlbumHelper;
import com.example.test1.util.PhotoUpAlbumHelper.GetAlbumList;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.media.ThumbnailUtils;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.view.Window;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.GridView;

public class AlbumsActivity extends Activity implements OnScrollListener{

    private GridView gridView;
    private AlbumsAdapter adapter;
    private PhotoUpAlbumHelper photoUpAlbumHelper;
    private List<PhotoUpImageBucket> list;
    public static HashMap<String, Bitmap> bitmaps = new HashMap<String, Bitmap>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.albums_gridview);
        init();
        loadData();
        onItemClick();
    }
    private void init(){
        gridView = (GridView) findViewById(R.id.album_gridv);
        adapter = new AlbumsAdapter(AlbumsActivity.this);
        gridView.setAdapter(adapter);
    }
    
    private void loadData(){
        photoUpAlbumHelper = PhotoUpAlbumHelper.getHelper();
        photoUpAlbumHelper.init(AlbumsActivity.this);
        photoUpAlbumHelper.setGetAlbumList(new GetAlbumList() {
            @Override
            public void getAlbumList(List<PhotoUpImageBucket> list) {
                adapter.setArrayList(list);
                adapter.notifyDataSetChanged();
                AlbumsActivity.this.list = list;
            }
        });
        photoUpAlbumHelper.execute(false);
    }
    
        //設置gridView的item點擊事件
    private void onItemClick(){
        gridView.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {
                Intent intent = new Intent(AlbumsActivity.this,AlbumItemActivity.class);
                intent.putExtra("imagelist", list.get(position));
                startActivity(intent);
            }
        });
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
    }
    
    //釋放圖片的函數  
    private void recycleBitmapCaches(int fromPosition,int toPosition){                 
            Bitmap delBitmap = null;  
            for(int del=fromPosition;del<toPosition;del++){  
                    delBitmap = bitmaps.get(list.get(del).getBucketName());          
                    if(delBitmap != null){          
                            //如果非空則表示有緩存的bitmap,需要清理          
                            //從緩存中移除該del->bitmap的映射                 
                            bitmaps.remove(list.get(del).getBucketName());                 
                            delBitmap.recycle();          
                            delBitmap = null;  
                    }  
            }                 
    } 
    
    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        
    }
    @Override
    public void onScroll(AbsListView view, int firstVisibleItem,
            int visibleItemCount, int totalItemCount) {
        //注釋:firstVisibleItem為第一個可見的Item的position,從0開始,隨著拖動會改變  
        //visibleItemCount為當前頁面總共可見的Item的項數  
        //totalItemCount為當前總共已經出現的Item的項數 
        recycleBitmapCaches(0,firstVisibleItem);
        recycleBitmapCaches(firstVisibleItem+visibleItemCount,totalItemCount);
        
    }
}

為GridView定義適配器AlbumsAdapter

package com.example.test1.adpater;

import java.util.ArrayList;
import java.util.List;

import com.example.test1.AlbumsActivity;
import com.example.test1.R;
import com.example.test1.bean.PhotoUpImageBucket;
import com.nostra13.universalimageloader.cache.disc.naming.Md5FileNameGenerator;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.ImageScaleType;
import com.nostra13.universalimageloader.core.assist.QueueProcessingType;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.media.ThumbnailUtils;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class AlbumsAdapter extends BaseAdapter {

    Context mContext;
    
    private List<PhotoUpImageBucket> arrayList;
    private LayoutInflater layoutInflater;
    private ImageLoader imageLoader = ImageLoader.getInstance();
    private DisplayImageOptions options;
    private String TAG = AlbumsAdapter.class.getSimpleName();
    public AlbumsAdapter(Context context){
        mContext = context;
        layoutInflater = LayoutInflater.from(context);
        arrayList = new ArrayList<PhotoUpImageBucket>();//初始化集合
        ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
        .threadPriority(Thread.NORM_PRIORITY - 2)
        .denyCacheImageMultipleSizesInMemory()
        .discCacheFileNameGenerator(new Md5FileNameGenerator())
        .tasksProcessingOrder(QueueProcessingType.LIFO)
        .memoryCacheExtraOptions(96, 120)
        .build();
        // Initialize ImageLoader with configuration.
        imageLoader.init(config);

        // 使用DisplayImageOption.Builder()創建DisplayImageOptions
        options = new DisplayImageOptions.Builder()
                .showStubImage(R.drawable.album_default_loading_pic) // 設置圖片下載期間顯示的圖片
                .showImageForEmptyUri(R.drawable.album_default_loading_pic) // 設置圖片Uri為空或是錯誤的時候顯示的圖片
                .showImageOnFail(R.drawable.album_default_loading_pic) // 設置圖片加載或解碼過程中發生錯誤顯示的圖片
                .cacheInMemory(true) // 設置下載的圖片是否緩存在內存中
                .cacheOnDisc(true) // 設置下載的圖片是否緩存在SD卡中
                // .displayer(new RoundedBitmapDisplayer(20)) // 設置成圓角圖片
                .bitmapConfig(Config.RGB_565)
                .imageScaleType(ImageScaleType.IN_SAMPLE_INT)
                .build(); // 創建配置過的DisplayImageOption對象
        
    };
    @Override
    public int getCount() {
        return arrayList.size();
    }

    @Override
    public Object getItem(int position) {
        return arrayList.get(position);
    }

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

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        final Holder holder;
        
        if (convertView == null) {
            holder = new Holder();
            convertView = layoutInflater.inflate(R.layout.ablums_adapter_item, parent, false);
            holder.image = (ImageView) convertView.findViewById(R.id.image);
            holder.name = (TextView) convertView.findViewById(R.id.name);
            holder.count = (TextView) convertView.findViewById(R.id.count);
            convertView.setTag(holder);
        }else {
            holder = (Holder) convertView.getTag();
        }
        holder.count.setText(""+arrayList.get(position).getCount());
        holder.name.setText(arrayList.get(position).getBucketName());
        
        Log.e("aaaaaaaaaaaaaaaaaaaaaa", "con:"+mContext.getString(R.string.video_file_name)+"   list:"+arrayList.get(position).getBucketName()+"   position:"+position);
        if ((mContext.getString(R.string.video_file_name)).equals(
                arrayList.get(position).getBucketName())) {//如果是視屏,則起一個線程獲取縮略圖
            holder.image.setImageDrawable(mContext.getResources().getDrawable(R.drawable.album_default_loading_pic));
            final Handler mhHandler = new Handler(){

                @Override
                public void handleMessage(Message msg) {
                    switch (msg.what) {
                    case 111:
                        Bitmap bitmap = (Bitmap) msg.obj;
                        holder.image.setImageBitmap(bitmap);
                        AlbumsActivity.bitmaps.put(arrayList.get(position).getBucketName(), bitmap);
                        break;

                    default:
                        break;
                    }
                    super.handleMessage(msg);
                    
                }
                
            };
            new Thread(new Runnable() {
                
                @Override
                public void run() {
                    String videoPath = arrayList.get(position).getImageList().get(0).getImagePath();
                    Bitmap bitmap= ThumbnailUtils.createVideoThumbnail(
                            videoPath,MediaStore.Video.Thumbnails.MINI_KIND);
                    Message msg = new Message();
                    msg.what=111;
                    msg.obj=bitmap;
                    mhHandler.sendMessage(msg);
                }
            }).start();
//          
            
        }else {
            imageLoader.displayImage("file://"+arrayList.get(position).getImageList().get(0).getImagePath(),
                    holder.image, options);
        }
        
        return convertView;
    }
    

    class Holder{
        ImageView image;
        TextView name;
        TextView count;
    }

    public void setArrayList(List<PhotoUpImageBucket> arrayList) {
        this.arrayList = arrayList;
    }
}

在這里加載圖片使用的時imageloader實現加載,以解決GridView加載圖片卡頓及內存問題

三、然后是進入相冊后圖片列表的activity

首先是albm_item_images.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="#ffffff" >
    <RelativeLayout 
        android:id="@+id/title"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:background="#ff78ccf2">
        <TextView 
            android:id="@+id/back"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_alignParentLeft="true"
            android:layout_marginLeft="10dp"
            android:textColor="#ffffff"
            android:textSize="14sp"
            android:text="@android:string/cancel"/>
        <TextView 
            android:id="@+id/sure"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_alignParentRight="true"
            android:layout_marginRight="10dp"
            android:textColor="#ffffff"
            android:textSize="14sp"
            android:text="@android:string/yes"/>
    </RelativeLayout>
    <GridView
        android:id="@+id/album_item_gridv"
        android:listSelector="@android:color/transparent"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/title"
        android:horizontalSpacing="8dp"
        android:verticalSpacing="20dp"
        android:numColumns="3" 
        android:layout_marginTop="10dp"
        android:layout_centerHorizontal="true"
        />

</RelativeLayout>

AlbumItemActivity,顯示圖片的界面

import com.example.test1.bean.PhotoUpImageBucket;
import com.example.test1.bean.PhotoUpImageItem;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.CheckBox;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.GridView;

public class AlbumItemActivity extends Activity implements OnClickListener, OnScrollListener{

    private GridView gridView;
    private TextView back,ok;
    private PhotoUpImageBucket photoUpImageBucket;
    private ArrayList<PhotoUpImageItem> selectImages;
    private AlbumItemAdapter adapter;
    public static HashMap<String, Bitmap> bitmaps = new HashMap<String, Bitmap>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.album_item_images);
        init();
        setListener();
    }
    private void init(){
        gridView = (GridView) findViewById(R.id.album_item_gridv);
        back = (TextView) findViewById(R.id.back);
        ok = (TextView) findViewById(R.id.sure);
        selectImages = new ArrayList<PhotoUpImageItem>();
        
        Intent intent = getIntent();
        photoUpImageBucket = (PhotoUpImageBucket) intent.getSerializableExtra("imagelist");
        adapter = new AlbumItemAdapter(photoUpImageBucket.getImageList(), AlbumItemActivity.this);
        gridView.setAdapter(adapter);
    }
    private void setListener(){
        back.setOnClickListener(this);
        ok.setOnClickListener(this);
        gridView.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {
                if (photoUpImageBucket.getImageList().get(position).isPhoto()) {//如果是圖片的話
                    
                    CheckBox checkBox = (CheckBox) view.findViewById(R.id.check);
                    photoUpImageBucket.getImageList().get(position).setSelected(
                            !checkBox.isChecked());
                    adapter.notifyDataSetChanged();
                    
                    Toast.makeText(AlbumItemActivity.this, "postion="+position, 
                            Toast.LENGTH_SHORT).show();
//                  photoUpImageBucket.getImageList().get(position).setSelected(
//                          !photoUpImageBucket.getImageList().get(position).isSelected());
//                  adapter.notifyDataSetChanged();
                    if (photoUpImageBucket.getImageList().get(position).isSelected()) {
                        if (selectImages.contains(photoUpImageBucket.getImageList().get(position))) {
                            
                        }else {
                            selectImages.add(photoUpImageBucket.getImageList().get(position));
                        }
                    }else {
                        if (selectImages.contains(photoUpImageBucket.getImageList().get(position))) {
                            selectImages.remove(photoUpImageBucket.getImageList().get(position));
                        }else {
                            
                        }
                    }
                }else {//如果是視屏的話
                    Toast.makeText(AlbumItemActivity.this, "跳轉頁面,展示視屏", Toast.LENGTH_SHORT).show();
                }
                
            }
        });
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
    }
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.back:
            finish();
            break;
        case R.id.sure:
//          Intent intent = new Intent(AlbumItemActivity.this,SelectedImagesActivity.class);
//          intent.putExtra("selectIma", selectImages);
//          startActivity(intent);
            break;

        default:
            break;
        }
    }
    //釋放圖片的函數  
    private void recycleBitmapCaches(int fromPosition,int toPosition){                 
            Bitmap delBitmap = null;  
            for(int del=fromPosition;del<toPosition;del++){  
                    delBitmap = bitmaps.get(photoUpImageBucket.getImageList().get(del).getImageId());          
                    if(delBitmap != null){          
                            //如果非空則表示有緩存的bitmap,需要清理          
                            //從緩存中移除該del->bitmap的映射                 
                            bitmaps.remove(photoUpImageBucket.getImageList().get(del).getImageId());                 
                            delBitmap.recycle();          
                            delBitmap = null;  
                    }  
            }                 
    } 
    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        
    }
    @Override
    public void onScroll(AbsListView view, int firstVisibleItem,
            int visibleItemCount, int totalItemCount) {
        //注釋:firstVisibleItem為第一個可見的Item的position,從0開始,隨著拖動會改變  
        //visibleItemCount為當前頁面總共可見的Item的項數  
        //totalItemCount為當前總共已經出現的Item的項數 
        recycleBitmapCaches(0,firstVisibleItem);
        recycleBitmapCaches(firstVisibleItem+visibleItemCount,totalItemCount);
    }

}

具體的圖片或者視屏的GridView的適配器

package com.example.test1.adpater;

import java.util.HashMap;
import java.util.List;

import com.example.test1.AlbumsActivity;
import com.example.test1.R;
import com.example.test1.bean.PhotoUpImageItem;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.assist.ImageScaleType;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.media.ThumbnailUtils;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.ImageView;

public class AlbumItemAdapter extends BaseAdapter {
    private List<PhotoUpImageItem> list;
    private LayoutInflater layoutInflater;
    private ImageLoader imageLoader;
    private DisplayImageOptions options;
    private Context mContext;
    private HashMap<Integer, Holder> holderMaps = new HashMap<Integer, AlbumItemAdapter.Holder>();
    public AlbumItemAdapter(List<PhotoUpImageItem> list,Context context){
        this.list = list;
        mContext = context;
        layoutInflater = LayoutInflater.from(context);
        imageLoader = ImageLoader.getInstance();
        // 使用DisplayImageOption.Builder()創建DisplayImageOptions
        options = new DisplayImageOptions.Builder()
                .showStubImage(R.drawable.album_default_loading_pic) // 設置圖片下載期間顯示的圖片
                .showImageForEmptyUri(R.drawable.album_default_loading_pic) // 設置圖片Uri為空或是錯誤的時候顯示的圖片
                .showImageOnFail(R.drawable.album_default_loading_pic) // 設置圖片加載或解碼過程中發生錯誤顯示的圖片
                .cacheInMemory(true) // 設置下載的圖片是否緩存在內存中
                .cacheOnDisc(true) // 設置下載的圖片是否緩存在SD卡中
                // .displayer(new RoundedBitmapDisplayer(20)) // 設置成圓角圖片
                .bitmapConfig(Config.ARGB_8888)
                .imageScaleType(ImageScaleType.IN_SAMPLE_INT)
                .build(); // 創建配置過的DisplayImageOption對象
    }
    
    @Override
    public int getCount() {
        return list.size();
    }

    @Override
    public Object getItem(int position) {
        return list.get(position);
    }

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

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        final Holder holder;
        if (convertView == null) {
            convertView = layoutInflater.inflate(R.layout.album_item_images_item_view, parent, false);
            holder = new Holder();
            holder.imageView = (ImageView) convertView.findViewById(R.id.image_item);
            holder.checkBox = (CheckBox) convertView.findViewById(R.id.check);
            holder.videPlay = (ImageView) convertView.findViewById(R.id.video_play);
            convertView.setTag(holder);
            holderMaps.put(position, holder);
        }else {
            holder = (Holder) convertView.getTag();
            holderMaps.put(position, holder);
        }
        if (list.get(position).isPhoto()) {
            //圖片加載器的使用代碼,就這一句代碼即可實現圖片的加載。請注意
            //這里的uri地址,因為我們現在實現的是獲取本地圖片,所以使
            //用"file://"+圖片的存儲地址。如果要獲取網絡圖片,
            //這里的uri就是圖片的網絡地址。
            imageLoader.displayImage("file://"+list.get(position).getImagePath(), holder.imageView, options);
            holder.checkBox.setChecked(list.get(position).isSelected());
            holder.videPlay.setVisibility(View.GONE);
        }else {
            holder.imageView.setImageDrawable(mContext.getResources().getDrawable(R.drawable.album_default_loading_pic));
            final Handler mhHandler = new Handler(){

                @Override
                public void handleMessage(Message msg) {
                    switch (msg.what) {
                    case 111:
                        Bitmap bitmap = (Bitmap) msg.obj;
                        int num = msg.arg1;
                        Holder mHolder= holderMaps.get(num);
                        if (bitmap!=null) {
                            mHolder.imageView.setImageBitmap(bitmap);
                            AlbumsActivity.bitmaps.put(list.get(position).getImageId(), bitmap);
                        }
                        mHolder.videPlay.setVisibility(View.VISIBLE);
                        mHolder.checkBox.setVisibility(View.GONE);
                        break;

                    default:
                        break;
                    }
                    super.handleMessage(msg);
                    
                }
                
            };
            new Thread(new Runnable() {
                
                @Override
                public void run() {
                    String videoPath = list.get(position).getImagePath();
                    Bitmap bitmap= ThumbnailUtils.createVideoThumbnail(
                            videoPath,MediaStore.Video.Thumbnails.MINI_KIND);
//                  if (bitmap!=null) {
//                      holder.imageView.setImageBitmap(bitmap);
//                      AlbumsActivity.bitmaps.put(list.get(position).getImageId(), bitmap);
//                  }
//                  holder.videPlay.setVisibility(View.VISIBLE);
//                  holder.checkBox.setVisibility(View.GONE);
                    Message msg = new Message();
                    msg.what=111;
                    msg.obj=bitmap;
                    msg.arg1=position;
                    mhHandler.sendMessage(msg);
                }
            }).start();
        }
        
        return convertView;
    }
    
    class Holder{
        ImageView imageView;
        CheckBox checkBox;
        ImageView videPlay;
    }
}

需要注意的是,在數據庫中查詢道德視屏時沒有縮略圖的uri的,所以我們適配時的適配展示圖需要用

Bitmap bitmap= ThumbnailUtils.createVideoThumbnail(
                            videoPath,MediaStore.Video.Thumbnails.MINI_KIND);

來獲取縮略圖,但因為imageloader加載圖片時用url進行記載的。
我們加載視屏縮略圖時要使用setImageBitmap(Bitmap)方法,那么我們就還需要釋放我們的資源:

AlbumsActivity.bitmaps.put(arrayList.get(position).getBucketName(), bitmap);

    //釋放圖片的函數  
    private void recycleBitmapCaches(int fromPosition,int toPosition){                 
            Bitmap delBitmap = null;  
            for(int del=fromPosition;del<toPosition;del++){  
                    delBitmap = bitmaps.get(list.get(del).getBucketName());          
                    if(delBitmap != null){          
                            //如果非空則表示有緩存的bitmap,需要清理          
                            //從緩存中移除該del->bitmap的映射                 
                            bitmaps.remove(list.get(del).getBucketName());                 
                            delBitmap.recycle();          
                            delBitmap = null;  
                    }  
            }                 
    }
        @Override
    public void onScroll(AbsListView view, int firstVisibleItem,
            int visibleItemCount, int totalItemCount) {
        //注釋:firstVisibleItem為第一個可見的Item的position,從0開始,隨著拖動會改變  
        //visibleItemCount為當前頁面總共可見的Item的項數  
        //totalItemCount為當前總共已經出現的Item的項數 
        recycleBitmapCaches(0,firstVisibleItem);
        recycleBitmapCaches(firstVisibleItem+visibleItemCount,totalItemCount);
        
    }

總結:
在實現獲取相冊中的圖片或視頻時需要注意的幾點是:

  1. 在加載時要放在異步線程中執行,否在可能會導致ART。
  2. 加載圖片使用imageloader以解決緩存及卡頓問題。
  3. 當要展示視頻縮略圖時需要自己生成Bitmap對象并加載,這是要注意釋放資源。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,406評論 6 538
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,034評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,413評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,449評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,165評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,559評論 1 325
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,606評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,781評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,327評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,084評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,278評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,849評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,495評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,927評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,172評論 1 291
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,010評論 3 396
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,241評論 2 375

推薦閱讀更多精彩內容