Android - Saving images to gallery in loop Mixes up the order

Viewed 35

I'm saving some images to gallery in a loop using the code below. However, the images do not keep their order when I view them in the Photos app. The order is all mixed up. I have added the meta data MediaStore.Images.Media.DATE_ADDED and .DATE_TAKEN as per some of the answers on SO but that does not help.

E.g. if they are total 4 images, the gallery should show images in order, i = [3], [2], [1] & [0]. Instead the actual order is mixed up and would be like [2], [3], [1], [0].

To be fair, the meta data does put the images at the top of gallery, just not in expected order.

EDIT: I think I know the cause of the problem. Google Photos sorts images based on .DATA_ADDED value but that value has to be in seconds, not milliseconds. Multiple images get inserted in gallery within the same second as they are in a loop, so the .DATA_ADDED timestamp is same for them and the Photos app doesn't how to sort them anymore.

So the question now is how can I keep them in order if I can only specify in DATE_ADDED in seconds and not milliseconds?

/// AsyncTask
@Override
        protected Uri doInBackground(Void... voids) {
            Uri result = null;
            for (int i = 0; i < bitmaps.size(); i++) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                    try {
                        result = saveBitmapNew(MainActivity.this, bitmaps.get(i));
                    catch (IOException e) {
                        e.printStackTrace();
                    }    
            }
            return result;
        }


@RequiresApi(api = Build.VERSION_CODES.Q)
    public Uri saveBitmapNew(@NonNull final Context context, @NonNull final Bitmap bitmap) throws IOException {
        final long currentMillis = System.currentTimeMillis();
        final String relativeLocation = Environment.DIRECTORY_PICTURES + File.separator + FOLDER_NAME;

        final ContentValues values = new ContentValues();
        values.put(MediaStore.Images.Media.TITLE, Long.toString(currentMillis));
        values.put(MediaStore.Images.Media.DISPLAY_NAME, Long.toString(currentMillis));
        values.put(MediaStore.Images.Media.DESCRIPTION, Long.toString(currentMillis));
        values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
        // Add the date meta data to ensure the image is added at the front of the gallery
        values.put(MediaStore.Images.Media.DATE_ADDED, currentMillis / 1000);
        values.put(MediaStore.Images.Media.DATE_TAKEN, currentMillis);
        values.put(MediaStore.Images.Media.RELATIVE_PATH, relativeLocation);


        final ContentResolver resolver = context.getContentResolver();
        Uri uri = null;

        try {
            final Uri contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
            uri = resolver.insert(contentUri, values);

            if (uri == null)
                throw new IOException("Failed to create new MediaStore record.");

            try (final OutputStream stream = resolver.openOutputStream(uri)) {
                if (stream == null)
                    throw new IOException("Failed to open output stream.");

                if (!bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream))
                    throw new IOException("Failed to save bitmap.");

            }

            return uri;
        } catch (IOException e) {
            if (uri != null) {
                // Don't leave an orphan entry in the MediaStore
                resolver.delete(uri, null, null);
            }
            throw e;
        }
    }
0 Answers
Related