/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.react.modules.camera;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import android.content.ContentResolver;
import android.net.Uri;
import android.os.AsyncTask;
import android.util.Base64;
import android.util.Base64OutputStream;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.GuardedAsyncTask;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.module.annotations.ReactModule;
@ReactModule(name = "ImageStoreManager")
public class ImageStoreManager extends ReactContextBaseJavaModule {
private static final int BUFFER_SIZE = 8192;
public ImageStoreManager(ReactApplicationContext reactContext) {
super(reactContext);
}
@Override
public String getName() {
return "ImageStoreManager";
}
/**
* Calculate the base64 representation for an image. The "tag" comes from iOS naming.
*
* @param uri the URI of the image, file:// or content://
* @param success callback to be invoked with the base64 string as the only argument
* @param error callback to be invoked on error (e.g. file not found, not readable etc.)
*/
@ReactMethod
public void getBase64ForTag(String uri, Callback success, Callback error) {
new GetBase64Task(getReactApplicationContext(), uri, success, error)
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
private class GetBase64Task extends GuardedAsyncTask<Void, Void> {
private final String mUri;
private final Callback mSuccess;
private final Callback mError;
private GetBase64Task(
ReactContext reactContext,
String uri,
Callback success,
Callback error) {
super(reactContext);
mUri = uri;
mSuccess = success;
mError = error;
}
@Override
protected void doInBackgroundGuarded(Void... params) {
try {
ContentResolver contentResolver = getReactApplicationContext().getContentResolver();
Uri uri = Uri.parse(mUri);
InputStream is = contentResolver.openInputStream(uri);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Base64OutputStream b64os = new Base64OutputStream(baos, Base64.DEFAULT);
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead;
try {
while ((bytesRead = is.read(buffer)) > -1) {
b64os.write(buffer, 0, bytesRead);
}
mSuccess.invoke(baos.toString());
} catch (IOException e) {
mError.invoke(e.getMessage());
} finally {
closeQuietly(is);
closeQuietly(b64os); // this also closes baos
}
} catch (FileNotFoundException e) {
mError.invoke(e.getMessage());
}
}
}
private static void closeQuietly(Closeable closeable) {
try {
closeable.close();
} catch (IOException e) {
// shhh
}
}
}