fix(android): improve content uri handling (#10316)

This commit is contained in:
Osei Fortune
2023-06-17 13:14:28 -04:00
committed by GitHub
parent 0401b09a43
commit 77f252e551
3 changed files with 767 additions and 741 deletions

View File

@ -649,23 +649,22 @@ declare module org {
export module widgets {
export class FileHelper {
public static class: java.lang.Class<org.nativescript.widgets.FileHelper>;
public appendTextSync(param0: globalAndroid.content.Context, param1: string, param2: string, param3: org.nativescript.widgets.FileHelper.Callback): void;
public appendText(param0: globalAndroid.content.Context, param1: string, param2: string, param3: org.nativescript.widgets.FileHelper.Callback): void;
public readText(param0: globalAndroid.content.Context, param1: string, param2: org.nativescript.widgets.FileHelper.Callback): void;
public appendSync(param0: globalAndroid.content.Context, param1: androidNative.Array<number>, param2: org.nativescript.widgets.FileHelper.Callback): void;
public append(param0: globalAndroid.content.Context, param1: androidNative.Array<number>, param2: org.nativescript.widgets.FileHelper.Callback): void;
public appendBufferSync(param0: globalAndroid.content.Context, param1: java.nio.ByteBuffer, param2: org.nativescript.widgets.FileHelper.Callback): void;
public appendBuffer(param0: globalAndroid.content.Context, param1: java.nio.ByteBuffer, param2: org.nativescript.widgets.FileHelper.Callback): void;
public readText(param0: globalAndroid.content.Context, param1: string, param2: org.nativescript.widgets.FileHelper.Callback): void;
public writeBufferSync(param0: globalAndroid.content.Context, param1: java.nio.ByteBuffer, param2: org.nativescript.widgets.FileHelper.Callback): void;
public writeTextSync(param0: globalAndroid.content.Context, param1: string, param2: string, param3: org.nativescript.widgets.FileHelper.Callback): void;
public copyToFileSync(param0: globalAndroid.content.Context, param1: java.io.File, param2: org.nativescript.widgets.FileHelper.Callback): boolean;
public appendTextSync(param0: globalAndroid.content.Context, param1: string, param2: string, param3: org.nativescript.widgets.FileHelper.Callback): void;
public read(param0: globalAndroid.content.Context, param1: org.nativescript.widgets.FileHelper.Callback): void;
public renameSync(param0: globalAndroid.content.Context, param1: string, param2: org.nativescript.widgets.FileHelper.Callback): void;
public appendBufferSync(param0: globalAndroid.content.Context, param1: java.nio.ByteBuffer, param2: org.nativescript.widgets.FileHelper.Callback): void;
public readSync(param0: globalAndroid.content.Context, param1: org.nativescript.widgets.FileHelper.Callback): androidNative.Array<number>;
public static fromString(param0: globalAndroid.content.Context, param1: string): org.nativescript.widgets.FileHelper;
public getSize(): number;
public getMime(): string;
public static exists(param0: globalAndroid.content.Context, param1: globalAndroid.net.Uri): boolean;
public append(param0: globalAndroid.content.Context, param1: androidNative.Array<number>, param2: org.nativescript.widgets.FileHelper.Callback): void;
public appendBuffer(param0: globalAndroid.content.Context, param1: java.nio.ByteBuffer, param2: org.nativescript.widgets.FileHelper.Callback): void;
public delete(param0: globalAndroid.content.Context): boolean;
public writeSync(param0: globalAndroid.content.Context, param1: androidNative.Array<number>, param2: org.nativescript.widgets.FileHelper.Callback): void;
public writeText(param0: globalAndroid.content.Context, param1: string, param2: string, param3: org.nativescript.widgets.FileHelper.Callback): void;
@ -680,6 +679,7 @@ declare module org {
public readTextSync(param0: globalAndroid.content.Context, param1: string, param2: org.nativescript.widgets.FileHelper.Callback): string;
public static fromUri(param0: globalAndroid.content.Context, param1: globalAndroid.net.Uri): org.nativescript.widgets.FileHelper;
public static exists(param0: globalAndroid.content.Context, param1: string): boolean;
public appendText(param0: globalAndroid.content.Context, param1: string, param2: string, param3: org.nativescript.widgets.FileHelper.Callback): void;
public getLastModified(): number;
}
export module FileHelper {

View File

@ -35,12 +35,12 @@ import java.util.concurrent.Executors;
public class FileHelper {
private Uri uri;
private String name;
private String mime;
private long lastModified;
private final ExecutorService executor = Executors.newSingleThreadExecutor();
private final Handler handler;
private DocumentFile documentFile;
private WeakReference<Context> context;
public interface Callback {
@ -49,9 +49,13 @@ public class FileHelper {
void onSuccess(@Nullable Object result);
}
FileHelper(Uri uri) {
FileHelper(Context context, Uri uri) {
handler = new Handler(Looper.myLooper());
this.context = new WeakReference<>(context);
this.uri = uri;
if (DocumentFile.isDocumentUri(context, uri)) {
documentFile = DocumentFile.fromSingleUri(context, uri);
}
}
private static boolean isExternalStorageDocument(Uri uri) {
@ -63,7 +67,8 @@ public class FileHelper {
Cursor getCursor(Context context, Uri uri) {
return getCursor(context, uri, new String[]{
MediaStore.MediaColumns.DISPLAY_NAME,
MediaStore.MediaColumns.DATE_MODIFIED
MediaStore.MediaColumns.DATE_MODIFIED,
MediaStore.MediaColumns.SIZE
});
}
@ -100,9 +105,22 @@ public class FileHelper {
}
}
static File getDocumentFile(Context context, Uri uri) {
if (Build.VERSION.SDK_INT >= 19 && DocumentsContract.isDocumentUri(context, uri)) {
return getFile(context, uri);
}
return null;
}
public static boolean exists(Context context, Uri uri) {
if (Build.VERSION.SDK_INT >= 19 && isExternalStorageDocument(uri)) {
File file = getFile(context, uri);
if (Build.VERSION.SDK_INT >= 19) {
if (DocumentsContract.isDocumentUri(context, uri)) {
DocumentFile file = DocumentFile.fromSingleUri(context, uri);
if (file != null) {
return file.exists();
}
}
File file = getDocumentFile(context, uri);
if (file != null) {
return file.exists();
}
@ -119,21 +137,14 @@ public class FileHelper {
public static @Nullable
FileHelper fromString(Context context, String string) {
try {
FileHelper ret = fromUri(context, Uri.parse(string));
if (ret != null) {
ret.context = new WeakReference<>(context);
}
return ret;
} catch (Exception e) {
return null;
}
return fromUri(context, Uri.parse(string));
}
@SuppressWarnings("deprecation")
private static @Nullable
File getFile(Context context, Uri uri) {
if (Build.VERSION.SDK_INT >= 19) {
if (isExternalStorageDocument(uri)) {
String docId = DocumentsContract.getDocumentId(uri);
String[] split = docId.split(":");
String type = split[0];
@ -161,62 +172,25 @@ public class FileHelper {
}
}
}
}
return null;
}
public static @Nullable
FileHelper fromUri(Context context, Uri contentUri) {
Uri uri = contentUri;
if (Build.VERSION.SDK_INT >= 19 && isExternalStorageDocument(uri)) {
File file = getFile(context, uri);
if (file == null) {
return null;
}
FileHelper helper = new FileHelper(uri);
helper.name = file.getName();
helper.mime = context.getContentResolver().getType(uri);
helper.lastModified = file.lastModified() / 1000;
helper.context = new WeakReference<>(context);
return helper;
}
Cursor cursor = getCursor(context, uri);
if (cursor == null) {
return null;
}
boolean moved = cursor.moveToFirst();
FileHelper helper = null;
if (moved) {
int nameIndex = cursor.getColumnIndex(
MediaStore.MediaColumns.DISPLAY_NAME
);
int lastModifiedIndex = cursor.getColumnIndex(
MediaStore.MediaColumns.DATE_MODIFIED
);
helper = new FileHelper(uri);
helper.name = cursor.getString(nameIndex);
helper.mime = context.getContentResolver().getType(uri);
helper.lastModified = cursor.getLong(lastModifiedIndex);
helper.context = new WeakReference<>(context);
}
cursor.close();
return helper;
return new FileHelper(context, contentUri);
}
private long getFileSize() {
if (documentFile != null) {
return documentFile.length();
}
Context context = this.context.get();
if (context == null) {
return 0;
}
if (Build.VERSION.SDK_INT >= 19 && isExternalStorageDocument(uri)) {
File file = getFile(context, uri);
if (Build.VERSION.SDK_INT >= 19 && DocumentsContract.isDocumentUri(context, uri)) {
File file = getDocumentFile(context, uri);
if (file == null) {
return 0;
}
@ -279,29 +253,6 @@ public class FileHelper {
updateValue(context, uri, values);
}
}
Cursor cursor = getCursor(context, uri);
if (cursor == null) {
return;
}
boolean moved = cursor.moveToFirst();
if (moved) {
int nameIndex = cursor.getColumnIndex(
MediaStore.MediaColumns.DISPLAY_NAME
);
int lastModifiedIndex = cursor.getColumnIndex(
MediaStore.MediaColumns.DATE_MODIFIED
);
name = cursor.getString(nameIndex);
mime = context.getContentResolver().getType(uri);
lastModified = cursor.getLong(lastModifiedIndex);
}
cursor.close();
}
public long getSize() {
@ -309,10 +260,53 @@ public class FileHelper {
}
public String getName() {
if (documentFile != null) {
return documentFile.getName();
}
String name = null;
Context context = this.context.get();
if (context != null) {
if (DocumentFile.isDocumentUri(context, uri)) {
File file = getDocumentFile(context, uri);
if (file != null) {
name = file.getName();
}
} else {
Cursor cursor = getCursor(context, uri, null);
if (cursor == null) {
return null;
}
boolean moved = cursor.moveToFirst();
if (moved) {
int nameIndex = cursor.getColumnIndex(
MediaStore.MediaColumns.DISPLAY_NAME
);
name = cursor.getString(nameIndex);
}
cursor.close();
return name;
}
}
return name;
}
public String getMime() {
String mime = null;
Context context = this.context.get();
if (context != null) {
mime = context.getContentResolver().getType(uri);
}
if (mime == null) {
return "application/octet-stream";
}
@ -320,6 +314,7 @@ public class FileHelper {
}
public String getExtension() {
String mime = getMime();
if (mime == null) {
return "";
}
@ -327,6 +322,37 @@ public class FileHelper {
}
public long getLastModified() {
long lastModified = 0;
if (documentFile != null) {
return documentFile.lastModified();
}
Context context = this.context.get();
if (context != null) {
if (DocumentFile.isDocumentUri(context, uri)) {
File file = getDocumentFile(context, uri);
if (file != null) {
lastModified = file.lastModified() / 1000;
}
} else {
Cursor cursor = getCursor(context, uri, null);
if (cursor == null) {
return 0;
}
boolean moved = cursor.moveToFirst();
if (moved) {
int sizeIndex = cursor.getColumnIndex(
MediaStore.MediaColumns.DATE_MODIFIED
);
lastModified = cursor.getLong(sizeIndex);
}
cursor.close();
}
}
return lastModified;
}