Skip to content

Commit

Permalink
#301: Fix a bug that made it impossible to open a file from the galle…
Browse files Browse the repository at this point in the history
…ry on android 6.
  • Loading branch information
Keidan committed Mar 25, 2024
1 parent c168c1f commit 8d274c2
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 8 deletions.
4 changes: 2 additions & 2 deletions app/src/main/java/fr/ralala/hexviewer/models/FileData.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,12 @@ public FileData(final Context ctx, final Uri uri, boolean openFromAppIntent) {

public FileData(final Context ctx, final Uri uri, boolean openFromAppIntent, long startOffset, long endOffset) {
mShiftOffset = 0;
mUri = uri;
mName = FileHelper.getFileName(ctx, uri);
mUri = FileHelper.adjustUri(ctx, uri);
mStartOffset = startOffset;
mEndOffset = endOffset;
mOpenFromAppIntent = openFromAppIntent;
mRealSize = FileHelper.getFileSize(ctx, ctx.getContentResolver(), uri);
mRealSize = FileHelper.getFileSize(ctx, ctx.getContentResolver(), mUri);
if (isSequential())
mSize = Math.abs(mEndOffset - mStartOffset);
else
Expand Down
78 changes: 72 additions & 6 deletions app/src/main/java/fr/ralala/hexviewer/utils/io/FileHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@
import android.net.Uri;
import android.os.Build;
import android.os.ParcelFileDescriptor;
import android.provider.MediaStore;
import android.provider.OpenableColumns;
import android.util.Log;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.List;
Expand All @@ -34,6 +36,7 @@
public class FileHelper {
private static final String FILE_HELPER_TAG = "FileHelper";
private static final String EXCEPTION_TAG = "Exception: ";
private static final String BUCKET_ID = "?bucketId=";

private FileHelper() {
}
Expand Down Expand Up @@ -233,6 +236,7 @@ public static long getFileSize(Context ctx, ContentResolver cr, Uri uri) {
/**
* Gets the file name from a Uri.
*
* @param ctx Android context.
* @param uri Uri
* @return String
*/
Expand All @@ -241,7 +245,6 @@ public static String getFileName(final Context ctx, final Uri uri) {
ApplicationCtx.addLog(ctx, FILE_HELPER_TAG,
String.format(Locale.US, "Get filename for uri: '%s'", uri));
if (uri.getScheme().equals("content")) {

ApplicationCtx.addLog(ctx, FILE_HELPER_TAG, "Uri scheme equals to content");
try (Cursor cursor = ctx.getContentResolver().query(uri, null, null, null, null)) {
if (cursor != null && cursor.moveToFirst()) {
Expand All @@ -260,16 +263,78 @@ public static String getFileName(final Context ctx, final Uri uri) {
String.format(Locale.US, "Get file name exception: '%s'", e.getMessage()));
}
}
if (result == null) {
result = extractName(getPathFromBucket(ctx, uri));
}

if (result == null) {
result = uri.getPath();
result = extractName(uri.getPath());
}
ApplicationCtx.addLog(ctx, FILE_HELPER_TAG,
String.format(Locale.US, "Filename result: '%s'", result));
return result;
}

public static Uri adjustUri(final Context ctx, final Uri uri) {
String path = getPathFromBucket(ctx, uri);
if (path == null)
return uri;
return Uri.fromFile(new File(path));
}

/**
* File name extraction.
*
* @param name Full name.
* @return File name.
*/
private static String extractName(final String name) {
String result = name;
if (result != null) {
int cut = result.lastIndexOf('/');
if (cut != -1) {
result = result.substring(cut + 1);
}
}
ApplicationCtx.addLog(ctx, FILE_HELPER_TAG,
String.format(Locale.US, "Filename result: '%s'", result));
return result;
}

/**
* Extracting the path from a URI with bucket id.
*
* @param ctx Android context.
* @param uri Uri
* @return String
*/
private static String getPathFromBucket(final Context ctx, final Uri uri) {
String result = null;
int bucketId = uri.toString().indexOf(BUCKET_ID);
if (bucketId != -1) {
String bid = uri.toString().substring(bucketId + BUCKET_ID.length());
ApplicationCtx.addLog(ctx, FILE_HELPER_TAG, "Bucket id mode: " + bid);
final String[] projectionBucket = {
MediaStore.MediaColumns.BUCKET_ID,
MediaStore.MediaColumns.DATA};
final String groupBy = "1) GROUP BY 1,(2";
final String orderBy = "MAX(" + MediaStore.MediaColumns.DATE_TAKEN + ") DESC";
try (Cursor cursor = ctx.getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projectionBucket, groupBy, null, orderBy)) {
if (cursor != null && cursor.moveToFirst()) {
int dataColumn = cursor.getColumnIndex(MediaStore.MediaColumns.DATA);
int idColumn = cursor.getColumnIndex(MediaStore.MediaColumns.BUCKET_ID);
do {
String data = cursor.getString(dataColumn);
String id = cursor.getString(idColumn);
ApplicationCtx.addLog(ctx, FILE_HELPER_TAG,
String.format(Locale.US, "Bucket data '%s' id: %s", data, id));
if (id.equals(bid)) {
result = data;
break;
}
} while (cursor.moveToNext());
}
}
}
return result;
}

Expand All @@ -282,12 +347,13 @@ public static String getFileName(final Context ctx, final Uri uri) {
public static Uri getParentUri(final Context ctx, final Uri uri) {
final String filename = getFileName(ctx, uri);
final String encoded = uri.getEncodedPath();
final int length = encoded.length() - filename.length();
final int filenameLen = (filename == null ? 0 : filename.length());
final int length = encoded.length() - filenameLen;
ApplicationCtx.addLog(ctx, FILE_HELPER_TAG,
String.format(Locale.US, "Search for parent uri: '%s'", uri));
String path;
if (length > 0 && length < encoded.length()) {
String parent = encoded.substring(0, encoded.length() - filename.length());
String parent = encoded.substring(0, encoded.length() - filenameLen);
ApplicationCtx.addLog(ctx, FILE_HELPER_TAG,
String.format(Locale.US, "Parent raw: '%s'", parent));
if (parent.endsWith("%2F")) {
Expand Down

0 comments on commit 8d274c2

Please sign in to comment.