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

cache files when files comes from contents provider #224

Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.logging.Logger;

/**
* @see <a href="https://developer.android.com/guide/topics/providers/document-provider.html">android documentation</a>
*/
Expand Down Expand Up @@ -174,22 +185,41 @@ public void onShowActivityResult(int resultCode, Intent data, Promise promise) {
}
}

private WritableMap getMetadata(Uri uri) {
private WritableMap getMetadata(Uri uri) throws FileNotFoundException {
WritableMap map = Arguments.createMap();

map.putString(FIELD_URI, uri.toString());

ContentResolver contentResolver = getReactApplicationContext().getContentResolver();

map.putString(FIELD_TYPE, contentResolver.getType(uri));

Cursor cursor = contentResolver.query(uri, null, null, null, null, null);

try {
if (cursor != null && cursor.moveToFirst()) {
String fileName = "";
int displayNameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
if (!cursor.isNull(displayNameIndex)) {
map.putString(FIELD_NAME, cursor.getString(displayNameIndex));
fileName = cursor.getString(displayNameIndex);
map.putString(FIELD_NAME, fileName);
}

if (uri != null && "content".equals(uri.getScheme())) {
try {
InputStream input = DocumentPickerModule.getInputStreamForVirtualFile(contentResolver,uri,contentResolver.getType(uri));
File file = new File(getReactApplicationContext().getCacheDir(),fileName);
OutputStream output = new FileOutputStream(file);
byte[] buffer = new byte[4 * 1024]; // or other buffer size
int read;
while ((read = input.read(buffer)) != -1) {
output.write(buffer, 0, read);
}
output.flush();
map.putString(FIELD_URI, file.getPath());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't this return a file path instead of a file:// URI breaking consistency with other platforms?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. This has risk if users expect to receive content uri.
Thank you for review.

} catch (IOException e) {
throw new FileNotFoundException();
}
} else {
map.putString(FIELD_URI, uri.toString());
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Expand All @@ -212,4 +242,20 @@ private WritableMap getMetadata(Uri uri) {

return map;
}

private static InputStream getInputStreamForVirtualFile(ContentResolver resolver, Uri uri, String mimeTypeFilter)
throws IOException {

String[] openableMimeTypes = resolver.getStreamTypes(uri, mimeTypeFilter);

if (openableMimeTypes == null ||
openableMimeTypes.length < 1) {
throw new FileNotFoundException();
}

return resolver
.openTypedAssetFileDescriptor(uri, openableMimeTypes[0], null)
.createInputStream();
}

}