Skip to content

Commit e570da7

Browse files
lukailunKaren
andauthored
Support React Native 0.78 for react-native-document-picker (#827)
* remove GuardedResultAsyncTask * remove GuardedResultAsyncTask * chore: add changeset --------- Co-authored-by: Karen <lukailun@mampod.com>
1 parent 649fa35 commit e570da7

File tree

2 files changed

+104
-105
lines changed

2 files changed

+104
-105
lines changed

.changeset/lucky-rings-end.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'react-native-document-picker': patch
3+
---
4+
5+
fix(android): remove GuardedResultAsyncTask to support React Native 0.78 for react-native-document-picker

android/src/main/java/com/reactnativedocumentpicker/RNDocumentPickerModule.java

Lines changed: 99 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
import android.database.Cursor;
1010
import android.net.Uri;
1111
import android.os.Bundle;
12+
import android.os.Handler;
13+
import android.os.Looper;
1214
import android.provider.DocumentsContract;
1315
import android.provider.OpenableColumns;
1416
import android.util.Log;
@@ -18,10 +20,8 @@
1820
import com.facebook.react.bridge.ActivityEventListener;
1921
import com.facebook.react.bridge.Arguments;
2022
import com.facebook.react.bridge.BaseActivityEventListener;
21-
import com.facebook.react.bridge.GuardedResultAsyncTask;
2223
import com.facebook.react.bridge.Promise;
2324
import com.facebook.react.bridge.ReactApplicationContext;
24-
import com.facebook.react.bridge.ReactContext;
2525
import com.facebook.react.bridge.ReactMethod;
2626
import com.facebook.react.bridge.ReadableArray;
2727
import com.facebook.react.bridge.ReadableMap;
@@ -32,12 +32,16 @@
3232
import java.io.FileOutputStream;
3333
import java.io.IOException;
3434
import java.io.InputStream;
35-
import java.lang.ref.WeakReference;
3635
import java.util.ArrayList;
3736
import java.util.List;
3837
import java.util.UUID;
38+
import java.util.concurrent.Executor;
39+
import java.util.concurrent.Executors;
3940

4041
public class RNDocumentPickerModule extends NativeDocumentPickerSpec {
42+
private final Executor executor = Executors.newSingleThreadExecutor();
43+
private final Handler handler = new Handler(Looper.getMainLooper());
44+
private final ReactApplicationContext reactContext;
4145
public static final String NAME = "RNDocumentPicker";
4246
private static final int READ_REQUEST_CODE = 41;
4347
private static final int PICK_DIR_REQUEST_CODE = 42;
@@ -66,6 +70,7 @@ public class RNDocumentPickerModule extends NativeDocumentPickerSpec {
6670

6771
public RNDocumentPickerModule(ReactApplicationContext reactContext) {
6872
super(reactContext);
73+
this.reactContext = reactContext;
6974
reactContext.addActivityEventListener(activityEventListener);
7075
}
7176

@@ -136,7 +141,7 @@ public void pick(ReadableMap args, Promise promise) {
136141
if (types.size() > 1) {
137142
String[] mimeTypes = readableArrayToStringArray(types);
138143
intent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes);
139-
intent.setType(String.join("|",mimeTypes));
144+
intent.setType(String.join("|", mimeTypes));
140145
} else if (types.size() == 1) {
141146
intent.setType(types.getString(0));
142147
}
@@ -222,128 +227,117 @@ public void onShowActivityResult(int resultCode, Intent data, Promise promise) {
222227
sendError(E_INVALID_DATA_RETURNED, "Invalid data returned by intent");
223228
return;
224229
}
225-
226-
new ProcessDataTask(getReactApplicationContext(), uris, copyTo, promise).execute();
230+
executor.execute(() -> {
231+
try {
232+
ReadableArray result = processData(uris);
233+
handler.post(() -> {
234+
promise.resolve(result);
235+
});
236+
} catch (IOException e) {
237+
handler.post(() -> {
238+
promise.reject("DocumentPicker_ERROR", e);
239+
});
240+
}
241+
});
227242
} catch (Exception e) {
228243
sendError(E_UNEXPECTED_EXCEPTION, e.getLocalizedMessage(), e);
229244
}
230245
}
231246

232-
private static class ProcessDataTask extends GuardedResultAsyncTask<ReadableArray> {
233-
private final WeakReference<Context> weakContext;
234-
private final List<Uri> uris;
235-
private final String copyTo;
236-
private final Promise promise;
237-
238-
protected ProcessDataTask(ReactContext reactContext, List<Uri> uris, String copyTo, Promise promise) {
239-
super(reactContext.getExceptionHandler());
240-
this.weakContext = new WeakReference<>(reactContext.getApplicationContext());
241-
this.uris = uris;
242-
this.copyTo = copyTo;
243-
this.promise = promise;
244-
}
245-
246-
@Override
247-
protected ReadableArray doInBackgroundGuarded() {
248-
WritableArray results = Arguments.createArray();
249-
for (Uri uri : uris) {
250-
results.pushMap(getMetadata(uri));
251-
}
252-
return results;
247+
private ReadableArray processData(List<Uri> uris) throws IOException {
248+
WritableArray results = Arguments.createArray();
249+
for (Uri uri : uris) {
250+
results.pushMap(getMetadata(uri));
253251
}
252+
return results;
253+
}
254254

255-
@Override
256-
protected void onPostExecuteGuarded(ReadableArray readableArray) {
257-
promise.resolve(readableArray);
255+
private WritableMap getMetadata(Uri uri) {
256+
Context context = reactContext;
257+
if (context == null) {
258+
return Arguments.createMap();
258259
}
259-
260-
private WritableMap getMetadata(Uri uri) {
261-
Context context = weakContext.get();
262-
if (context == null) {
263-
return Arguments.createMap();
264-
}
265-
ContentResolver contentResolver = context.getContentResolver();
266-
WritableMap map = Arguments.createMap();
267-
map.putString(FIELD_URI, uri.toString());
268-
map.putString(FIELD_TYPE, contentResolver.getType(uri));
269-
try (Cursor cursor = contentResolver.query(uri, null, null, null, null, null)) {
270-
if (cursor != null && cursor.moveToFirst()) {
271-
int displayNameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
272-
if (!cursor.isNull(displayNameIndex)) {
273-
String fileName = cursor.getString(displayNameIndex);
274-
map.putString(FIELD_NAME, fileName);
275-
} else {
276-
map.putNull(FIELD_NAME);
277-
}
278-
int mimeIndex = cursor.getColumnIndex(DocumentsContract.Document.COLUMN_MIME_TYPE);
279-
if (!cursor.isNull(mimeIndex)) {
280-
map.putString(FIELD_TYPE, cursor.getString(mimeIndex));
281-
}
282-
int sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE);
283-
if (cursor.isNull(sizeIndex)) {
284-
map.putNull(FIELD_SIZE);
285-
} else {
286-
map.putDouble(FIELD_SIZE, cursor.getLong(sizeIndex));
287-
}
260+
ContentResolver contentResolver = context.getContentResolver();
261+
WritableMap map = Arguments.createMap();
262+
map.putString(FIELD_URI, uri.toString());
263+
map.putString(FIELD_TYPE, contentResolver.getType(uri));
264+
try (Cursor cursor = contentResolver.query(uri, null, null, null, null, null)) {
265+
if (cursor != null && cursor.moveToFirst()) {
266+
int displayNameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
267+
if (!cursor.isNull(displayNameIndex)) {
268+
String fileName = cursor.getString(displayNameIndex);
269+
map.putString(FIELD_NAME, fileName);
270+
} else {
271+
map.putNull(FIELD_NAME);
272+
}
273+
int mimeIndex = cursor.getColumnIndex(DocumentsContract.Document.COLUMN_MIME_TYPE);
274+
if (!cursor.isNull(mimeIndex)) {
275+
map.putString(FIELD_TYPE, cursor.getString(mimeIndex));
276+
}
277+
int sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE);
278+
if (cursor.isNull(sizeIndex)) {
279+
map.putNull(FIELD_SIZE);
280+
} else {
281+
map.putDouble(FIELD_SIZE, cursor.getLong(sizeIndex));
288282
}
289283
}
290-
291-
prepareFileUri(context, map, uri);
292-
return map;
293284
}
294285

295-
private void prepareFileUri(Context context, WritableMap map, Uri uri) {
296-
if (copyTo == null) {
297-
map.putNull(FIELD_FILE_COPY_URI);
298-
} else {
299-
copyFileToLocalStorage(context, map, uri);
300-
}
286+
prepareFileUri(context, map, uri);
287+
return map;
288+
}
289+
290+
private void prepareFileUri(Context context, WritableMap map, Uri uri) {
291+
if (copyTo == null) {
292+
map.putNull(FIELD_FILE_COPY_URI);
293+
} else {
294+
copyFileToLocalStorage(context, map, uri);
301295
}
296+
}
302297

303-
private void copyFileToLocalStorage(Context context, WritableMap map, Uri uri) {
304-
File dir = context.getCacheDir();
305-
if (copyTo.equals("documentDirectory")) {
306-
dir = context.getFilesDir();
298+
private void copyFileToLocalStorage(Context context, WritableMap map, Uri uri) {
299+
File dir = context.getCacheDir();
300+
if (copyTo.equals("documentDirectory")) {
301+
dir = context.getFilesDir();
302+
}
303+
// we don't want to rename the file so we put it into a unique location
304+
dir = new File(dir, UUID.randomUUID().toString());
305+
try {
306+
boolean didCreateDir = dir.mkdir();
307+
if (!didCreateDir) {
308+
throw new IOException("failed to create directory at " + dir.getAbsolutePath());
307309
}
308-
// we don't want to rename the file so we put it into a unique location
309-
dir = new File(dir, UUID.randomUUID().toString());
310-
try {
311-
boolean didCreateDir = dir.mkdir();
312-
if (!didCreateDir) {
313-
throw new IOException("failed to create directory at " + dir.getAbsolutePath());
314-
}
315-
String fileName = map.getString(FIELD_NAME);
316-
if (fileName == null) {
317-
fileName = String.valueOf(System.currentTimeMillis());
318-
}
319-
File destFile = safeGetDestination(new File(dir, fileName), dir.getCanonicalPath());
320-
Uri copyPath = copyFile(context, uri, destFile);
321-
map.putString(FIELD_FILE_COPY_URI, copyPath.toString());
322-
} catch (Exception e) {
323-
e.printStackTrace();
324-
map.putNull(FIELD_FILE_COPY_URI);
325-
map.putString(FIELD_COPY_ERROR, e.getLocalizedMessage());
310+
String fileName = map.getString(FIELD_NAME);
311+
if (fileName == null) {
312+
fileName = String.valueOf(System.currentTimeMillis());
326313
}
314+
File destFile = safeGetDestination(new File(dir, fileName), dir.getCanonicalPath());
315+
Uri copyPath = copyFile(context, uri, destFile);
316+
map.putString(FIELD_FILE_COPY_URI, copyPath.toString());
317+
} catch (Exception e) {
318+
e.printStackTrace();
319+
map.putNull(FIELD_FILE_COPY_URI);
320+
map.putString(FIELD_COPY_ERROR, e.getLocalizedMessage());
327321
}
322+
}
328323

329-
public File safeGetDestination(File destFile, String expectedDir) throws IllegalArgumentException, IOException {
330-
String canonicalPath = destFile.getCanonicalPath();
331-
if (!canonicalPath.startsWith(expectedDir)) {
332-
throw new IllegalArgumentException("The copied file is attempting to write outside of the target directory.");
333-
}
334-
return destFile;
324+
public File safeGetDestination(File destFile, String expectedDir) throws IllegalArgumentException, IOException {
325+
String canonicalPath = destFile.getCanonicalPath();
326+
if (!canonicalPath.startsWith(expectedDir)) {
327+
throw new IllegalArgumentException("The copied file is attempting to write outside of the target directory.");
335328
}
329+
return destFile;
330+
}
336331

337-
public static Uri copyFile(Context context, Uri uri, File destFile) throws IOException {
338-
try(InputStream inputStream = context.getContentResolver().openInputStream(uri);
339-
FileOutputStream outputStream = new FileOutputStream(destFile)) {
340-
byte[] buf = new byte[8192];
341-
int len;
342-
while ((len = inputStream.read(buf)) > 0) {
343-
outputStream.write(buf, 0, len);
344-
}
345-
return Uri.fromFile(destFile);
332+
public static Uri copyFile(Context context, Uri uri, File destFile) throws IOException {
333+
try (InputStream inputStream = context.getContentResolver().openInputStream(uri);
334+
FileOutputStream outputStream = new FileOutputStream(destFile)) {
335+
byte[] buf = new byte[8192];
336+
int len;
337+
while ((len = inputStream.read(buf)) > 0) {
338+
outputStream.write(buf, 0, len);
346339
}
340+
return Uri.fromFile(destFile);
347341
}
348342
}
349343

0 commit comments

Comments
 (0)