Skip to content

Commit

Permalink
#180: Allow show image from Uri that cannot be translated to file (i.…
Browse files Browse the repository at this point in the history
…e. WhatsApp photo)
  • Loading branch information
k3b committed Aug 19, 2020
1 parent 22e1413 commit ba052eb
Show file tree
Hide file tree
Showing 6 changed files with 213 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -750,6 +750,8 @@ private void defineMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_image_detail_locked, menu);
LockScreen.removeDangerousCommandsFromMenu(menu);

} else if (null == getCurrentIFile()) {
getMenuInflater().inflate(R.menu.menu_image_detail_non_file, menu);
} else {
getMenuInflater().inflate(R.menu.menu_image_detail, menu);
getMenuInflater().inflate(R.menu.menu_image_commands, menu);
Expand Down Expand Up @@ -873,24 +875,27 @@ private void onSlideShowNext() {
}

private void cmdShowDetails(final CharSequence title, final IFile file, final long currentImageId) {

File missingRoot = getMissingRootDirFileOrNull(
"ImageDetailActivityViewPager.osRenameTo", file.getFile());
if (missingRoot != null) {
// ask for needed permissions
requestRootUriDialog(missingRoot, title,
new FilePermissionActivity.IOnDirectoryPermissionGrantedHandler() {
@Override
public void afterGrant(FilePermissionActivity activity) {
((ImageDetailActivityViewPager) activity).cmdShowDetails(title, file, currentImageId);
}
});
return;
if (file != null) {
File missingRoot = getMissingRootDirFileOrNull(
"ImageDetailActivityViewPager.osRenameTo", file.getFile());
if (missingRoot != null) {
// ask for needed permissions
requestRootUriDialog(missingRoot, title,
new FilePermissionActivity.IOnDirectoryPermissionGrantedHandler() {
@Override
public void afterGrant(FilePermissionActivity activity) {
((ImageDetailActivityViewPager) activity).cmdShowDetails(title, file, currentImageId);
}
});
return;
}
}
CharSequence countMsg = TagSql.getStatisticsMessage(this, R.string.show_photo,
mGalleryContentQuery);

ImageDetailMetaDialogBuilder.createImageDetailDialog(this, file, currentImageId,
Uri uri = (file == null) ? getImageUri() : null;

ImageDetailMetaDialogBuilder.createImageDetailDialog(this, file, uri, currentImageId,
mGalleryContentQuery,
mViewPager.getCurrentItem(),
countMsg).show();
Expand Down Expand Up @@ -1277,6 +1282,14 @@ protected IFile getCurrentIFile() {
return null;
}

protected Uri getImageUri() {
if ((mViewPager != null) && (mAdapter != null)) {
int itemPosition = mViewPager.getCurrentItem();
return this.mAdapter.getImageUri(itemPosition);
}
return null;
}

protected String getCurrentAbsolutPath() {
IFile file = getCurrentIFile();
if (file != null) return file.getAbsolutePath();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.ContentValues;
import android.net.Uri;
import android.widget.ScrollView;
import android.widget.TextView;

Expand Down Expand Up @@ -50,26 +51,29 @@
public class ImageDetailMetaDialogBuilder {
private static final String NL = "\n";

public static Dialog createImageDetailDialog(Activity context, IFile file, long imageId,
public static Dialog createImageDetailDialog(Activity context, IFile file, Uri imageUri, long imageId,
QueryParameter query,
long offset, Object... moreBlocks) {
StringBuilder result = new StringBuilder();

Object fileId = (file == null) ? imageUri : file;
if (fileId == null) fileId = "";
result
.append(imageId)
.append(":").append(file)
.append(":").append(fileId)
.append("\n");
appendExifInfo(result, context, file, imageId);
appendExifInfo(context, result, file, imageUri, imageId);
appendQueryInfo(result, query, offset);

if ((moreBlocks != null) && (moreBlocks.length > 0)) {
for (Object subBlock : moreBlocks) {
if (subBlock != null) {
append(result,"\n");
append(result, subBlock.toString());
append(result, "\n");
append(result, fileId.toString());
}
}
}
return createImageDetailDialog(context, file.toString(), result.toString());
return createImageDetailDialog(context, fileId.toString(), result.toString());
}

public static Dialog createImageDetailDialog(Activity context, String title, String block, Object... moreBlocks) {
Expand Down Expand Up @@ -125,15 +129,17 @@ private static void append(StringBuilder result, String block) {
+ TagSql.SQL_COL_LAST_MODIFIED
+ ",").toLowerCase();

private static void appendExifInfo(StringBuilder result, Activity context, IFile jpegFile, long currentImageId) {
private static void appendExifInfo(Activity context, StringBuilder result, IFile jpegFile, Uri imageUri, long currentImageId) {
try {
getExifInfo_android(result, jpegFile);
getExifInfo_android(context, result, jpegFile, imageUri);

addExif(result, jpegFile);
addExif(context, result, jpegFile, imageUri);

// #84 show long and short xmp file
addXmp(result, XmpFile.getSidecar(jpegFile, true));
addXmp(result, XmpFile.getSidecar(jpegFile, false));
if (jpegFile != null) {
// #84 show long and short xmp file
addXmp(result, XmpFile.getSidecar(jpegFile, true));
addXmp(result, XmpFile.getSidecar(jpegFile, false));
}

if (currentImageId != 0) {

Expand All @@ -142,7 +148,7 @@ private static void appendExifInfo(StringBuilder result, Activity context, IFile
result.append(NL).append(line).append(NL);
result.append(NL).append(TagSql.SQL_TABLE_EXTERNAL_CONTENT_URI_FILE).append(NL).append(NL);
// sort by keys
List<String> sortedKeys=new ArrayList(dbContent.keySet());
List<String> sortedKeys = new ArrayList(dbContent.keySet());
Collections.sort(sortedKeys);
for (String key : sortedKeys) {
Object value = dbContent.get(key);
Expand Down Expand Up @@ -184,16 +190,28 @@ private static void appendDate(StringBuilder result, Object value, int factor) {

private static String line = "------------------";

private static void addExif(StringBuilder builder, IFile file) throws IOException {
if (file.exists()) {
builder.append(NL).append(file).append(NL).append(NL);

PhotoPropertiesImageReader meta = new PhotoPropertiesImageReader().load(
private static void addExif(Activity context, StringBuilder builder, IFile file, Uri imageUri) throws IOException {
PhotoPropertiesImageReader meta = null;
Object fileId = file;
if (file != null && file.exists()) {
meta = new PhotoPropertiesImageReader().load(
file, file.openInputStream(), null, "ImageDetailMetaDialogBuilder");
if (meta != null) builder.append(meta.toString());
} else if (imageUri != null) {
fileId = imageUri;
meta = new PhotoPropertiesImageReader().load(
(IFile) null,
context.getContentResolver().openInputStream(imageUri),
null, "ImageDetailMetaDialogBuilder(" +
imageUri + ")");
}

if (meta != null) {
builder.append(NL).append(fileId).append(NL).append(NL);

builder.append(meta.toString());
builder.append(NL).append(line).append(NL);
} else {
builder.append(NL).append(file).append(" not found.").append(NL);
builder.append(NL).append(fileId).append(" not found.").append(NL);
}
}

Expand All @@ -209,13 +227,26 @@ private static void addXmp(StringBuilder builder, IFile file) throws IOException
}
}

private static void getExifInfo_android(StringBuilder builder, IFile filepath) throws IOException {
ExifInterfaceEx exif = ExifInterfaceEx.create(filepath, null, null, "ImageDetailMetaDialogBuilder.getExifInfo_android");
private static void getExifInfo_android(Activity context, StringBuilder builder, IFile filepath, Uri imageUri) throws IOException {
Object fileId = filepath;
ExifInterfaceEx exif = null;
if (filepath != null && filepath.exists()) {
exif = ExifInterfaceEx.create(filepath, null, null, "ImageDetailMetaDialogBuilder.getExifInfo_android");
} else if (imageUri != null) {
fileId = imageUri;
exif = ExifInterfaceEx.create(
(IFile) null,
context.getContentResolver().openInputStream(imageUri),
null, "ImageDetailMetaDialogBuilder.getExifInfo_android(" +
imageUri + ")");
}

builder.append(NL).append(line).append(NL);
builder.append(NL).append(filepath).append(NL).append(NL);
if (exif.isValidJpgExifFormat()) builder.append(exif.getDebugString(NL));
if (exif != null) {
builder.append(NL).append(line).append(NL);
builder.append(NL).append(fileId).append(NL).append(NL);
if (exif.isValidJpgExifFormat()) builder.append(exif.getDebugString(NL));

builder.append(NL).append(line).append(NL);
builder.append(NL).append(line).append(NL);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.v4.view.PagerAdapter;
import android.util.Log;
Expand Down Expand Up @@ -51,6 +52,7 @@
import de.k3b.android.util.MenuUtils;
import de.k3b.android.util.PhotoChangeNotifyer;
import de.k3b.android.util.ResourceUtils;
import de.k3b.io.StringUtils;
import de.k3b.io.filefacade.FileFacade;
import de.k3b.io.filefacade.IFile;
import de.k3b.media.PhotoPropertiesBulkUpdateService;
Expand Down Expand Up @@ -197,10 +199,24 @@ public IFile getFile(int position) {
return getiFile(position, fullFilePath, imageID);
}

/** translates offset in adapter to id of image */
/**
* translates offset in adapter to id of image
*/
public long getImageId(int position) {
Cursor cursor = getCursorAt(position);
return DBUtils.getLong(cursor, FotoSql.SQL_COL_PK,0);
return DBUtils.getLong(cursor, FotoSql.SQL_COL_PK, 0);
}

/**
* gets uri that belongongs to current image
*/
public Uri getImageUri(int position) {
IFile file = getFullFilePath(position);
String path = (file != null) ? file.getAsUriString() : null;
if (!StringUtils.isNullOrEmpty(path)) {
return Uri.parse(path);
}
return null;
}

public Date getDatePhotoTaken(int position) {
Expand All @@ -211,7 +227,7 @@ public Date getDatePhotoTaken(int position) {

public boolean hasGeo(int position) {
Cursor cursor = getCursorAt(position);
return !DBUtils.isNull(cursor,FotoSql.SQL_COL_GPS,true);
return !DBUtils.isNull(cursor, FotoSql.SQL_COL_GPS, true);
}

/**
Expand Down Expand Up @@ -244,7 +260,7 @@ public View instantiateItem(ViewGroup container, int position) {

IFile file = getFile(position); // , fullPhotoPath);
if (file != null) {
return createViewWithContent(position, container, file, "instantiateItemFromCursor(#", size);
return createViewWithContent(position, container, file, null, "instantiateItemFromCursor(#", size);
}

}
Expand Down Expand Up @@ -284,7 +300,7 @@ public int getPositionFromPath(IFile file) {

@NonNull
protected View createViewWithContent(
int position, ViewGroup container, IFile imageFile, String debugContext, int size) {
int position, ViewGroup container, IFile imageFile, Uri imageUri, String debugContext, int size) {
final Context context = container.getContext();

final boolean useLayout = true;
Expand Down Expand Up @@ -323,31 +339,40 @@ protected View createViewWithContent(

String loadType;

// if image is big use memoryefficient, fast, low-quality thumbnail (old code)
if (size > Global.imageDetailThumbnailIfBiggerThan) {
loadType = "image too big using thumb ";
setImageFromThumbnail(photoView, imageFile);
} else {
try {
// #53 Optimisation: no need for thumbnail - saves cache memory but may throw OutOfMemoryError
loadType = "image small enough ";
Bitmap bitmap = HugeImageLoader.loadImage(imageFile, MAX_IMAGE_DIMENSION, MAX_IMAGE_DIMENSION);
// rotation is done by photoView
photoView.setImageBitmap(bitmap);
photoView.setImageReloadFile((IFile) null);
photoView.setDebugPrefix(imageFile.getName());
} catch (OutOfMemoryError err) {
loadType = "small image out of memory using thumb ";
if (imageFile != null) {
// if image is big use memoryefficient, fast, low-quality thumbnail (old code)
if (size > Global.imageDetailThumbnailIfBiggerThan) {
loadType = "image too big using thumb ";
setImageFromThumbnail(photoView, imageFile);
} else {
try {
// #53 Optimisation: no need for thumbnail - saves cache memory but may throw OutOfMemoryError
loadType = "image small enough ";
Bitmap bitmap = HugeImageLoader.loadImage(imageFile, MAX_IMAGE_DIMENSION, MAX_IMAGE_DIMENSION);
// rotation is done by photoView
photoView.setImageBitmap(bitmap);
photoView.setImageReloadFile((IFile) null);
photoView.setDebugPrefix(imageFile.getName());
} catch (OutOfMemoryError err) {
loadType = "small image out of memory using thumb ";
setImageFromThumbnail(photoView, imageFile);
}
}
final int rotationInDegrees = PhotoPropertiesBulkUpdateService.getRotationFromExifOrientation(imageFile, null);
if (Global.debugEnabledViewItem) {
Log.i(Global.LOG_CONTEXT, mDebugPrefix + debugContext + position + ", rotation=" +
rotationInDegrees + ", "
+ loadType + ") => " + imageFile + " => " + photoView);
}
photoView.setRotationTo(rotationInDegrees);
} else if (imageUri != null) {
if (Global.debugEnabledViewItem) {
Log.i(Global.LOG_CONTEXT, mDebugPrefix + debugContext + ") => " + imageUri + " => " + photoView);
}
photoView.setImageURI(imageUri);
} else if (Global.debugEnabledViewItem) {
Log.w(Global.LOG_CONTEXT, mDebugPrefix + debugContext + ") no ifile and no imageUri " + photoView);
}
final int rotationInDegrees = PhotoPropertiesBulkUpdateService.getRotationFromExifOrientation(imageFile, null);
if (Global.debugEnabledViewItem) {
Log.i(Global.LOG_CONTEXT, mDebugPrefix + debugContext + position +", rotation=" +
rotationInDegrees + ", "
+ loadType + ") => " + imageFile + " => " + photoView);
}
photoView.setRotationTo(rotationInDegrees);

container.addView(root, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
return root;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,30 @@ private IFile getLocalFullFilePath(int position) {
return null;
}

/** translates offset in adapter to id of image */
/**
* translates offset in adapter to id of image
*/
@Override
public long getImageId(int position) {
if (imageUri != null) return -1;
if (mArrayImpl != null) return mArrayImpl.getImageId(position);
return super.getImageId(position);
}

/**
* gets uri that belongongs to current image
*/
@Override
public Uri getImageUri(int position) {
Uri uri = super.getImageUri(position);

if ((uri == null) && (this.imageUri != null)) {
uri = this.imageUri;
}

return uri;
}

@Override
public Date getDatePhotoTaken(int position) {
if (imageUri != null) return null;
Expand All @@ -111,11 +127,16 @@ public View instantiateItem(ViewGroup container, int position) {
IFile file = getFile(position);
if (file != null) {
// special case image from ".nomedia" folder via absolute path not via content: uri
return createViewWithContent(position, container, file, "instantiateItemFromArray(#", 32767);
return createViewWithContent(position, container, file, null, "instantiateItemFromArray(#", 32767);
}

if (this.imageUri != null) {
// special case where uri exists and cannot be translated to file uri.
return createViewWithContent(position, container, null, this.imageUri, "instantiateItemFromArray(" + imageUri, 32767);
}

// no array avaliable. Use original cursor baed implementation
return super.instantiateItem(container,position);
return super.instantiateItem(container, position);
}
/** internal helper. return -1 if position is not available */
@Override
Expand Down
Loading

0 comments on commit ba052eb

Please sign in to comment.