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;
}
}