9

I'm using following code to open a gallery inside of my app

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, FIND_RESULT);

Is it possible to limit a list of images to only show images taken by camera? Viewing Gallery on my 2.1 system, images are grouped so there has to be a parameter that defines to which folder it belongs.

Checking the MediaStore.Images.ImageColumns I did not a find any column that would define such thing.

Could I be wrong? Because if I could create a query to filter by folder and create my own gallery view, then my problem would be solved.

FrEaKmAn
  • 1,785
  • 1
  • 21
  • 47

5 Answers5

8

You just need to implement MediaScannerConnectionClient in your activity and after that you have to give the exact path of one of the file inside that folder name here as SCAN_PATH and it will scan all the files containing in that folder and open it inside built in gallery. So just give the name of you folder and you will get all the files inside including video. If you want to open only images change FILE_TYPE="image/*"

public class SlideShow extends Activity implements MediaScannerConnectionClient {

        public String[] allFiles;
        private String SCAN_PATH ;
        private static final String FILE_TYPE = "*/*";
        private MediaScannerConnection conn;

        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);

            setContentView(R.layout.main);

            File folder = new File("/sdcard/yourfoldername/");
            allFiles = folder.list();

            SCAN_PATH=Environment.getExternalStorageDirectory().toString()+"/yourfoldername/"+allFiles[0];

            Button scanBtn = (Button) findViewById(R.id.scanBtn);
            scanBtn.setOnClickListener(new OnClickListener()
            {
                public void onClick(View v)
                {
                    startScan();
                }
            });
        }

        private void startScan()
        {
            if(conn!=null)
            {
                conn.disconnect();
            }

            conn = new MediaScannerConnection(this, this);
            conn.connect();
        }


        public void onMediaScannerConnected()
        {
            conn.scanFile(SCAN_PATH, FILE_TYPE);    
        }


        public void onScanCompleted(String path, Uri uri)
        {
            try
            {
                if (uri != null) 
                {
                    Intent intent = new Intent(Intent.ACTION_VIEW);
                    intent.setData(uri);
                    startActivity(intent);
                }
            }
            finally 
            {
                conn.disconnect();
                conn = null;
            }
        }
    }
PiyushMishra
  • 5,743
  • 6
  • 37
  • 57
  • it will show one image at a time why? like i have 6 images in the folder & if i write allFiles[0] it will show 1 image,then i write allFiles[1] it will show 2 image & so on. But i want to show all the images at one time. – Amandeep singh Mar 06 '12 at 04:08
  • you need gallery aman to show all images at a time this example didnt tell anywhere how to show ur data, it just create an array of string containing path of all the files inside that folder. You can use this array of strings in ur gallary to display ur images. – PiyushMishra Mar 06 '12 at 07:03
  • This open the specific image not the folder in gallery – Muhammad Hamza Shahid Apr 08 '16 at 04:57
5

None of the above answers are correct, including the one marked as correct.

Here's the actual correct solution:

The secret is finding the bucket/album your folder is represented as. Buckets show up after a successful MediaScan so be sure any images/videos you want to show are first scanned as demonstrated multiple times above.

Let's assume I have an indexed folder in /sdcard/myapp/myappsmediafolder:

String bucketId = "";

final String[] projection = new String[] {"DISTINCT " + MediaStore.Images.Media.BUCKET_DISPLAY_NAME + ", " + MediaStore.Images.Media.BUCKET_ID};
final Cursor cur = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection, null, null, null);

while (cur != null && cur.moveToNext()) {
    final String bucketName = cur.getString((cur.getColumnIndex(MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME)));
    if (bucketName.equals("myappsmediafolder")) {
        bucketId = cur.getString((cur.getColumnIndex(MediaStore.Images.ImageColumns.BUCKET_ID)));
        break;
    }
}

Now that we have the bucketId for our album we can open it with a simple intent.

Filters Video files:

Uri mediaUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;

Filters Image files:

Uri mediaUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;

...

if (bucketId.length() > 0) {
    mediaUri = mediaUri.buildUpon()
            .authority("media")
            .appendQueryParameter("bucketId", bucketId)
            .build();
}

Intent intent = new Intent(Intent.ACTION_VIEW, mediaUri);
startActivity(intent);

I can verify this works with the built-in Gallery app. Mileage may vary with other apps such as Google Photos.

I have yet to figure out how not to filter images/video, even though within Gallery you can select a specific Album with no filter.

I figured this out by looking at the AOSP source to the gallery app.

ShellDude
  • 579
  • 6
  • 12
  • I upvoted already. This solution worked perfectly for up to API 5. But for API 6 it shows only 1 photo. I have to scroll to move to next photo. How to make make it work for API 6? Please let me know. Thanks! – masiboo Jul 28 '17 at 08:56
  • Is their any way to get combine folder names for images and videos in same cursor? – Harsh Bhavsar Nov 09 '17 at 09:28
  • Any idea on how to implement it on older APIs? `Field requires API level 29: android.provider.MediaStore.MediaColumns#BUCKET_DISPLAY_NAME` – Pat Lee Apr 26 '21 at 10:47
1

I don't have enough reputation to upvote or comment on his answer but ShellDude's answer allows you to put a directory URI in the gallery intent. So when the gallery app is opened it displays all of the images instead of 1.

For me, scanning my files like the answers above did not work. Querying the MediaStore.Images.Media.EXTERNAL_CONTENT_URI only worked after inserting new rows into the MediaStore.Images.Media.DATA table with the ContentResolver:

ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DATA, image.getPath());  
values.put(MediaStore.Images.Media.MIME_TYPE,"image/jpeg");
contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
ajplumlee33
  • 321
  • 3
  • 6
  • odd, as i would have expected a mediascan to do the above for you. is there a .nomedia file or similar in the path to your folder? – ShellDude Jul 09 '16 at 04:18
0

Here is a simplified one

private  MediaScannerConnection conn;
private void notifySystemWithImage(final File imageFile) {

        conn = new MediaScannerConnection(this, new MediaScannerConnectionClient() {

        @Override
        public void onScanCompleted(String path, Uri uri) {

            try {
                if (uri != null) {
                    Intent intent = new Intent(Intent.ACTION_VIEW);
                    intent.setDataAndType(uri, "image/*");
                    startActivity(intent);
                }
            } finally {
                conn.disconnect();
                conn = null;
            }
        }

        @Override
        public void onMediaScannerConnected() {
            conn.scanFile(imageFile.getAbsolutePath(), "*/*"); 

        }
    });

        conn.connect();
}
Simon K. Gerges
  • 3,097
  • 36
  • 34
0

For those who this still give activity not found exception:

You need to specify directory of your inner application folder. Not user default root if images and everything.

public class SlideShow extends Activity implements MediaScannerConnectionClient {

        public String[] allFiles;
        private String SCAN_PATH ;
        private static final String FILE_TYPE = "*/*";
        private MediaScannerConnection conn;

        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);

            setContentView(R.layout.main);

            File folder = new File(HistoryActivity.this.getExternalFilesDir(null)+"/a/");
            allFiles = folder.list();

            SCAN_PATH= HistoryActivity.this.getExternalFilesDir(null)+"/a/"+allFiles[0];

            Button scanBtn = (Button) findViewById(R.id.scanBtn);
            scanBtn.setOnClickListener(new OnClickListener()
            {
                public void onClick(View v)
                {
                    startScan();
                }
            });
        }

        private void startScan()
        {
            if(conn!=null)
            {
                conn.disconnect();
            }

            conn = new MediaScannerConnection(this, this);
            conn.connect();
        }


        public void onMediaScannerConnected()
        {
            conn.scanFile(SCAN_PATH, FILE_TYPE);    
        }


        public void onScanCompleted(String path, Uri uri)
        {
            try
            {
                if (uri != null) 
                {
                    Intent intent = new Intent(Intent.ACTION_VIEW);
                    intent.setData(uri);
                    startActivity(intent);
                }
            }
            finally 
            {
                conn.disconnect();
                conn = null;
            }
        }
    }

works... but kitkat show only one photo. I managed to fix it for earlier versions with (updating gallery, when storing image):

public void savePhoto(Bitmap bmp)
{
    File imageFileFolder = new File(context.getExternalFilesDir(null)+"/a/") ;
    imageFileFolder.mkdir();
    FileOutputStream out = null;
    Calendar c = Calendar.getInstance();
    String date = fromInt(c.get(Calendar.MONTH))
            + fromInt(c.get(Calendar.DAY_OF_MONTH))
            + fromInt(c.get(Calendar.YEAR))
            + fromInt(c.get(Calendar.HOUR_OF_DAY))
            + fromInt(c.get(Calendar.MINUTE))
            + fromInt(c.get(Calendar.SECOND));
    File imageFileName = new File(imageFileFolder, date.toString() + ".jpg");
    try
    {
        out = new FileOutputStream(imageFileName);
        bmp.compress(Bitmap.CompressFormat.JPEG, 100, out);
        out.flush();
        out.close();
        scanPhoto(imageFileName.toString());
        out = null;
    } catch (Exception e)
    {
        e.printStackTrace();
    }
}


public String fromInt(int val)
{
    return String.valueOf(val);
}


public void scanPhoto(final String imageFileName)
{
    msConn = new MediaScannerConnection(context,new MediaScannerConnection.MediaScannerConnectionClient()
    {
        public void onMediaScannerConnected()
        {
            msConn.scanFile(imageFileName, null);
            Log.i("msClient obj  in Photo Utility", "connection established");
        }
        public void onScanCompleted(String path, Uri uri)
        {
            msConn.disconnect();
            Log.i("msClient obj in Photo Utility","scan completed");
        }
    });
    msConn.connect();
}
sanevys
  • 559
  • 1
  • 7
  • 27