In one of my previous posts, I wrote about how to fetch and display images from the SD card. The problem with the previous post is that one would have to wait until the first couple of images are available and shown on the screen. This implies that when the user wants to see the images, he will wait a couple of seconds until the first screen of images is available. The code that I'm going to post here works more like the Gallery application, meaning that one image at a time will be displayed on the screen. To achieve this effect, I used an AsyncTask, which fetches one image at a time in the background, and adds that image to the grid view during the progress update.
package blog.android.sdcard2;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.Display;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.AdapterView.OnItemClickListener;
/**
* Loads images from SD card.
*
* @author Mihai Fonoage
*
*/
public class LoadImagesFromSDCardActivity extends Activity implements
OnItemClickListener {
/**
* Grid view holding the images.
*/
private GridView sdcardImages;
/**
* Image adapter for the grid view.
*/
private ImageAdapter imageAdapter;
/**
* Display used for getting the width of the screen.
*/
private Display display;
/**
* Creates the content view, sets up the grid, the adapter, and the click listener.
*
* @see android.app.Activity#onCreate(android.os.Bundle)
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Request progress bar
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.sdcard);
display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
setupViews();
setProgressBarIndeterminateVisibility(true);
loadImages();
}
/**
* Free up bitmap related resources.
*/
protected void onDestroy() {
super.onDestroy();
final GridView grid = sdcardImages;
final int count = grid.getChildCount();
ImageView v = null;
for (int i = 0; i < count; i++) {
v = (ImageView) grid.getChildAt(i);
((BitmapDrawable) v.getDrawable()).setCallback(null);
}
}
/**
* Setup the grid view.
*/
private void setupViews() {
sdcardImages = (GridView) findViewById(R.id.sdcard);
sdcardImages.setNumColumns(display.getWidth()/95);
sdcardImages.setClipToPadding(false);
sdcardImages.setOnItemClickListener(LoadImagesFromSDCardActivity.this);
imageAdapter = new ImageAdapter(getApplicationContext());
sdcardImages.setAdapter(imageAdapter);
}
/**
* Load images.
*/
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);
}
}
}
/**
* Add image(s) to the grid view adapter.
*
* @param value Array of LoadedImages references
*/
private void addImage(LoadedImage... value) {
for (LoadedImage image : value) {
imageAdapter.addPhoto(image);
imageAdapter.notifyDataSetChanged();
}
}
/**
* Save bitmap images into a list and return that list.
*
* @see android.app.Activity#onRetainNonConfigurationInstance()
*/
@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;
}
/**
* Async task for loading the images from the SD card.
*
* @author Mihai Fonoage
*
*/
class LoadImagesFromSDCard extends AsyncTask<Object, LoadedImage, Object> {
/**
* Load images from SD Card in the background, and display each image on the screen.
*
* @see android.os.AsyncTask#doInBackground(Params[])
*/
@Override
protected Object doInBackground(Object... params) {
//setProgressBarIndeterminateVisibility(true);
Bitmap bitmap = null;
Bitmap newBitmap = null;
Uri uri = null;
// Set up an array of the Thumbnail Image ID column we want
String[] projection = {MediaStore.Images.Thumbnails._ID};
// Create the cursor pointing to the SDCard
Cursor cursor = managedQuery( MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI,
projection, // Which columns to return
null, // Return all rows
null,
null);
int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Thumbnails._ID);
int size = cursor.getCount();
// If size is 0, there are no images on the SD Card.
if (size == 0) {
//No Images available, post some message to the user
}
int imageID = 0;
for (int i = 0; i < size; i++) {
cursor.moveToPosition(i);
imageID = cursor.getInt(columnIndex);
uri = Uri.withAppendedPath(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, "" + imageID);
try {
bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri));
if (bitmap != null) {
newBitmap = Bitmap.createScaledBitmap(bitmap, 70, 70, true);
bitmap.recycle();
if (newBitmap != null) {
publishProgress(new LoadedImage(newBitmap));
}
}
} catch (IOException e) {
//Error fetching image, try to recover
}
}
cursor.close();
return null;
}
/**
* Add a new LoadedImage in the images grid.
*
* @param value The image.
*/
@Override
public void onProgressUpdate(LoadedImage... value) {
addImage(value);
}
/**
* Set the visibility of the progress bar to false.
*
* @see android.os.AsyncTask#onPostExecute(java.lang.Object)
*/
@Override
protected void onPostExecute(Object result) {
setProgressBarIndeterminateVisibility(false);
}
}
/**
* Adapter for our image files.
*
* @author Mihai Fonoage
*
*/
class ImageAdapter extends BaseAdapter {
private Context mContext;
private ArrayList<LoadedImage> photos = new ArrayList<LoadedImage>();
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 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(8, 8, 8, 8);
imageView.setImageBitmap(photos.get(position).getBitmap());
return imageView;
}
}
/**
* A LoadedImage contains the Bitmap loaded for the image.
*/
private static class LoadedImage {
Bitmap mBitmap;
LoadedImage(Bitmap bitmap) {
mBitmap = bitmap;
}
public Bitmap getBitmap() {
return mBitmap;
}
}
/**
* When an image is clicked, load that image as a puzzle.
*/
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
int columnIndex = 0;
String[] projection = {MediaStore.Images.Media.DATA};
Cursor cursor = managedQuery( MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI,
projection,
null,
null,
null);
if (cursor != null) {
columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToPosition(position);
String imagePath = cursor.getString(columnIndex);
FileInputStream is = null;
BufferedInputStream bis = null;
try {
is = new FileInputStream(new File(imagePath));
bis = new BufferedInputStream(is);
Bitmap bitmap = BitmapFactory.decodeStream(bis);
Bitmap useThisBitmap = Bitmap.createScaledBitmap(bitmap, parent.getWidth(), parent.getHeight(), true);
bitmap.recycle();
//Display bitmap (useThisBitmap)
}
catch (Exception e) {
//Try to recover
}
finally {
try {
if (bis != null) {
bis.close();
}
if (is != null) {
is.close();
}
cursor.close();
projection = null;
} catch (Exception e) {
}
}
}
}
}
The sdcard.xml file:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<GridView
android:id="@+id/sdcard"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:stretchMode="columnWidth"
android:gravity="center" />
</FrameLayout>
That's it. Let me know if you have any questions.
Enjoy!
247 comments:
«Oldest ‹Older 201 – 247 of 247amazon expert consultant
Fulfillment by Amazon
Amazon Seller Consulting Agency
Amazon consulting firms
blockchain full node audit
ethereum smart contract audit
smart contract auditing services
Benefits of cryptocurrency exchange script
binance clone script V2.0 enhanced
Crypto Exchange Software
Cryptocurrency Exchange Script
binance clone Software
bitcoin Exchange Script
binance clone Script
we are the best Flutter App development company in noida
CarDekhen is India's leading car search venture that helps users buy cars that are right for them. The company has tie-ups with many auto manufacturers, more than 4000 car dealers and numerous financial institutions to facilitate the purchase of vehicles.
A concept car (also known as a concept vehicle, show vehicle or prototype) is a made to showcase new styling and/or new technology
CarDekhen is India's leading portal helping users buy & experience cars like never before. Explore us!
self drive car rental noida
self drive car rental greater noida
I use this in my proj bt i have one problem i use onclicklistner in getview when user click on image it works only after all images get load bt i want it work when we adding images too so please help me thanks in advance..
car rental services in Delhi
Blockchain casino game Clone Script
Bitcoin harving 2024
crypto casino game development
NFT game development company
metaverse game development company
Bc.game clone script
crypto casino script
Stake alternative
Ultimate way to create your crypto exchange like binance by Binance clone script
Raise your casino card game like Black jack using BlackJack Game Clone Development
Thanks for sharing this kind of information. This is meant to me. Check the best mobile app development agency if you want the best mobile app solutions.
Your blog is a captivating journey through insightful thoughts and eloquent expression. Each post is a testament to your profound understanding and passion for the subject matter. Your words resonate deeply, leaving readers both enlightened and inspired. Thank you for sharing your unique perspective and enriching the online community.
business consultant in uae
I cannot thank Arab Business Consultant enough for their invaluable guidance and support. Their unmatched expertise in navigating the complexities of the UAE Free Zone has been instrumental in driving our enterprise towards success.
Visit CMOLDS one of the web development companies in dubai offering complete and most authentic services in this domain.
Your way of explaining things is awesome; it makes understanding easier. Your post provided me with a lot of useful information. If anyone wants to learn more about this crypto trading bot development, feel free to check out my page and share your thoughts.
Your post is truly amazing, and I've been searching for something like this for a while. Thank you so much! If anyone wants to build a crypto trading bot development, my blog and my Best crypto trading bot development company can help. Drop by and share your thoughts.
I am very happy and satisfied with your blog for getting more information. I am here to share another amazing blog about most trending gaming platform zed run clone software.
As a promising crypto trading bot development company just want to appreciate your effort. Thanks for the knowledge-sharing.
This is an excellent post with an exciting line of content. Thanks for Supreme Hoodie sharing this article, great way of bringing this topic to discussion.
This blog post satisfied me with the information I needed. So if anybody is interested in learning about the same kind of interesting topic check our Binance clone page you will get valuable insights from there
Your blog has been very helpful for my personal growth, and the content of the entire blog post is wonderfully written. I truly have the utmost respect and appreciation for your work. If you want immediate revenue for cryptocurrency exchange I will suggest ICO token development
You're a wonderful blog writer. To continue your blog writing journey along with the wishes, I want to share about a cryptocurrency exchange development company for all crypto entrepreneurs.
I truly appreciate this informative blog post. It provided valuable knowledge and helped me understand this concept better. If anyone is looking for immediate revenue from cryptocurrency trading, they should consider building a crypto trading bot development services with a leading cryptocurrency exchange development company.
Your blog has been very helpful for my personal growth, and the content of the entire blog post is wonderfully written. I truly have the utmost respect and appreciation for your work. Investing in blockchain wallet development can help your cryptocurrency exchange improve its user experience and revenue sources. This tool offers customers a quick and safe way to store and manage their digital assets.
I am not only here to appreciate your work. I want to offer a blog to be appreciated which is a generative AI development services.
Your blog writing is superb and very nice words. Anyone interested for game development in a game industry I will suggest BC.game clone script is very interested game
I truly appreciate this informative blog post. It provided valuable knowledge and helped me understand this concept better. If anyone is looking for immediate revenue from cryptocurrency trading, they should consider building a coinbase clone script with a leading cryptocurrency exchange development company.
I am really amazed by your words, my friend. Are you interested in crypto casino game development, please connect, and click the share link?
Super helpful! I appreciate the practical tips you shared. If you're planning a dice game platform, the Mega Dice clone script offers an easy setup and great functionality.
Just saying thank you, will not enough for your article. I want to share something new about the popular game development company that provides a complete support for the developing quality games.
This post is incredibly informative and imprese for everyone. Creating complex characters and rich narratives is essential in RPGs. Let our RPG game development team build your dream game from scratch.
Wow, this was incredibly helpful! Your breakdown of the topic was thorough and very well-organized. Thanks for providing such valuable information.
Have a read on this topic- PancakeSwap Clone Script
I am waiting for your upcoming blogs. If you need to know new information from my side here it is blockchain wallet development solutions
This blog provides a great perspective on the topic and is a fantastic read. Our dApp game development company offers the perfect blend of creativity and technology. Partner with us for game-changing solutions.
Excellent read! The content is very engaging and insightful. Partner with our Bingo game development company for innovative and seamless gaming solutions.
I really enjoyed reading this! For anyone in the gaming industry, now is the time to develop a crypto game like BC.Game and tap into the blockchain revolution.
Thanks for sharing this blog. I want to share another informative thing to you which is about Dapp development
Very well-explained blog! Great tips and strategies. Build a secure and scalable platform with our Trust Dice clone script solution.
Appreciate the valuable information here! To anyone exploring poker game development, our poker game development company delivers innovative solutions tailored to your needs.
Your article was a pleasure to read! The insights you provided are incredibly valuable and well-articulated. Thanks for contributing to the community with such excellent content. If anyone wants to know more about the cryptocurrency exchange development, I can help expand their thinking.
I was very happy while reading this blog. Just, I want to share you something here. Playing games in mobile is best ever feel for all generation kids. So, entrepreneurs can launch the new mobile games by utilizing mobile game development services from well established company.
Such an interesting read, thanks for sharing! Let our cryptocurrency wallet development services pave the way for your blockchain success.
Post a Comment