안드로이드(Android) - 저장된 이미지를 불러와 갤러리 기능 구현 |
개발환경 : JDK 1.5, Android 2.1, Eclipse Galieo |
전체내용 |
이 글은 SD 카드에 저장되어있는 모든 이미지를 불러와 보여주는 갤러리 기능을 구현한
것입니다. 두개의 화면으로 구성되어있으며 첫번째 화면은 모든 그림정보를 불러와
리스트로 보여주죠. 두번째 화면은 이미지를 클릭해 큰 화면으로 볼수 있도록 구현되었다.
그리고 버튼을 클릭하면 리스트로 돌아오게 되어있습니다.
첫번째 화면구현 |
첫번째 리스트를 구현한 화면의 내용입니다.
GridView 위젯과 GridView 의 setOnItemClickListener 함수를 이용해 클릭시
상세 화면으로 갈수 있는 기능을 구현하였습니다.
GridView gv = (GridView)findViewById(R.id.ImgGridView); final ImageAdapter ia = new ImageAdapter(this); gv.setAdapter(ia); gv.setOnItemClickListener(new OnItemClickListener(){ public void onItemClick(AdapterView parent, View v, int position, long id){ ia.callImageViewer(position); } });
GridView 의 내용을 표현하기 위해서는 Adapter 클래스가 필요합니다. 그래서 BaseAdapter 를
상속받아 ImageAdapter 가 구현되었습니다. GridView 에 들어가는 개별 View 는 ImageView
위젯을 사용합니다. ImageView 위젯에 Bitmap 정보를 넣어서 넘기면 되는것입니다.
그 Bitmap 정보를 설정하는 소스 입니다.
ImageView 의 레이아웃 설정은 setLayoutParams 으로 하며, setScaleType 을 사용하여 이미지를
View 크기에 어떻게 넣을 건지 설정합니다. 그리고 아래에 소스에서는 이미지를 Bitmap 객체에
불러와 크기를 새로 치수에 맞게 새로 설정해서 셋팅하였다.ImageView imageView; if (convertView == null){ imageView = new ImageView(mContext); imageView.setLayoutParams(new GridView.LayoutParams(95, 95)); imageView.setAdjustViewBounds(false); imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); imageView.setPadding(2, 2, 2, 2); }else{ imageView = (ImageView) convertView; } // 이미지 크기를 새로 설정한다. BitmapFactory.Options bo = new BitmapFactory.Options(); bo.inSampleSize = 8; Bitmap bmp = BitmapFactory.decodeFile(thumbsDataList.get(position), bo); Bitmap resized = Bitmap.createScaledBitmap(bmp, 95, 95, true); imageView.setImageBitmap(resized);
여기서 중요하게 다루어지는 내용중 하나는 managedQuery 를 사용하여
SD 카드에 그림들을 전부 불러오는 부분입니다. 첫번째 들어가는 파라미터에 따라
다양한 정보들을 불러 올수있도록 Url 정보를 넘기는데 미디어 정보인 이미지를 가져오기
위해서는 MediaStore.Images.Media.EXTERNAL_CONTENT_URI 필요합니다.
그리고 어떤 데이터를 받을지 String 배열을 파라미터로 설정해 넘기면 된다.
String[] proj = {MediaStore.Images.Media._ID, MediaStore.Images.Media.DATA, MediaStore.Images.Media.DISPLAY_NAME, MediaStore.Images.Media.SIZE}; Cursor imageCursor = managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, proj, null, null, null);
managedQuery 의 함수와 파라미터 정보를 사용해 동영상,이미지 등 다양한 정보를
Cursor 객체로 받을수 있다. 그리고 쿼리의 where 절 처럼 두번째 쿼리에 값을 설정하면
특정 데이터를 불러 올수 있다.
Cursor imageCursor = managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, proj, "_ID='"+ thumbID +"'", null, null); if (imageCursor != null && imageCursor.moveToFirst()){ if (imageCursor.getCount() > 0){ int imgData = imageCursor.getColumnIndex(MediaStore.Images.Media.DATA); imageDataPath = imageCursor.getString(imgData); } }
첫번째 화면의 전체소스 |
import java.util.ArrayList; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; import android.provider.MediaStore; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.GridView; import android.widget.ImageView; import android.widget.AdapterView.OnItemClickListener; import com.success.R; public class ImageList extends Activity { private Context mContext; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.image_list); mContext = this; GridView gv = (GridView)findViewById(R.id.ImgGridView); final ImageAdapter ia = new ImageAdapter(this); gv.setAdapter(ia); gv.setOnItemClickListener(new OnItemClickListener(){ public void onItemClick(AdapterView parent, View v, int position, long id){ ia.callImageViewer(position); } }); } /**========================================== * Adapter class * ==========================================*/ public class ImageAdapter extends BaseAdapter { private String imgData; private String geoData; private ArrayListthumbsDataList; private ArrayList thumbsIDList; ImageAdapter(Context c){ mContext = c; thumbsDataList = new ArrayList (); thumbsIDList = new ArrayList (); getThumbInfo(thumbsIDList, thumbsDataList); } public final void callImageViewer(int selectedIndex){ Intent i = new Intent(mContext, ImagePopup.class); String imgPath = getImageInfo(imgData, geoData, thumbsIDList.get(selectedIndex)); i.putExtra("filename", imgPath); startActivityForResult(i, 1); } public boolean deleteSelected(int sIndex){ return true; } public int getCount() { return thumbsIDList.size(); } public Object getItem(int position) { return position; } public long getItemId(int position) { return position; } public View getView(int position, View convertView, ViewGroup parent) { ImageView imageView; if (convertView == null){ imageView = new ImageView(mContext); imageView.setLayoutParams(new GridView.LayoutParams(95, 95)); imageView.setAdjustViewBounds(false); imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); imageView.setPadding(2, 2, 2, 2); }else{ imageView = (ImageView) convertView; } BitmapFactory.Options bo = new BitmapFactory.Options(); bo.inSampleSize = 8; Bitmap bmp = BitmapFactory.decodeFile(thumbsDataList.get(position), bo); Bitmap resized = Bitmap.createScaledBitmap(bmp, 95, 95, true); imageView.setImageBitmap(resized); return imageView; } private void getThumbInfo(ArrayList thumbsIDs, ArrayList thumbsDatas){ String[] proj = {MediaStore.Images.Media._ID, MediaStore.Images.Media.DATA, MediaStore.Images.Media.DISPLAY_NAME, MediaStore.Images.Media.SIZE}; Cursor imageCursor = managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, proj, null, null, null); if (imageCursor != null && imageCursor.moveToFirst()){ String title; String thumbsID; String thumbsImageID; String thumbsData; String data; String imgSize; int thumbsIDCol = imageCursor.getColumnIndex(MediaStore.Images.Media._ID); int thumbsDataCol = imageCursor.getColumnIndex(MediaStore.Images.Media.DATA); int thumbsImageIDCol = imageCursor.getColumnIndex(MediaStore.Images.Media.DISPLAY_NAME); int thumbsSizeCol = imageCursor.getColumnIndex(MediaStore.Images.Media.SIZE); int num = 0; do { thumbsID = imageCursor.getString(thumbsIDCol); thumbsData = imageCursor.getString(thumbsDataCol); thumbsImageID = imageCursor.getString(thumbsImageIDCol); imgSize = imageCursor.getString(thumbsSizeCol); num++; if (thumbsImageID != null){ thumbsIDs.add(thumbsID); thumbsDatas.add(thumbsData); } }while (imageCursor.moveToNext()); } imageCursor.close(); return; } private String getImageInfo(String ImageData, String Location, String thumbID){ String imageDataPath = null; String[] proj = {MediaStore.Images.Media._ID, MediaStore.Images.Media.DATA, MediaStore.Images.Media.DISPLAY_NAME, MediaStore.Images.Media.SIZE}; Cursor imageCursor = managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, proj, "_ID='"+ thumbID +"'", null, null); if (imageCursor != null && imageCursor.moveToFirst()){ if (imageCursor.getCount() > 0){ int imgData = imageCursor.getColumnIndex(MediaStore.Images.Media.DATA); imageDataPath = imageCursor.getString(imgData); } } imageCursor.close(); return imageDataPath; } } }
두번째 화면구현 |
Intent 를 이용해 리스트화면에서 받은 이미지 경로와 파일명을 받습니다.
그리고 이미지 크기를 화면에 맞게 맞추어서 보여주면 됩니다.
/** 전송메시지 */
Intent i = getIntent();
Bundle extras = i.getExtras();
String imgPath = extras.getString("filename");
두번째 화면의 전체소스 |
import android.app.Activity; import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView; import com.success.R; public class ImagePopup extends Activity implements OnClickListener{ private Context mContext = null; private final int imgWidth = 320; private final int imgHeight = 372; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.image_popup); mContext = this; /** 전송메시지 */ Intent i = getIntent(); Bundle extras = i.getExtras(); String imgPath = extras.getString("filename"); /** 완성된 이미지 보여주기 */ BitmapFactory.Options bfo = new BitmapFactory.Options(); bfo.inSampleSize = 2; ImageView iv = (ImageView)findViewById(R.id.imageView); Bitmap bm = BitmapFactory.decodeFile(imgPath, bfo); Bitmap resized = Bitmap.createScaledBitmap(bm, imgWidth, imgHeight, true); iv.setImageBitmap(resized); /** 리스트로 가기 버튼 */ Button btn = (Button)findViewById(R.id.btn_back); btn.setOnClickListener(this); } /* (non-Javadoc) * @see android.view.View.OnClickListener#onClick(android.view.View) */ public void onClick(View v) { switch(v.getId()){ case R.id.btn_back: Intent intent = new Intent(mContext, ImageList.class); startActivity(intent); break; } } }
빠진 xml 값을 넣었습니다.
// ===== image_list.xml 레이아웃설정을 위한 xml 값 =====//
위의 파일은 전체 프로젝트 파일입니다. 이것만 이클립스에서 import 시키시면
될겁니다. 그리고 현재 여기에 소개되어있는 아티클은 연습용이 아닌 어플
출시용으로 쓰기에는 무리가 있습니다. 안드로이드 시스템에 어떻게 Intent 를
날려서 데이타를 가져오는지에 대한 학습이 주요 목적입니다.
현재 내용은 이미지전체를 가져오기 때문에 상당한 로딩시간과 리소스가
소모됩니다. 그래서 섬네일로 불러와야 하는데 아래 처럼 파라미터로
MediaStore.Images.Thumbnails 넘깁니다.
String[] projection = {MediaStore.Images.Thumbnails._ID}; // Create the cursor pointing to the SDCard imagecursor = managedQuery( MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, projection, // Which columns to return null, // Return all rows null, MediaStore.Images.Thumbnails.IMAGE_ID);
섬네일로 불러올려면 전체 이미지를 불러올때 섬네일이 없으면 섬네일 작업을
해서 넣어야 겠죠. 기회가 되면 업버전을 올리도록 하겠습니다.
현재 걸려있는 일들이 있어서 답변하는 수준밖에 안되 죄송하네요 ..
'안드로이드 개발' 카테고리의 다른 글
안드로이드 (android) 플러그인과 SDK 가 업데이트 에러 날 때 (1) | 2010.08.04 |
---|---|
구글에서 GMail 계정을 이용해 SMTP 로 안드로이드 메일보내기 (49) | 2010.08.02 |
Android(안드로이드) 에서 터치이벤트와 트랙볼 이벤트 처리 (7) | 2010.08.02 |
안드로이드 SDK 버전에 따른 전세계 사용자 분석(2.1 사용자 4/1 이상) (0) | 2010.08.02 |
안드로이드 OS VMWare 설치하기 (8) | 2010.08.02 |
iMac(맥) 에서 화면 캡쳐하기 (0) | 2010.08.02 |
MS Window (윈도우) 에서 Mac 공유 폴더 접근하기 (3) | 2010.08.01 |
synergy(시너지) 를 사용하는 경우 Mac 에서 한영 전환이 잘 되지 않을 때 (0) | 2010.08.01 |