init: avoid intermediate ImageEntry when fetching from MediaStore

This commit is contained in:
Thibault Deckers 2020-02-26 14:29:34 +09:00
parent e33b365c5d
commit a51ab4c07a
2 changed files with 32 additions and 75 deletions

View file

@ -5,7 +5,6 @@ import android.net.Uri;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import java.io.File; import java.io.File;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import deckers.thibault.aves.utils.Constants; import deckers.thibault.aves.utils.Constants;
@ -22,65 +21,23 @@ public class ImageEntry {
private long dateModifiedSecs, sourceDateTakenMillis; private long dateModifiedSecs, sourceDateTakenMillis;
private long durationMillis; private long durationMillis;
public ImageEntry(Uri uri, String mimeType) {
this.contentId = -1;
this.uri = uri;
this.mimeType = mimeType;
}
// uri: content provider uri // uri: content provider uri
// path: FileUtils.getPathFromUri(activity, itemUri) is useful (for Download, File, etc.) but is slower than directly using `MediaStore.MediaColumns.DATA` from the MediaStore query // path: FileUtils.getPathFromUri(activity, itemUri) is useful (for Download, File, etc.) but is slower than directly using `MediaStore.MediaColumns.DATA` from the MediaStore query
public ImageEntry(Uri uri, String path, long id, String mimeType, int width, int height, int orientationDegrees, long sizeBytes,
String title, long dateModifiedSecs, long dateTakenMillis, String bucketDisplayName, long durationMillis) {
this.uri = uri;
this.path = path;
this.contentId = id;
this.mimeType = mimeType;
this.width = width;
this.height = height;
this.orientationDegrees = orientationDegrees;
this.sizeBytes = sizeBytes;
this.title = title;
this.dateModifiedSecs = dateModifiedSecs;
this.sourceDateTakenMillis = dateTakenMillis;
this.bucketDisplayName = bucketDisplayName;
this.durationMillis = durationMillis;
}
public ImageEntry(Map map) { public ImageEntry(Map map) {
this( this.uri = Uri.parse((String) map.get("uri"));
Uri.parse((String) map.get("uri")), this.path = (String) map.get("path");
(String) map.get("path"), this.contentId = toLong(map.get("contentId"));
toLong(map.get("contentId")), this.mimeType = (String) map.get("mimeType");
(String) map.get("mimeType"), this.width = (int) map.get("width");
(int) map.get("width"), this.height = (int) map.get("height");
(int) map.get("height"), this.orientationDegrees = (int) map.get("orientationDegrees");
(int) map.get("orientationDegrees"), this.sizeBytes = toLong(map.get("sizeBytes"));
toLong(map.get("sizeBytes")), this.title = (String) map.get("title");
(String) map.get("title"), this.dateModifiedSecs = toLong(map.get("dateModifiedSecs"));
toLong(map.get("dateModifiedSecs")), this.sourceDateTakenMillis = toLong(map.get("sourceDateTakenMillis"));
toLong(map.get("sourceDateTakenMillis")), this.bucketDisplayName = (String) map.get("bucketDisplayName");
(String) map.get("bucketDisplayName"), this.durationMillis = toLong(map.get("durationMillis"));
toLong(map.get("durationMillis"))
);
}
public static Map toMap(ImageEntry entry) {
return new HashMap<String, Object>() {{
put("uri", entry.uri.toString());
put("path", entry.path);
put("contentId", entry.contentId);
put("mimeType", entry.mimeType);
put("width", entry.width);
put("height", entry.height);
put("orientationDegrees", entry.orientationDegrees);
put("sizeBytes", entry.sizeBytes);
put("title", entry.title);
put("dateModifiedSecs", entry.dateModifiedSecs);
put("sourceDateTakenMillis", entry.sourceDateTakenMillis);
put("bucketDisplayName", entry.bucketDisplayName);
put("durationMillis", entry.durationMillis);
}};
} }
public Uri getUri() { public Uri getUri() {

View file

@ -7,9 +7,9 @@ import android.net.Uri;
import android.provider.MediaStore; import android.provider.MediaStore;
import android.util.Log; import android.util.Log;
import java.util.HashMap;
import java.util.stream.Stream; import java.util.stream.Stream;
import deckers.thibault.aves.model.ImageEntry;
import deckers.thibault.aves.utils.Env; import deckers.thibault.aves.utils.Env;
import deckers.thibault.aves.utils.PermissionManager; import deckers.thibault.aves.utils.PermissionManager;
import deckers.thibault.aves.utils.StorageUtils; import deckers.thibault.aves.utils.StorageUtils;
@ -66,30 +66,30 @@ public class MediaStoreImageProvider extends ImageProvider {
while (cursor.moveToNext()) { while (cursor.moveToNext()) {
long contentId = cursor.getLong(idColumn); long contentId = cursor.getLong(idColumn);
Uri itemUri = ContentUris.withAppendedId(contentUri, contentId); Uri itemUri = ContentUris.withAppendedId(contentUri, contentId);
ImageEntry imageEntry = new ImageEntry( int width = cursor.getInt(widthColumn);
itemUri,
cursor.getString(pathColumn),
contentId,
cursor.getString(mimeTypeColumn),
cursor.getInt(widthColumn),
cursor.getInt(heightColumn),
cursor.getInt(orientationColumn),
cursor.getLong(sizeColumn),
cursor.getString(titleColumn),
cursor.getLong(dateModifiedColumn),
cursor.getLong(dateTakenColumn),
cursor.getString(bucketDisplayNameColumn),
durationColumn != -1 ? cursor.getLong(durationColumn) : 0
);
// TODO TLAD sanitize mimeType // TODO TLAD sanitize mimeType
// problem: some images were added as image/jpeg, but they're actually image/png // problem: some images were added as image/jpeg, but they're actually image/png
// possible solution: // possible solution:
// 1) check that MediaStore mimeType matches expected mimeType from file path extension // 1) check that MediaStore mimeType matches expected mimeType from file path extension
// 2) extract actual mimeType with metadata-extractor // 2) extract actual mimeType with metadata-extractor
// 3) update MediaStore // 3) update MediaStore
if (imageEntry.getWidth() > 0) { if (width > 0) {
// TODO TLAD avoid creating ImageEntry to convert it right after entrySink.success(
entrySink.success(ImageEntry.toMap(imageEntry)); new HashMap<String, Object>() {{
put("uri", itemUri.toString());
put("path", cursor.getString(pathColumn));
put("contentId", contentId);
put("mimeType", cursor.getString(mimeTypeColumn));
put("width", width);
put("height", cursor.getInt(heightColumn));
put("orientationDegrees", cursor.getInt(orientationColumn));
put("sizeBytes", cursor.getLong(sizeColumn));
put("title", cursor.getString(titleColumn));
put("dateModifiedSecs", cursor.getLong(dateModifiedColumn));
put("sourceDateTakenMillis", cursor.getLong(dateTakenColumn));
put("bucketDisplayName", cursor.getString(bucketDisplayNameColumn));
put("durationMillis", durationColumn != -1 ? cursor.getLong(durationColumn) : 0);
}});
// } else { // } else {
// // some images are incorrectly registered in the MediaStore, // // some images are incorrectly registered in the MediaStore,
// // they are valid but miss some attributes, such as width, height, orientation // // they are valid but miss some attributes, such as width, height, orientation