read files with uri only, and fix to handle unknown MediaMetadataRetriever issues
This commit is contained in:
parent
cbacb923e7
commit
a6eeba7744
6 changed files with 36 additions and 59 deletions
|
@ -8,6 +8,7 @@ import android.content.pm.PackageManager;
|
||||||
import android.content.pm.ResolveInfo;
|
import android.content.pm.ResolveInfo;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
@ -29,12 +30,15 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import deckers.thibault.aves.utils.Utils;
|
||||||
import io.flutter.plugin.common.MethodCall;
|
import io.flutter.plugin.common.MethodCall;
|
||||||
import io.flutter.plugin.common.MethodChannel;
|
import io.flutter.plugin.common.MethodChannel;
|
||||||
|
|
||||||
import static com.bumptech.glide.request.RequestOptions.centerCropTransform;
|
import static com.bumptech.glide.request.RequestOptions.centerCropTransform;
|
||||||
|
|
||||||
public class AppAdapterHandler implements MethodChannel.MethodCallHandler {
|
public class AppAdapterHandler implements MethodChannel.MethodCallHandler {
|
||||||
|
private static final String LOG_TAG = Utils.createLogTag(AppAdapterHandler.class);
|
||||||
|
|
||||||
public static final String CHANNEL = "deckers.thibault/aves/app";
|
public static final String CHANNEL = "deckers.thibault/aves/app";
|
||||||
|
|
||||||
private Context context;
|
private Context context;
|
||||||
|
@ -162,11 +166,11 @@ public class AppAdapterHandler implements MethodChannel.MethodCallHandler {
|
||||||
data = stream.toByteArray();
|
data = stream.toByteArray();
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
Log.w(LOG_TAG, "failed to decode app icon for packageName=" + packageName, e);
|
||||||
}
|
}
|
||||||
Glide.with(context).clear(target);
|
Glide.with(context).clear(target);
|
||||||
} catch (PackageManager.NameNotFoundException e) {
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
e.printStackTrace();
|
Log.w(LOG_TAG, "failed to get app info for packageName=" + packageName, e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
|
|
|
@ -8,6 +8,7 @@ import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.provider.MediaStore;
|
import android.provider.MediaStore;
|
||||||
import android.text.format.Formatter;
|
import android.text.format.Formatter;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
@ -30,7 +31,6 @@ import com.drew.metadata.gif.GifAnimationDirectory;
|
||||||
import com.drew.metadata.webp.WebpDirectory;
|
import com.drew.metadata.webp.WebpDirectory;
|
||||||
import com.drew.metadata.xmp.XmpDirectory;
|
import com.drew.metadata.xmp.XmpDirectory;
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -42,10 +42,13 @@ import deckers.thibault.aves.utils.Constants;
|
||||||
import deckers.thibault.aves.utils.MetadataHelper;
|
import deckers.thibault.aves.utils.MetadataHelper;
|
||||||
import deckers.thibault.aves.utils.MimeTypes;
|
import deckers.thibault.aves.utils.MimeTypes;
|
||||||
import deckers.thibault.aves.utils.StorageUtils;
|
import deckers.thibault.aves.utils.StorageUtils;
|
||||||
|
import deckers.thibault.aves.utils.Utils;
|
||||||
import io.flutter.plugin.common.MethodCall;
|
import io.flutter.plugin.common.MethodCall;
|
||||||
import io.flutter.plugin.common.MethodChannel;
|
import io.flutter.plugin.common.MethodChannel;
|
||||||
|
|
||||||
public class MetadataHandler implements MethodChannel.MethodCallHandler {
|
public class MetadataHandler implements MethodChannel.MethodCallHandler {
|
||||||
|
private static final String LOG_TAG = Utils.createLogTag(MetadataHandler.class);
|
||||||
|
|
||||||
public static final String CHANNEL = "deckers.thibault/aves/metadata";
|
public static final String CHANNEL = "deckers.thibault/aves/metadata";
|
||||||
|
|
||||||
// catalog metadata
|
// catalog metadata
|
||||||
|
@ -105,12 +108,11 @@ public class MetadataHandler implements MethodChannel.MethodCallHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getAllMetadata(MethodCall call, MethodChannel.Result result) {
|
private void getAllMetadata(MethodCall call, MethodChannel.Result result) {
|
||||||
String path = call.argument("path");
|
|
||||||
String uri = call.argument("uri");
|
String uri = call.argument("uri");
|
||||||
|
|
||||||
Map<String, Map<String, String>> metadataMap = new HashMap<>();
|
Map<String, Map<String, String>> metadataMap = new HashMap<>();
|
||||||
|
|
||||||
try (InputStream is = StorageUtils.openInputStream(context, Uri.parse(uri), path)) {
|
try (InputStream is = StorageUtils.openInputStream(context, Uri.parse(uri))) {
|
||||||
Metadata metadata = ImageMetadataReader.readMetadata(is);
|
Metadata metadata = ImageMetadataReader.readMetadata(is);
|
||||||
for (Directory dir : metadata.getDirectories()) {
|
for (Directory dir : metadata.getDirectories()) {
|
||||||
if (dir.getTagCount() > 0) {
|
if (dir.getTagCount() > 0) {
|
||||||
|
@ -136,7 +138,7 @@ public class MetadataHandler implements MethodChannel.MethodCallHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (XMPException e) {
|
} catch (XMPException e) {
|
||||||
e.printStackTrace();
|
Log.w(LOG_TAG, "failed to read XMP directory for uri=" + uri, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -144,15 +146,12 @@ public class MetadataHandler implements MethodChannel.MethodCallHandler {
|
||||||
result.success(metadataMap);
|
result.success(metadataMap);
|
||||||
} catch (ImageProcessingException e) {
|
} catch (ImageProcessingException e) {
|
||||||
getAllVideoMetadataFallback(call, result);
|
getAllVideoMetadataFallback(call, result);
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
result.error("getAllMetadata-filenotfound", "failed to get metadata for uri=" + uri + ", path=" + path, e.getMessage());
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
result.error("getAllMetadata-exception", "failed to get metadata for uri=" + uri + ", path=" + path, e.getMessage());
|
result.error("getAllMetadata-exception", "failed to get metadata for uri=" + uri, e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getAllVideoMetadataFallback(MethodCall call, MethodChannel.Result result) {
|
private void getAllVideoMetadataFallback(MethodCall call, MethodChannel.Result result) {
|
||||||
String path = call.argument("path");
|
|
||||||
String uri = call.argument("uri");
|
String uri = call.argument("uri");
|
||||||
|
|
||||||
Map<String, Map<String, String>> metadataMap = new HashMap<>();
|
Map<String, Map<String, String>> metadataMap = new HashMap<>();
|
||||||
|
@ -160,7 +159,7 @@ public class MetadataHandler implements MethodChannel.MethodCallHandler {
|
||||||
// unnamed fallback directory
|
// unnamed fallback directory
|
||||||
metadataMap.put("", dirMap);
|
metadataMap.put("", dirMap);
|
||||||
|
|
||||||
MediaMetadataRetriever retriever = StorageUtils.openMetadataRetriever(context, Uri.parse(uri), path);
|
MediaMetadataRetriever retriever = StorageUtils.openMetadataRetriever(context, Uri.parse(uri));
|
||||||
try {
|
try {
|
||||||
for (Map.Entry<Integer, String> kv : Constants.MEDIA_METADATA_KEYS.entrySet()) {
|
for (Map.Entry<Integer, String> kv : Constants.MEDIA_METADATA_KEYS.entrySet()) {
|
||||||
Integer key = kv.getKey();
|
Integer key = kv.getKey();
|
||||||
|
@ -179,7 +178,7 @@ public class MetadataHandler implements MethodChannel.MethodCallHandler {
|
||||||
}
|
}
|
||||||
result.success(metadataMap);
|
result.success(metadataMap);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
result.error("getAllVideoMetadataFallback-exception", "failed to get metadata for uri=" + uri + ", path=" + path, e.getMessage());
|
result.error("getAllVideoMetadataFallback-exception", "failed to get metadata for uri=" + uri, e.getMessage());
|
||||||
} finally {
|
} finally {
|
||||||
// cannot rely on `MediaMetadataRetriever` being `AutoCloseable` on older APIs
|
// cannot rely on `MediaMetadataRetriever` being `AutoCloseable` on older APIs
|
||||||
retriever.release();
|
retriever.release();
|
||||||
|
@ -188,12 +187,11 @@ public class MetadataHandler implements MethodChannel.MethodCallHandler {
|
||||||
|
|
||||||
private void getCatalogMetadata(MethodCall call, MethodChannel.Result result) {
|
private void getCatalogMetadata(MethodCall call, MethodChannel.Result result) {
|
||||||
String mimeType = call.argument("mimeType");
|
String mimeType = call.argument("mimeType");
|
||||||
String path = call.argument("path");
|
|
||||||
String uri = call.argument("uri");
|
String uri = call.argument("uri");
|
||||||
|
|
||||||
Map<String, Object> metadataMap = new HashMap<>();
|
Map<String, Object> metadataMap = new HashMap<>();
|
||||||
|
|
||||||
try (InputStream is = StorageUtils.openInputStream(context, Uri.parse(uri), path)) {
|
try (InputStream is = StorageUtils.openInputStream(context, Uri.parse(uri))) {
|
||||||
if (!MimeTypes.MP2T.equals(mimeType)) {
|
if (!MimeTypes.MP2T.equals(mimeType)) {
|
||||||
Metadata metadata = ImageMetadataReader.readMetadata(is);
|
Metadata metadata = ImageMetadataReader.readMetadata(is);
|
||||||
|
|
||||||
|
@ -233,7 +231,7 @@ public class MetadataHandler implements MethodChannel.MethodCallHandler {
|
||||||
putLocalizedTextFromXmp(metadataMap, KEY_XMP_TITLE_DESCRIPTION, xmpMeta, XMP_DESCRIPTION_PROP_NAME);
|
putLocalizedTextFromXmp(metadataMap, KEY_XMP_TITLE_DESCRIPTION, xmpMeta, XMP_DESCRIPTION_PROP_NAME);
|
||||||
}
|
}
|
||||||
} catch (XMPException e) {
|
} catch (XMPException e) {
|
||||||
e.printStackTrace();
|
Log.w(LOG_TAG, "failed to read XMP directory for uri=" + uri, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,7 +249,7 @@ public class MetadataHandler implements MethodChannel.MethodCallHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isVideo(mimeType)) {
|
if (isVideo(mimeType)) {
|
||||||
MediaMetadataRetriever retriever = StorageUtils.openMetadataRetriever(context, Uri.parse(uri), path);
|
MediaMetadataRetriever retriever = StorageUtils.openMetadataRetriever(context, Uri.parse(uri));
|
||||||
try {
|
try {
|
||||||
String dateString = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DATE);
|
String dateString = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DATE);
|
||||||
String rotationString = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION);
|
String rotationString = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION);
|
||||||
|
@ -287,25 +285,20 @@ public class MetadataHandler implements MethodChannel.MethodCallHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
result.error("getCatalogMetadata-exception", "failed to get video metadata for uri=" + uri + ", path=" + path, e.getMessage());
|
result.error("getCatalogMetadata-exception", "failed to get video metadata for uri=" + uri, e.getMessage());
|
||||||
} finally {
|
} finally {
|
||||||
// cannot rely on `MediaMetadataRetriever` being `AutoCloseable` on older APIs
|
// cannot rely on `MediaMetadataRetriever` being `AutoCloseable` on older APIs
|
||||||
retriever.release();
|
retriever.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result.success(metadataMap);
|
result.success(metadataMap);
|
||||||
} catch (ImageProcessingException e) {
|
|
||||||
result.error("getCatalogMetadata-imageprocessing", "failed to get metadata for uri=" + uri + ", path=" + path, e.getMessage());
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
result.error("getCatalogMetadata-filenotfound", "failed to get metadata for uri=" + uri + ", path=" + path, e.getMessage());
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
result.error("getCatalogMetadata-exception", "failed to get metadata for uri=" + uri + ", path=" + path, e.getMessage());
|
result.error("getCatalogMetadata-exception", "failed to get metadata for uri=" + uri, e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getOverlayMetadata(MethodCall call, MethodChannel.Result result) {
|
private void getOverlayMetadata(MethodCall call, MethodChannel.Result result) {
|
||||||
String mimeType = call.argument("mimeType");
|
String mimeType = call.argument("mimeType");
|
||||||
String path = call.argument("path");
|
|
||||||
String uri = call.argument("uri");
|
String uri = call.argument("uri");
|
||||||
|
|
||||||
Map<String, Object> metadataMap = new HashMap<>();
|
Map<String, Object> metadataMap = new HashMap<>();
|
||||||
|
@ -315,7 +308,7 @@ public class MetadataHandler implements MethodChannel.MethodCallHandler {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try (InputStream is = StorageUtils.openInputStream(context, Uri.parse(uri), path)) {
|
try (InputStream is = StorageUtils.openInputStream(context, Uri.parse(uri))) {
|
||||||
Metadata metadata = ImageMetadataReader.readMetadata(is);
|
Metadata metadata = ImageMetadataReader.readMetadata(is);
|
||||||
ExifSubIFDDirectory directory = metadata.getFirstDirectoryOfType(ExifSubIFDDirectory.class);
|
ExifSubIFDDirectory directory = metadata.getFirstDirectoryOfType(ExifSubIFDDirectory.class);
|
||||||
if (directory != null) {
|
if (directory != null) {
|
||||||
|
@ -327,12 +320,8 @@ public class MetadataHandler implements MethodChannel.MethodCallHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result.success(metadataMap);
|
result.success(metadataMap);
|
||||||
} catch (ImageProcessingException e) {
|
|
||||||
result.error("getOverlayMetadata-imageprocessing", "failed to get metadata for uri=" + uri + ", path=" + path, e.getMessage());
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
result.error("getOverlayMetadata-filenotfound", "failed to get metadata for uri=" + uri + ", path=" + path, e.getMessage());
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
result.error("getOverlayMetadata-exception", "failed to get metadata for uri=" + uri + ", path=" + path, e.getMessage());
|
result.error("getOverlayMetadata-exception", "failed to get metadata for uri=" + uri, e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ class VideoThumbnailFetcher implements DataFetcher<InputStream> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void loadData(@NonNull Priority priority, @NonNull DataCallback<? super InputStream> callback) {
|
public void loadData(@NonNull Priority priority, @NonNull DataCallback<? super InputStream> callback) {
|
||||||
MediaMetadataRetriever retriever = StorageUtils.openMetadataRetriever(model.getContext(), model.getUri(), null);
|
MediaMetadataRetriever retriever = StorageUtils.openMetadataRetriever(model.getContext(), model.getUri());
|
||||||
try {
|
try {
|
||||||
byte[] picture = retriever.getEmbeddedPicture();
|
byte[] picture = retriever.getEmbeddedPicture();
|
||||||
if (picture != null) {
|
if (picture != null) {
|
||||||
|
|
|
@ -119,7 +119,7 @@ public class ImageEntry {
|
||||||
|
|
||||||
// metadata retrieval
|
// metadata retrieval
|
||||||
|
|
||||||
// expects entry with: uri/path, mimeType
|
// expects entry with: uri, mimeType
|
||||||
// finds: width, height, orientation/rotation, date, title, duration
|
// finds: width, height, orientation/rotation, date, title, duration
|
||||||
public ImageEntry fillPreCatalogMetadata(Context context) {
|
public ImageEntry fillPreCatalogMetadata(Context context) {
|
||||||
fillByMediaMetadataRetriever(context);
|
fillByMediaMetadataRetriever(context);
|
||||||
|
@ -130,10 +130,10 @@ public class ImageEntry {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// expects entry with: uri/path, mimeType
|
// expects entry with: uri, mimeType
|
||||||
// finds: width, height, orientation/rotation, date, title, duration
|
// finds: width, height, orientation/rotation, date, title, duration
|
||||||
private void fillByMediaMetadataRetriever(Context context) {
|
private void fillByMediaMetadataRetriever(Context context) {
|
||||||
MediaMetadataRetriever retriever = StorageUtils.openMetadataRetriever(context, uri, path);
|
MediaMetadataRetriever retriever = StorageUtils.openMetadataRetriever(context, uri);
|
||||||
try {
|
try {
|
||||||
String width = null, height = null, rotation = null, durationMillis = null;
|
String width = null, height = null, rotation = null, durationMillis = null;
|
||||||
if (isImage()) {
|
if (isImage()) {
|
||||||
|
@ -180,12 +180,12 @@ public class ImageEntry {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// expects entry with: uri/path, mimeType
|
// expects entry with: uri, mimeType
|
||||||
// finds: width, height, orientation, date
|
// finds: width, height, orientation, date
|
||||||
private void fillByMetadataExtractor(Context context) {
|
private void fillByMetadataExtractor(Context context) {
|
||||||
if (MimeTypes.SVG.equals(mimeType)) return;
|
if (MimeTypes.SVG.equals(mimeType)) return;
|
||||||
|
|
||||||
try (InputStream is = StorageUtils.openInputStream(context, uri, path)) {
|
try (InputStream is = StorageUtils.openInputStream(context, uri)) {
|
||||||
Metadata metadata = ImageMetadataReader.readMetadata(is);
|
Metadata metadata = ImageMetadataReader.readMetadata(is);
|
||||||
|
|
||||||
if (MimeTypes.JPEG.equals(mimeType)) {
|
if (MimeTypes.JPEG.equals(mimeType)) {
|
||||||
|
@ -242,12 +242,12 @@ public class ImageEntry {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// expects entry with: uri/path
|
// expects entry with: uri
|
||||||
// finds: width, height
|
// finds: width, height
|
||||||
private void fillByBitmapDecode(Context context) {
|
private void fillByBitmapDecode(Context context) {
|
||||||
if (MimeTypes.SVG.equals(mimeType)) return;
|
if (MimeTypes.SVG.equals(mimeType)) return;
|
||||||
|
|
||||||
try (InputStream is = StorageUtils.openInputStream(context, uri, path)) {
|
try (InputStream is = StorageUtils.openInputStream(context, uri)) {
|
||||||
BitmapFactory.Options options = new BitmapFactory.Options();
|
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||||
options.inJustDecodeBounds = true;
|
options.inJustDecodeBounds = true;
|
||||||
BitmapFactory.decodeStream(is, null, options);
|
BitmapFactory.decodeStream(is, null, options);
|
||||||
|
|
|
@ -42,41 +42,28 @@ public class StorageUtils {
|
||||||
return uri != null && ContentResolver.SCHEME_CONTENT.equalsIgnoreCase(uri.getScheme()) && MediaStore.AUTHORITY.equalsIgnoreCase(uri.getHost());
|
return uri != null && ContentResolver.SCHEME_CONTENT.equalsIgnoreCase(uri.getScheme()) && MediaStore.AUTHORITY.equalsIgnoreCase(uri.getHost());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static InputStream openInputStream(Context context, Uri uri, String path) throws FileNotFoundException {
|
public static InputStream openInputStream(Context context, Uri uri) throws FileNotFoundException {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
// we get a permission denial if we require original from a provider other than the media store
|
// we get a permission denial if we require original from a provider other than the media store
|
||||||
if (isMediaStoreContentUri(uri)) {
|
if (isMediaStoreContentUri(uri)) {
|
||||||
uri = MediaStore.setRequireOriginal(uri);
|
uri = MediaStore.setRequireOriginal(uri);
|
||||||
}
|
}
|
||||||
return context.getContentResolver().openInputStream(uri);
|
|
||||||
}
|
}
|
||||||
|
return context.getContentResolver().openInputStream(uri);
|
||||||
// on Android <Q, we directly work with file paths if possible,
|
|
||||||
// as `FileInputStream` is faster than input stream from `ContentResolver`
|
|
||||||
return path != null ? new FileInputStream(path) : context.getContentResolver().openInputStream(uri);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MediaMetadataRetriever openMetadataRetriever(Context context, Uri uri, String path) {
|
public static MediaMetadataRetriever openMetadataRetriever(Context context, Uri uri) {
|
||||||
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
|
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
// we get a permission denial if we require original from a provider other than the media store
|
// we get a permission denial if we require original from a provider other than the media store
|
||||||
if (isMediaStoreContentUri(uri)) {
|
if (isMediaStoreContentUri(uri)) {
|
||||||
uri = MediaStore.setRequireOriginal(uri);
|
uri = MediaStore.setRequireOriginal(uri);
|
||||||
}
|
}
|
||||||
retriever.setDataSource(context, uri);
|
|
||||||
return retriever;
|
|
||||||
}
|
}
|
||||||
|
retriever.setDataSource(context, uri);
|
||||||
// on Android <Q, we directly work with file paths if possible
|
} catch (Exception e) {
|
||||||
if (path != null) {
|
Log.w(LOG_TAG, "failed to open MediaMetadataRetriever for uri=" + uri, e);
|
||||||
retriever.setDataSource(path);
|
|
||||||
} else {
|
|
||||||
retriever.setDataSource(context, uri);
|
|
||||||
}
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
Log.w(LOG_TAG, "failed to open MediaMetadataRetriever for uri=" + uri + ", path=" + path);
|
|
||||||
}
|
}
|
||||||
return retriever;
|
return retriever;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@ class MetadataService {
|
||||||
try {
|
try {
|
||||||
final result = await platform.invokeMethod('getAllMetadata', <String, dynamic>{
|
final result = await platform.invokeMethod('getAllMetadata', <String, dynamic>{
|
||||||
'mimeType': entry.mimeType,
|
'mimeType': entry.mimeType,
|
||||||
'path': entry.path,
|
|
||||||
'uri': entry.uri,
|
'uri': entry.uri,
|
||||||
});
|
});
|
||||||
return result as Map;
|
return result as Map;
|
||||||
|
@ -40,7 +39,6 @@ class MetadataService {
|
||||||
// 'xmpTitleDescription': XMP title or XMP description (string)
|
// 'xmpTitleDescription': XMP title or XMP description (string)
|
||||||
final result = await platform.invokeMethod('getCatalogMetadata', <String, dynamic>{
|
final result = await platform.invokeMethod('getCatalogMetadata', <String, dynamic>{
|
||||||
'mimeType': entry.mimeType,
|
'mimeType': entry.mimeType,
|
||||||
'path': entry.path,
|
|
||||||
'uri': entry.uri,
|
'uri': entry.uri,
|
||||||
}) as Map;
|
}) as Map;
|
||||||
result['contentId'] = entry.contentId;
|
result['contentId'] = entry.contentId;
|
||||||
|
@ -61,7 +59,6 @@ class MetadataService {
|
||||||
// return map with string descriptions for: 'aperture' 'exposureTime' 'focalLength' 'iso'
|
// return map with string descriptions for: 'aperture' 'exposureTime' 'focalLength' 'iso'
|
||||||
final result = await platform.invokeMethod('getOverlayMetadata', <String, dynamic>{
|
final result = await platform.invokeMethod('getOverlayMetadata', <String, dynamic>{
|
||||||
'mimeType': entry.mimeType,
|
'mimeType': entry.mimeType,
|
||||||
'path': entry.path,
|
|
||||||
'uri': entry.uri,
|
'uri': entry.uri,
|
||||||
}) as Map;
|
}) as Map;
|
||||||
return OverlayMetadata.fromMap(result);
|
return OverlayMetadata.fromMap(result);
|
||||||
|
|
Loading…
Reference in a new issue