Android Open Source - MediaPicker Image Base Loader






From Project

Back to project page MediaPicker.

License

The source code is released under:

Apache License

If you think the Android project MediaPicker listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.urza.mediapicker;
//from ww  w. j av  a 2  s .  com
import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
import android.database.CursorJoiner;
import android.net.Uri;
import android.os.Handler;
import android.provider.MediaStore;
import android.support.v4.content.AsyncTaskLoader;
import android.util.Log;

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

/**
 * Created by urza on 25.7.2014.
 */
public class ImageBaseLoader extends AsyncTaskLoader<List<MediaEntityWrapper>> {

    // We hold a reference to the Loaders data here.
    private List<MediaEntityWrapper> mData;
    private SampleObserver mObserver;
    private String parent;

    public ImageBaseLoader(Context ctx, String parent) {
        // Loaders may be used across multiple Activities (assuming they aren't
        // bound to the LoaderManager), so NEVER hold a reference to the context
        // directly. Doing so will cause you to leak an entire Activity's context.
        // The superclass constructor will store a reference to the Application
        // Context instead, and can be retrieved with a call to getContext().
        super(ctx);
        this.parent = parent;
    }

    /****************************************************/
    /** (1) A task that performs the asynchronous load **/
    /**
     * ************************************************
     */

    public List<MediaEntityWrapper> loadInBackground() {
        // This method is called on a background thread and should generate a
        // new set of data to be delivered back to the client.

        List<MediaEntityWrapper> entityList = new ArrayList<MediaEntityWrapper>();
        // TODO: Perform the query here and add the results to 'data'.
        Log.d("DEBUG_TAG", "Querying Images...");
        try {
            final Uri baseFilesUri = MediaStore.Files.getContentUri("external");
            Log.d("DEBUG_TAG", "Files Uri: " + baseFilesUri.toString());
            final String[] fileColumns = {
                    MediaStore.Files.FileColumns._ID,
                    MediaStore.Files.FileColumns.MEDIA_TYPE,
                    MediaStore.Files.FileColumns.MIME_TYPE,
                    MediaStore.Files.FileColumns.PARENT,
                    MediaStore.Files.FileColumns.DATA
            };
            final String filesSelection = MediaStore.Files.FileColumns.MEDIA_TYPE + " = ? AND " + MediaStore.Files.FileColumns.PARENT + " = ?";
            final String[] filesSelectionArgs = {"" + MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE, parent};
            final String filesOrderBy = MediaStore.Files.FileColumns._ID + " ASC";

            Cursor imageCursor = getContext().getContentResolver().query(
                    baseFilesUri, fileColumns,
                    filesSelection, filesSelectionArgs, filesOrderBy);

            Log.d("DEBUG_TAG", "ImageCursor Returned " + imageCursor.getCount() + " image files");

            final Uri imageThumbUri = MediaStore.Images.Thumbnails.getContentUri("external");
            Log.d("DEBUG_TAG", "ImageThumbnailsUri: " + imageThumbUri.toString());
            final String[] thumbColumns = {
                    MediaStore.Images.Thumbnails.IMAGE_ID,
                    MediaStore.Images.Thumbnails._ID,
                    MediaStore.Images.Thumbnails.KIND,
                    MediaStore.Images.Thumbnails.DATA
            };
            final String thumbSelection = MediaStore.Images.Thumbnails.KIND + " = ?";
            final String[] thumbSelectionArgs = {"" + MediaStore.Images.Thumbnails.MINI_KIND};
            final String thumbOrderBy = MediaStore.Images.Thumbnails.IMAGE_ID + " ASC";

            Cursor thumbCursor = getContext().getContentResolver().query(
                    imageThumbUri, thumbColumns,
                    thumbSelection, thumbSelectionArgs, thumbOrderBy);

            Log.d("DEBUG_TAG", "ThumbCursor Returned " + thumbCursor.getCount() + " thumb files");

            if ((imageCursor != null && imageCursor.getCount() > 0)) {

                CursorJoiner joiner = new CursorJoiner(imageCursor,
                        new String[]{MediaStore.Files.FileColumns._ID},
                        thumbCursor,
                        new String[]{MediaStore.Images.Thumbnails.IMAGE_ID});

                for (CursorJoiner.Result joinerResult : joiner) {
                    switch (joinerResult) {
                        case LEFT: {
                            MediaEntityWrapper tmpImgEntity = new MediaEntityWrapper();
                            tmpImgEntity.masterId = imageCursor.getString(imageCursor.getColumnIndex(MediaStore.Files.FileColumns._ID));
                            tmpImgEntity.parent = imageCursor.getString(imageCursor.getColumnIndex(MediaStore.Files.FileColumns.PARENT));
                            tmpImgEntity.mimeType = imageCursor.getString(imageCursor.getColumnIndex(MediaStore.Files.FileColumns.MIME_TYPE));
                            tmpImgEntity.masterDataPath = imageCursor.getString(imageCursor.getColumnIndex(MediaStore.Files.FileColumns.DATA));
                            entityList.add(tmpImgEntity);
                            break;
                        }
                        case RIGHT:
                            // handle case where a row in cursorB is unique
                            break;
                        case BOTH: {
                            // handle case where a row with the same key is in both cursors
                            MediaEntityWrapper tmpImgEntity = new MediaEntityWrapper();
                            tmpImgEntity.masterId = imageCursor.getString(imageCursor.getColumnIndex(MediaStore.Files.FileColumns._ID));
                            tmpImgEntity.parent = imageCursor.getString(imageCursor.getColumnIndex(MediaStore.Files.FileColumns.PARENT));
                            tmpImgEntity.mimeType = imageCursor.getString(imageCursor.getColumnIndex(MediaStore.Files.FileColumns.MIME_TYPE));
                            tmpImgEntity.masterDataPath = imageCursor.getString(imageCursor.getColumnIndex(MediaStore.Files.FileColumns.DATA));
                            tmpImgEntity.thumbId = thumbCursor.getString(thumbCursor.getColumnIndex(MediaStore.Images.Thumbnails._ID));
                            tmpImgEntity.thumbDataPath = thumbCursor.getString(thumbCursor.getColumnIndex(MediaStore.Images.Thumbnails.DATA));
                            entityList.add(tmpImgEntity);
                            break;
                        }
                    }
                }
                Log.d("DEBUG_TAG", "Created Cursor with " + entityList.size() + " images+thumb");
            }
            imageCursor.close();
            thumbCursor.close();

        } catch (Exception e) {
            e.printStackTrace();
        }

        Collections.reverse(entityList);
        return entityList;
    }

    /********************************************************/
    /** (2) Deliver the results to the registered listener **/
    /**
     * ****************************************************
     */

    public void deliverResult(List<MediaEntityWrapper> data) {
        if (isReset()) {
            // The Loader has been reset; ignore the result and invalidate the data.
            releaseResources(data);
            return;
        }

        // Hold a reference to the old data so it doesn't get garbage collected.
        // We must protect it until the new data has been delivered.
        List<MediaEntityWrapper> oldData = mData;
        mData = data;

        if (isStarted()) {
            // If the Loader is in a started state, deliver the results to the
            // client. The superclass method does this for us.
            super.deliverResult(data);
        }

        // Invalidate the old data as we don't need it any more.
        if (oldData != null && oldData != data) {
            releaseResources(oldData);
        }
    }

    /*********************************************************/
    /** (3) Implement the Loaders state-dependent behavior **/
    /**
     * ****************************************************
     */

    protected void onStartLoading() {
        if (mData != null) {
            // Deliver any previously loaded data immediately.
            deliverResult(mData);
        }

        // Begin monitoring the underlying data source.
        if (mObserver == null) {
            mObserver = new SampleObserver(new Handler());
            getContext().getContentResolver().registerContentObserver(MediaStore.Images.Media.getContentUri("external"), true, mObserver);
        }

        if (takeContentChanged() || mData == null) {
            // When the observer detects a change, it should call onContentChanged()
            // on the Loader, which will cause the next call to takeContentChanged()
            // to return true. If this is ever the case (or if the current data is
            // null), we force a new load.
            System.out.println("ImageBaseLoader.forceLoad called");
            forceLoad();
        }
    }

    protected void onStopLoading() {
        // The Loader is in a stopped state, so we should attempt to cancel the
        // current load (if there is one).
        cancelLoad();

        // Note that we leave the observer as is. Loaders in a stopped state
        // should still monitor the data source for changes so that the Loader
        // will know to force a new load if it is ever started again.
    }


    protected void onReset() {
        // Ensure the loader has been stopped.
        onStopLoading();

        // At this point we can release the resources associated with 'mData'.
        if (mData != null) {
            releaseResources(mData);
            mData = null;
        }

        // The Loader is being reset, so we should stop monitoring for changes.
        if (mObserver != null) {
            // TODO: unregister the observer
            getContext().getContentResolver().unregisterContentObserver(mObserver);
            mObserver = null;
        }
    }

    public void onCanceled(List<MediaEntityWrapper> data) {
        // Attempt to cancel the current asynchronous load.
        super.onCanceled(data);

        // The load has been canceled, so we should release the resources
        // associated with 'data'.
        releaseResources(data);
    }

    private void releaseResources(List<MediaEntityWrapper> data) {
        // For a simple List, there is nothing to do. For something like a Cursor, we
        // would close it in this method. All resources associated with the Loader
        // should be released here.
    }

    /*********************************************************************/
    /** (4) Observer which receives notifications when the data changes **/
    /**
     * ******************************************************************
     */

    //TODO Implement proper ContentObserver
    private class SampleObserver extends ContentObserver {
        public SampleObserver(Handler handler) {
            super(handler);
        }

        public void onChange(boolean selfChange) {
            super.onChange(selfChange);
            onContentChanged();
            System.out.println("SampleObserver.onChange fired");
        }
    }
}




Java Source Code List

com.urza.masterdetailtest.ApplicationTest.java
com.urza.mediapicker.CurrentSelectionFragment.java
com.urza.mediapicker.FolderBaseLoader.java
com.urza.mediapicker.FolderDetailFragment.java
com.urza.mediapicker.FolderListActivityFragmented.java
com.urza.mediapicker.FolderListFragment.java
com.urza.mediapicker.ImageBaseLoader.java
com.urza.mediapicker.MediaEntityAdapter.java
com.urza.mediapicker.MediaEntityBaseAdapter.java
com.urza.mediapicker.MediaEntityWrapper.java
com.urza.mediapicker.MediaFolderAdapter.java
com.urza.mediapicker.MediaFolder.java
com.urza.mediapicker.MultiPicker.java
com.urza.mediapicker.VideoBaseLoader.java