0

I want to get path from all images on phone. I used this code but that gives me every file that is in dcim/camera/ directory (it includes videos(.mp4) files which I don't want to get). I want to get path to image in every directory.

String targetPath = ExternalStorageDirectoryPath + "/DCIM/Camera/";

File targetDirector = new File(targetPath);

final File[] files = targetDirector.listFiles();
for (File file : files){
    // file is path to file
}
Yaroslav Admin
  • 13,880
  • 6
  • 63
  • 83
  • You'd have to do a recursive entry into every directory, sniffing out files with the appropriate extension (or metadata) if you want to use `File` and `listFiles`, since it only gives you the entries in the current directory. Something like [this answer](http://stackoverflow.com/a/11482350/410342) would help, but you have to make sure you run it in its own thread. – Shotgun Ninja Sep 28 '15 at 14:06

2 Answers2

2

For the purpose you will have to query the Media Store Content Provider. In my projects I use the following method to get the list with some other data associated with every image.

public static ArrayList<MediaStorePhoto> getAllPhotosFromExternalStorage(ContentResolver mContentResolver) {

    MediaStorePhoto photo;
    ArrayList<MediaStorePhoto> photoList = new ArrayList<>();

    // which image properties are we querying
    String[] projection = new String[]{
            MediaStore.Images.Media.BUCKET_ID,
            MediaStore.Images.Media.BUCKET_DISPLAY_NAME,
            MediaStore.Images.Media._ID,
            MediaStore.Images.Media.DATE_TAKEN,
            MediaStore.Images.Media.SIZE,
            MediaStore.Images.Media.DISPLAY_NAME,
            MediaStore.Images.Media.DATA
    };

    // content:// style URI for the "primary" external storage volume
    Uri images = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;

    // Make the query.
    Cursor cur = mContentResolver.query(images,
            projection, // Which columns to return
            null,       // Which rows to return (all rows)
            null,       // Selection arguments (none)
            null        // Ordering
    );

    Log.i("ListingImages", " query count=" + cur.getCount());

    if (cur.moveToFirst()) {
        String bucketId;
        long id;
        long size;
        String bucket;
        String date;
        String name;
        String dataUri;

        int bucketIdColumn = cur.getColumnIndex(
                MediaStore.Images.Media.BUCKET_ID);

        int idColumn = cur.getColumnIndex(
                MediaStore.Images.Media._ID);

        int bucketColumn = cur.getColumnIndex(
                MediaStore.Images.Media.BUCKET_DISPLAY_NAME);

        int dateColumn = cur.getColumnIndex(
                MediaStore.Images.Media.DATE_TAKEN);

        int sizeColumn = cur.getColumnIndex(
                MediaStore.Images.Media.SIZE);

        int nameColumn = cur.getColumnIndex(
                MediaStore.Images.Media.DISPLAY_NAME);

        int dataColumn = cur.getColumnIndex(
                MediaStore.Images.Media.DATA);
        do {
            // Get the field values
            bucketId = cur.getString(bucketIdColumn);
            bucket = cur.getString(bucketColumn);
            date = cur.getString(dateColumn);
            size = cur.getLong(sizeColumn);
            id = cur.getLong(idColumn);
            name = cur.getString(nameColumn);
            dataUri = cur.getString(dataColumn);

            // Store photo in Photo object
            photo = new MediaStorePhoto(String.valueOf(id), name,
                    bucket, date, String.valueOf(size), "null", dataUri, bucketId);

            // Add photo to photo list
            photoList.add(photo);
        } while (cur.moveToNext());

    }
    cur.close();
    return photoList;
} 

Note : Here MediaStorePhoto is a class that I made something like

public class MediaStorePhoto implements Parcelable {

    public static final Creator CREATOR = new Creator() {
        public MediaStorePhoto createFromParcel(Parcel in) {
            return new MediaStorePhoto(in);
        }

        public MediaStorePhoto[] newArray(int size) {
            return new MediaStorePhoto[size];
        }
    };
    private String id;
    private String displayName;
    private String bucket;
    private String date;
    private String size;
    private String status;
    private String dataUri;
    private String bucketId;

    public MediaStorePhoto(String id, String displayName, String bucket, String date, String size, String status, String dataUri, String bucketId) {
        this.id = id;
        this.displayName = displayName;
        ...
        ...
        this.bucketId = bucketId;
    }

    public MediaStorePhoto(Parcel in) {
        String[] data = new String[8];

        in.readStringArray(data);
        this.id = data[0];
        this.displayName = data[1];
        ...
        ...
        this.bucketId = data[7];
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeStringArray(new String[]{this.id,
                this.displayName,
                this.bucket,
                ...
                ...
                this.bucketId});
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    ...
    ...
    ...

    public String getBucketId() {
        return bucketId;
    }

    public void setBucketId(String bucketId) {
        this.bucketId = bucketId;
    }
}

So, the uri to the image will be in mediaStorePhoto.getDataUri() also mediaStorePhoto.getBucket() will get you the name of the directory.

Kushal Sharma
  • 5,978
  • 5
  • 25
  • 41
-1

Okay, what you have is a good start, but you need to change it up a little bit. First of all, in order to go through what could be a variable number of file paths, you need a recursive function that calls itself on a directory.

public void walk(File currDir, List<String> fileNames) {
    File[] list = null;
    try {
        list = currDir.listFiles();
    } catch (SecurityException e) {
        // Can't read this file, just do nothing.
        return;
    }
    File[] list = currDir.listFiles();
    for (File f : list) {
        if (f.isDirectory()) {
            walk(f, fileNames);
        } else {
            // Add only images with the extension "jpg" (substitute your own logic here if necessary)
            String fileName = f.getName();
            String extension = fileName.substring(fileName.lastIndexOf(".")+1);
            if ("jpg".equalsIgnoreCase(extension)) {
                fileNames.add(fileName);
            }
        }
    }
}

After you have this, all you need to do is call it on your current directory to start the chain. Note, however, that this may take a while, so you'll need to run this in a separate thread from your UI if you expect a lot of images.

List<String> files = new LinkedList<String>();
String targetPath = ExternalStorageDirectoryPath + "/DCIM/Camera/"; // TODO Change me as needed!
File targetDirectory = new File(targetPath);
walk(targetDirectory, files);

After this, files should have all JPG files in the given directory and all subdirectories.

Shotgun Ninja
  • 2,540
  • 3
  • 26
  • 32
  • I tried code and it finds all .jpg pictures but only in directory that is defined (/DCIM/Camera/), when u put only /DCIM/ it find .jpg files in that directory but i want it to look in every directory (dcim, images, pictures or any other directory). I tried to remove /dcim/camera/ and leave just ExternalStorageDirectoryPath but it crashed app. – Alen Genije Sep 29 '15 at 13:00
  • Yeah, first of all, of *course* it only checks in DCIM/Camera; that's the root path specified, and it won't go backwards from there. Second, you'd need to have exception handling around `listFiles()`, since you'd need to handle `SecurityException`s thrown by that method. – Shotgun Ninja Sep 29 '15 at 13:40
  • Also, have you tried using `ExternalStorageDirectoryPath + "/"`? – Shotgun Ninja Sep 29 '15 at 13:44
  • I tried your code and it doesnt work. I tried with ExternalStorageDirectoryPath + "/" and it gets .jpg images from sdcard but it doesnt search inside of other directoris (dcim/images/videos/....). – Alen Genije Oct 03 '15 at 15:12