Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[file-system][android] add ability to read from bundle resources #8104

Merged
merged 2 commits into from May 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/expo-file-system/CHANGELOG.md
Expand Up @@ -11,5 +11,6 @@
### 🎉 New features

- Add `FileSystem.uploadAsync` method. ([#7380](https://github.com/expo/expo/pull/7380) by [@lukmccall](https://github.com/lukmccall))
- Add ability to read Android `raw` and `drawable` resources in `FileSystem.getInfoAsync`, `FileSystem.readAsStringAsync`, and `FileSystem.copyAsync`. ([#8104](https://github.com/expo/expo/pull/8104) by [@esamelson](https://github.com/esamelson))

### 🐛 Bug fixes
Expand Up @@ -165,6 +165,10 @@ private EnumSet<Permission> permissionsForUri(Uri uri) {
if ("file".equals(uri.getScheme())) {
return permissionsForPath(uri.getPath());
}
if (uri.getScheme() == null) {
// this is probably an asset embedded by the packager in resources
return EnumSet.of(Permission.READ);
}
return EnumSet.noneOf(Permission.class);
}

Expand Down Expand Up @@ -193,6 +197,18 @@ private InputStream openAssetInputStream(Uri uri) throws IOException {
return getContext().getAssets().open(asset);
}

private InputStream openResourceInputStream(String resourceName) throws IOException {
int resourceId = getContext().getResources().getIdentifier(resourceName, "raw", getContext().getPackageName());
if (resourceId == 0) {
// this resource doesn't exist in the raw folder, so try drawable
resourceId = getContext().getResources().getIdentifier(resourceName, "drawable", getContext().getPackageName());
if (resourceId == 0) {
throw new FileNotFoundException("No resource found with the name " + resourceName);
}
}
return getContext().getResources().openRawResource(resourceId);
}

@ExpoMethod
public void getInfoAsync(String uriStr, Map<String, Object> options, Promise promise) {
try {
Expand All @@ -216,12 +232,17 @@ public void getInfoAsync(String uriStr, Map<String, Object> options, Promise pro
result.putBoolean("isDirectory", false);
promise.resolve(result);
}
} else if ("content".equals(uri.getScheme()) || "asset".equals(uri.getScheme())) {
} else if ("content".equals(uri.getScheme()) || "asset".equals(uri.getScheme()) || uri.getScheme() == null) {
Bundle result = new Bundle();
try {
InputStream is = "content".equals(uri.getScheme()) ?
getContext().getContentResolver().openInputStream(uri) :
openAssetInputStream(uri);
InputStream is;
if ("content".equals(uri.getScheme())) {
is = getContext().getContentResolver().openInputStream(uri);
} else if ("asset".equals(uri.getScheme())) {
is = openAssetInputStream(uri);
} else {
is = openResourceInputStream(uriStr);
}
if (is == null) {
throw new FileNotFoundException();
}
Expand Down Expand Up @@ -288,6 +309,9 @@ public void readAsStringAsync(String uriStr, Map<String, Object> options, Promis
contents = IOUtils.toString(new FileInputStream(uriToFile(uri)));
} else if ("asset".equals(uri.getScheme())) {
contents = IOUtils.toString(openAssetInputStream(uri));
} else if (uri.getScheme() == null) {
// this is probably an asset embedded by the packager in resources
contents = IOUtils.toString(openResourceInputStream(uriStr));
} else {
throw new IOException("Unsupported scheme for location '" + uri + "'.");
}
Expand Down Expand Up @@ -434,6 +458,12 @@ public void copyAsync(Map<String, Object> options, Promise promise) {
OutputStream out = new FileOutputStream(uriToFile(toUri));
IOUtils.copy(in, out);
promise.resolve(null);
} else if (fromUri.getScheme() == null) {
// this is probably an asset embedded by the packager in resources
InputStream in = openResourceInputStream((String) options.get("from"));
OutputStream out = new FileOutputStream(uriToFile(toUri));
IOUtils.copy(in, out);
promise.resolve(null);
} else {
throw new IOException("Unsupported scheme for location '" + fromUri + "'.");
}
Expand Down