mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-14 10:01:08 +08:00
@ -607,6 +607,7 @@ export class FileSystemAccess implements IFileSystemAccess {
|
||||
}
|
||||
|
||||
export class FileSystemAccess29 extends FileSystemAccess {
|
||||
__skip = true;
|
||||
getLastModified(path: string): Date {
|
||||
if (isContentUri(path)) {
|
||||
return new Date(getOrSetHelper(path).getLastModified() * 1000);
|
||||
|
@ -126,6 +126,26 @@ export class FileSystemEntity {
|
||||
return;
|
||||
}
|
||||
|
||||
const localError = function (error) {
|
||||
if (onError) {
|
||||
onError(error);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
const fileAccess = getFileAccess();
|
||||
// call rename for FileSystemAccess29
|
||||
if ((<any>fileAccess).__skip) {
|
||||
fileAccess.rename(this.path, newName, localError);
|
||||
const fileInfo = getFileAccess().getFile(this.path, null);
|
||||
if (fileInfo) {
|
||||
this._name = fileInfo.name;
|
||||
this._extension = fileInfo.extension;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const parentFolder = this.parent;
|
||||
if (!parentFolder) {
|
||||
if (onError) {
|
||||
@ -135,18 +155,9 @@ export class FileSystemEntity {
|
||||
return;
|
||||
}
|
||||
|
||||
const fileAccess = getFileAccess();
|
||||
const path = parentFolder.path;
|
||||
const newPath = fileAccess.joinPath(path, newName);
|
||||
|
||||
const localError = function (error) {
|
||||
if (onError) {
|
||||
onError(error);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
fileAccess.rename(this.path, newPath, localError);
|
||||
this._path = newPath;
|
||||
this._name = newName;
|
||||
|
Binary file not shown.
@ -83,6 +83,12 @@ dependencies {
|
||||
outLogger.withStyle(Style.SuccessHeader).println "\t + using android X library androidx.appcompat:appcompat:$androidXAppCompatVersion"
|
||||
}
|
||||
|
||||
def androidXDocumentFileVersion = "1.0.1"
|
||||
if (project.hasProperty("androidXDocumentFile")) {
|
||||
androidXDocumentFileVersion = androidXDocumentFile
|
||||
outLogger.withStyle(Style.SuccessHeader).println "\t + using android X library androidx.documentfile:documentfile:$androidXDocumentFileVersion"
|
||||
}
|
||||
|
||||
|
||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||
|
||||
@ -93,6 +99,7 @@ dependencies {
|
||||
implementation "androidx.transition:transition:$androidXTransitionVersion"
|
||||
implementation "androidx.exifinterface:exifinterface:$androidXExifInterfaceVersion"
|
||||
implementation "androidx.appcompat:appcompat:$androidXAppCompatVersion"
|
||||
implementation "androidx.documentfile:documentfile:$androidXDocumentFileVersion"
|
||||
}
|
||||
|
||||
task cleanBuildDir (type: Delete) {
|
||||
|
@ -5,15 +5,20 @@ import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.provider.DocumentsContract;
|
||||
import android.provider.MediaStore;
|
||||
import android.webkit.MimeTypeMap;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.documentfile.provider.DocumentFile;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
@ -42,6 +47,51 @@ public class FileHelper {
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
private static boolean isExternalStorageDocument(Uri uri) {
|
||||
return "com.android.externalstorage.documents".equals(uri
|
||||
.getAuthority());
|
||||
}
|
||||
|
||||
private static @Nullable
|
||||
Cursor getCursor(Context context, Uri uri) {
|
||||
Cursor cursor = null;
|
||||
try {
|
||||
if (Build.VERSION.SDK_INT >= 19) {
|
||||
if (DocumentsContract.isDocumentUri(context, uri)) {
|
||||
String docId = DocumentsContract.getDocumentId(uri);
|
||||
String[] split = docId.split(":");
|
||||
String type = split[0];
|
||||
|
||||
Uri contentUri;
|
||||
if ("image".equals(type)) {
|
||||
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
|
||||
} else if ("video".equals(type)) {
|
||||
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
|
||||
} else if ("audio".equals(type)) {
|
||||
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
|
||||
} else {
|
||||
contentUri = MediaStore.Files.getContentUri("external");
|
||||
}
|
||||
|
||||
String selection = "_id=?";
|
||||
String[] selectionArgs = {split[1]};
|
||||
|
||||
cursor = context.getContentResolver().query(
|
||||
contentUri, null, selection, selectionArgs, null, null
|
||||
);
|
||||
}
|
||||
}
|
||||
if (cursor == null) {
|
||||
cursor = context.getContentResolver().query(uri, null, null, null, null);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
cursor = null;
|
||||
}
|
||||
|
||||
return cursor;
|
||||
|
||||
}
|
||||
|
||||
public static boolean exists(Context context, String string) {
|
||||
try {
|
||||
return exists(context, Uri.parse(string));
|
||||
@ -51,9 +101,17 @@ public class FileHelper {
|
||||
}
|
||||
|
||||
public static boolean exists(Context context, Uri uri) {
|
||||
Cursor cursor = context.getContentResolver()
|
||||
.query(uri, null, null, null, null);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 19 && isExternalStorageDocument(uri)) {
|
||||
File file = getFile(context, uri);
|
||||
if (file != null) {
|
||||
return file.exists();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
Cursor cursor = getCursor(context, uri);
|
||||
if (cursor == null) {
|
||||
return false;
|
||||
}
|
||||
boolean exists = cursor.moveToFirst();
|
||||
cursor.close();
|
||||
return exists;
|
||||
@ -62,17 +120,77 @@ public class FileHelper {
|
||||
public static @Nullable
|
||||
FileHelper fromString(Context context, String string) {
|
||||
try {
|
||||
return fromUri(context, Uri.parse(string));
|
||||
} catch (Exception ignored) {
|
||||
return fromUri(context, Uri.parse(Uri.decode(string)), false);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private static @Nullable
|
||||
File getFile(Context context, Uri uri) {
|
||||
if (Build.VERSION.SDK_INT >= 19) {
|
||||
String docId = DocumentsContract.getDocumentId(uri);
|
||||
String[] split = docId.split(":");
|
||||
String type = split[0];
|
||||
String path = split[1];
|
||||
|
||||
if ("primary".equals(type)) {
|
||||
String[] parts = Uri.decode(uri.toString()).split(":" + path + "/");
|
||||
String file = Environment.getExternalStorageDirectory() + "/" + path + "/" + parts[1];
|
||||
return new File(file);
|
||||
} else {
|
||||
File[] cacheDirs = context.getExternalCacheDirs();
|
||||
String storageDir = null;
|
||||
for (File cacheDir : cacheDirs) {
|
||||
final String cachePath = cacheDir.getPath();
|
||||
int index = cachePath.indexOf(type);
|
||||
if (index >= 0) {
|
||||
storageDir = cachePath.substring(0, index + type.length());
|
||||
}
|
||||
}
|
||||
|
||||
if (storageDir != null) {
|
||||
return new File(storageDir + "/" + path);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static @Nullable
|
||||
FileHelper fromUri(Context context, Uri uri) {
|
||||
Cursor cursor = context.getContentResolver()
|
||||
.query(uri, null, null, null, null);
|
||||
return fromUri(context, uri, true);
|
||||
}
|
||||
|
||||
private static @Nullable
|
||||
FileHelper fromUri(Context context, Uri contentUri, boolean parseUri) {
|
||||
Uri uri;
|
||||
|
||||
if (parseUri) {
|
||||
uri = Uri.parse(Uri.decode(contentUri.toString()));
|
||||
} else {
|
||||
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.size = file.length();
|
||||
helper.name = file.getName();
|
||||
helper.mime = context.getContentResolver().getType(uri);
|
||||
helper.lastModified = file.lastModified() / 1000;
|
||||
return helper;
|
||||
}
|
||||
|
||||
Cursor cursor = getCursor(context, uri);
|
||||
|
||||
if (cursor == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int sizeIndex = cursor.getColumnIndex(
|
||||
MediaStore.MediaColumns.SIZE
|
||||
@ -104,20 +222,41 @@ public class FileHelper {
|
||||
updateInternal(context, true);
|
||||
}
|
||||
|
||||
|
||||
private void updateValue(Context context, Uri uri, ContentValues values) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
context.getContentResolver().update(uri, values, null);
|
||||
} else {
|
||||
context.getContentResolver().update(uri, values, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateInternal(Context context, boolean force) {
|
||||
|
||||
if (force) {
|
||||
// trigger db update
|
||||
ContentValues values = new ContentValues();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
context.getContentResolver().update(uri, values, null);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
if (isExternalStorageDocument(uri)) {
|
||||
return;
|
||||
}
|
||||
if (DocumentsContract.isDocumentUri(context, uri)) {
|
||||
DocumentFile file = DocumentFile.fromSingleUri(context, uri);
|
||||
if (file != null) {
|
||||
updateValue(context, file.getUri(), values);
|
||||
}
|
||||
} else {
|
||||
updateValue(context, uri, values);
|
||||
}
|
||||
} else {
|
||||
context.getContentResolver().update(uri, values, null, null);
|
||||
updateValue(context, uri, values);
|
||||
}
|
||||
}
|
||||
|
||||
Cursor cursor = context.getContentResolver()
|
||||
.query(uri, null, null, null, null);
|
||||
Cursor cursor = getCursor(context, uri);
|
||||
if (cursor == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
int sizeIndex = cursor.getColumnIndex(
|
||||
MediaStore.MediaColumns.SIZE
|
||||
@ -170,8 +309,35 @@ public class FileHelper {
|
||||
return lastModified;
|
||||
}
|
||||
|
||||
private InputStream getInputStream(Context context, Uri uri) throws Exception {
|
||||
if (Build.VERSION.SDK_INT >= 19) {
|
||||
if (isExternalStorageDocument(uri)) {
|
||||
File file = getFile(context, uri);
|
||||
return new FileInputStream(file);
|
||||
}
|
||||
if (DocumentsContract.isDocumentUri(context, uri)) {
|
||||
return context.getContentResolver().openInputStream(DocumentFile.fromSingleUri(context, uri).getUri());
|
||||
}
|
||||
}
|
||||
return context.getContentResolver().openInputStream(uri);
|
||||
}
|
||||
|
||||
|
||||
private OutputStream getOutputStream(Context context, Uri uri) throws Exception {
|
||||
if (Build.VERSION.SDK_INT >= 19) {
|
||||
if (isExternalStorageDocument(uri)) {
|
||||
File file = getFile(context, uri);
|
||||
return new FileOutputStream(file);
|
||||
}
|
||||
if (DocumentsContract.isDocumentUri(context, uri)) {
|
||||
return context.getContentResolver().openOutputStream(DocumentFile.fromSingleUri(context, uri).getUri());
|
||||
}
|
||||
}
|
||||
return context.getContentResolver().openOutputStream(uri);
|
||||
}
|
||||
|
||||
private byte[] readSyncInternal(Context context) throws Exception {
|
||||
InputStream is = context.getContentResolver().openInputStream(uri);
|
||||
InputStream is = getInputStream(context, uri);
|
||||
byte[] array = new byte[(int) size];
|
||||
is.read(array);
|
||||
is.close();
|
||||
@ -207,7 +373,7 @@ public class FileHelper {
|
||||
characterSet = "UTF-8";
|
||||
}
|
||||
|
||||
InputStream is = context.getContentResolver().openInputStream(uri);
|
||||
InputStream is = getInputStream(context, uri);
|
||||
InputStreamReader isr = new InputStreamReader(is, characterSet);
|
||||
BufferedReader reader = new BufferedReader(isr);
|
||||
char[] buf = new char[is.available()];
|
||||
@ -239,7 +405,7 @@ public class FileHelper {
|
||||
}
|
||||
|
||||
private void writeSyncInternal(Context context, byte[] content) throws Exception {
|
||||
OutputStream os = context.getContentResolver().openOutputStream(uri);
|
||||
OutputStream os = getOutputStream(context, uri);
|
||||
os.write(content, 0, content.length);
|
||||
os.flush();
|
||||
os.close();
|
||||
@ -268,7 +434,7 @@ public class FileHelper {
|
||||
}
|
||||
|
||||
private void writeTextSyncInternal(Context context, String content, @Nullable String encoding) throws Exception {
|
||||
OutputStream os = context.getContentResolver().openOutputStream(uri);
|
||||
OutputStream os = getOutputStream(context, uri);
|
||||
String characterSet = encoding;
|
||||
if (characterSet == null) {
|
||||
characterSet = "UTF-8";
|
||||
@ -313,7 +479,7 @@ public class FileHelper {
|
||||
}
|
||||
|
||||
private void copyToFileInternal(Context context, File file) throws Exception {
|
||||
InputStream is = context.getContentResolver().openInputStream(uri);
|
||||
InputStream is = getInputStream(context, uri);
|
||||
FileOutputStream os = new FileOutputStream(file);
|
||||
copyToFileInternal(is, os);
|
||||
}
|
||||
@ -344,6 +510,41 @@ public class FileHelper {
|
||||
|
||||
public boolean delete(Context context) {
|
||||
try {
|
||||
if (Build.VERSION.SDK_INT >= 19) {
|
||||
if (isExternalStorageDocument(uri)) {
|
||||
File file = getFile(context, uri);
|
||||
if (file != null) {
|
||||
return file.delete();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (DocumentsContract.isDocumentUri(context, uri)) {
|
||||
String docId = DocumentsContract.getDocumentId(uri);
|
||||
String[] split = docId.split(":");
|
||||
String type = split[0];
|
||||
|
||||
Uri contentUri;
|
||||
if ("image".equals(type)) {
|
||||
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
|
||||
} else if ("video".equals(type)) {
|
||||
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
|
||||
} else if ("audio".equals(type)) {
|
||||
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
|
||||
} else {
|
||||
contentUri = MediaStore.Files.getContentUri("external");
|
||||
}
|
||||
|
||||
String selection = "_id=?";
|
||||
String[] selectionArgs = {split[1]};
|
||||
|
||||
return context.getContentResolver().delete(
|
||||
contentUri, selection, selectionArgs
|
||||
) > 0;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return context.getContentResolver().delete(uri, null, null) > 0;
|
||||
} catch (SecurityException e) {
|
||||
return false;
|
||||
@ -354,6 +555,44 @@ public class FileHelper {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(MediaStore.MediaColumns.DISPLAY_NAME, newName);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 19) {
|
||||
if (isExternalStorageDocument(uri)) {
|
||||
File file = getFile(context, uri);
|
||||
if (file != null) {
|
||||
file.renameTo(new File(file.getParentFile(), newName));
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (DocumentsContract.isDocumentUri(context, uri)) {
|
||||
String docId = DocumentsContract.getDocumentId(uri);
|
||||
String[] split = docId.split(":");
|
||||
String type = split[0];
|
||||
|
||||
Uri contentUri;
|
||||
if ("image".equals(type)) {
|
||||
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
|
||||
} else if ("video".equals(type)) {
|
||||
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
|
||||
} else if ("audio".equals(type)) {
|
||||
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
|
||||
} else {
|
||||
contentUri = MediaStore.Files.getContentUri("external");
|
||||
}
|
||||
|
||||
String selection = "_id=?";
|
||||
String[] selectionArgs = {split[1]};
|
||||
|
||||
context.getContentResolver().update(
|
||||
contentUri, values, selection, selectionArgs
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
context.getContentResolver().update(uri, values, null);
|
||||
} else {
|
||||
@ -373,7 +612,6 @@ public class FileHelper {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void rename(Context context, String newName, Callback callback) {
|
||||
executor.execute(() -> {
|
||||
try {
|
||||
|
Reference in New Issue
Block a user