mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
@@ -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