Loading all the images from gallery into the Application in android

Solution 1:

Working solution with the help of Glide. Bonus part is Glide will auto play Gif .

enter image description here

import java.util.ArrayList;

import android.app.Activity;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.provider.MediaStore.MediaColumns;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.Toast;

import com.bumptech.glide.Glide;

/**
 * The Class GallarySample.
 */
public class GallarySample extends Activity {

    /** The images. */
    private ArrayList<String> images;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.gallery_activity);

        GridView gallery = (GridView) findViewById(R.id.galleryGridView);

        gallery.setAdapter(new ImageAdapter(this));

        gallery.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1,
                    int position, long arg3) {
                if (null != images && !images.isEmpty())
                    Toast.makeText(
                            getApplicationContext(),
                            "position " + position + " " + images.get(position),
                            300).show();
                ;

            }
        });

    }

    /**
     * The Class ImageAdapter.
     */
    private class ImageAdapter extends BaseAdapter {

        /** The context. */
        private Activity context;

        /**
         * Instantiates a new image adapter.
         *
         * @param localContext
         *            the local context
         */
        public ImageAdapter(Activity localContext) {
            context = localContext;
            images = getAllShownImagesPath(context);
        }

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

        public Object getItem(int position) {
            return position;
        }

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

        public View getView(final int position, View convertView,
                ViewGroup parent) {
            ImageView picturesView;
            if (convertView == null) {
                picturesView = new ImageView(context);
                picturesView.setScaleType(ImageView.ScaleType.FIT_CENTER);
                picturesView
                        .setLayoutParams(new GridView.LayoutParams(270, 270));

            } else {
                picturesView = (ImageView) convertView;
            }

            Glide.with(context).load(images.get(position))
                    .placeholder(R.drawable.ic_launcher).centerCrop()
                    .into(picturesView);

            return picturesView;
        }

        /**
         * Getting All Images Path.
         *
         * @param activity
         *            the activity
         * @return ArrayList with images Path
         */
        private ArrayList<String> getAllShownImagesPath(Activity activity) {
            Uri uri;
            Cursor cursor;
            int column_index_data, column_index_folder_name;
            ArrayList<String> listOfAllImages = new ArrayList<String>();
            String absolutePathOfImage = null;
            uri = android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI;

            String[] projection = { MediaColumns.DATA,
                    MediaStore.Images.Media.BUCKET_DISPLAY_NAME };

            cursor = activity.getContentResolver().query(uri, projection, null,
                    null, null);

            column_index_data = cursor.getColumnIndexOrThrow(MediaColumns.DATA);
            column_index_folder_name = cursor
                    .getColumnIndexOrThrow(MediaStore.Images.Media.BUCKET_DISPLAY_NAME);
            while (cursor.moveToNext()) {
                absolutePathOfImage = cursor.getString(column_index_data);

                listOfAllImages.add(absolutePathOfImage);
            }
            return listOfAllImages;
        }
    }
}

Layout file for gridView

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <GridView
        android:id="@+id/galleryGridView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:columnWidth="280dp"
        android:gravity="center"
        android:horizontalSpacing="2dp"
        android:numColumns="2"
        android:padding="2dp"
        android:stretchMode="columnWidth"
        android:verticalSpacing="2dp" >
    </GridView>

</RelativeLayout>

UPDATE 2019 with Kotlin and LoderManager:

** 2) Use LoderManager to load async load images.**

Implement LoaderManager.LoaderCallbacks<Cursor> in your activity or Fragment class

Override LoaderCallbacks this:

private val IMAGE_LOADER_ID = 1
private val listOfAllImages = ArrayList<String>()



override fun onCreateLoader(p0: Int, p1: Bundle?): Loader<Cursor> {

    val uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
    val projection = arrayOf(MediaColumns.DATA, MediaStore.Images.Media.BUCKET_DISPLAY_NAME)
    val selection: String? = null     //Selection criteria
    val selectionArgs = arrayOf<String>()  //Selection criteria
    val sortOrder: String? = null

    return CursorLoader(
            activity!!.applicationContext,
            uri,
            projection,
            selection,
            selectionArgs,
            sortOrder)
}

override fun onLoadFinished(loader: Loader<Cursor>, cursor: Cursor?) {

    cursor?.let {
        val columnIndexData = it.getColumnIndexOrThrow(MediaColumns.DATA);

        while (it.moveToNext()) {

            listOfAllImages.add(it.getString(columnIndexData));
        }
    }
}


override fun onLoaderReset(loader: Loader<Cursor>) {
}

Lastly on onCreate method init loader:

 loaderManager.initLoader(IMAGE_LOADER_ID,
                null,
                this)

3) Using Kotlin Coroutine & ViewModel

implementation 'androidx.core:core-ktx:1.0.2'

implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.0-M2'

implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.0-M2"

Create View Model With Coroutine Context

  /**
   * Use Coroutines To Load Images
   */
   class ImageViewModel : ViewModel(), CoroutineScope {

    private val job = Job()
    override val coroutineContext: CoroutineContext
        get() = job + Dispatchers.Main

    private var imagesLiveData: MutableLiveData<List<String>> = MutableLiveData()
    fun getImageList(): MutableLiveData<List<String>> {
        return imagesLiveData
    }

    /**
     * Getting All Images Path.
     *
     * Required Storage Permission
     *
     * @return ArrayList with images Path
     */
    internal fun loadImagesfromSDCard(): ArrayList<String> {
        val uri: Uri = android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI
        val cursor: Cursor?
        val column_index_data: Int
        val column_index_folder_name: Int
        val listOfAllImages = ArrayList<String>()
        var absolutePathOfImage: String? = null

        val projection = arrayOf(MediaStore.MediaColumns.DATA, MediaStore.Images.Media.BUCKET_DISPLAY_NAME)

        cursor = AppController.globalContentResolvere!!.query(uri, projection, null, null, null)

        column_index_data = cursor!!.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA)
        column_index_folder_name = cursor!!
            .getColumnIndexOrThrow(MediaStore.Images.Media.BUCKET_DISPLAY_NAME)
        while (cursor!!.moveToNext()) {
            absolutePathOfImage = cursor!!.getString(column_index_data)
            listOfAllImages.add(absolutePathOfImage)
        }
        return listOfAllImages
    }

    fun getAllImages() {
        launch(Dispatchers.Main) {
            imagesLiveData.value = withContext(Dispatchers.IO) {
                loadImagesfromSDCard()
            }
        }
    }
}

And then use viewModel

 val imageViewModel = ViewModelProviders.of(this).get(ImageViewModel::class.java)

    imageViewModel.getImageList().observe(this, Observer<List<String>> { listOfImage ->
        imageWidgetStatus.text = """ Found ${listOfImage.size} Images"""


    // load images
    imageViewModel.getAllImages()

Solution 2:

You are using MediaStore.Images.Media.EXTERNAL_CONTENT_URI which is only the external storage.For the internal there is MediaStore.Images.Media.INTERNAL_CONTENT_URI. You can use a MergeCursor to combine both query results.

Solution 3:

Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), SELECT_PICTURE);

Solution 4:

 public static ArrayList<String> fetchGalleryImages(Activity context) {
        ArrayList<String> galleryImageUrls;
        final String[] columns = {MediaStore.Images.Media.DATA, MediaStore.Images.Media._ID};//get all columns of type images
        final String orderBy = MediaStore.Images.Media.DATE_TAKEN;//order data by date

        Cursor imagecursor = context.managedQuery(
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns, null,
                null, orderBy + " DESC");//get all data in Cursor by sorting in DESC order

        galleryImageUrls = new ArrayList<String>();

        for (int i = 0; i < imagecursor.getCount(); i++) {
            imagecursor.moveToPosition(i);
            int dataColumnIndex = imagecursor.getColumnIndex(MediaStore.Images.Media.DATA);//get column index
            galleryImageUrls.add(imagecursor.getString(dataColumnIndex));//get Image from column index

        }
        Log.e("fatch in","images");
        return galleryImageUrls;
    }