Skip to content

Instantly share code, notes, and snippets.

@adoankim
Last active April 11, 2018 10:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adoankim/56b1c06f0eb575dcca617e2b428a7d18 to your computer and use it in GitHub Desktop.
Save adoankim/56b1c06f0eb575dcca617e2b428a7d18 to your computer and use it in GitHub Desktop.
Support Blob provider on detached Expo apps
/**
* Copyright (c) 2015-present, Facebook, Inc. All rights reserved.
*
* <p>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 kim.adoan.modules.blob;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.support.annotation.Nullable;
import com.facebook.react.modules.blob.BlobModule;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
public final class BlobProvider extends ContentProvider {
@Override
public boolean onCreate() {
return true;
}
@Override
public @Nullable Cursor query(
Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
return null;
}
@Override
public @Nullable String getType(Uri uri) {
return null;
}
@Override
public @Nullable Uri insert(Uri uri, ContentValues values) {
return null;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
return 0;
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
return 0;
}
@Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
if (!mode.equals("r")) {
throw new FileNotFoundException("Cannot open " + uri.toString() + " in mode '" + mode + "'");
}
BlobModule blobModule;
if (BlobProviderModule.mContext == null) {
throw new RuntimeException("blob provider context is null!");
}
blobModule = BlobProviderModule.mContext.getNativeModule(BlobModule.class);
if (blobModule == null) {
throw new RuntimeException("No blob module associated with BlobProvider");
}
byte[] data = blobModule.resolve(uri);
if (data == null) {
throw new FileNotFoundException("Cannot open " + uri.toString() + ", blob not found.");
}
ParcelFileDescriptor[] pipe;
try {
pipe = ParcelFileDescriptor.createPipe();
} catch (IOException exception) {
return null;
}
ParcelFileDescriptor readSide = pipe[0];
ParcelFileDescriptor writeSide = pipe[1];
OutputStream outputStream = new ParcelFileDescriptor.AutoCloseOutputStream(writeSide);
try {
outputStream.write(data);
outputStream.close();
} catch (IOException exception) {
return null;
}
return readSide;
}
}
package kim.adoan.modules.blob;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
public class BlobProviderModule extends ReactContextBaseJavaModule {
public static ReactApplicationContext mContext = null;
public BlobProviderModule(ReactApplicationContext reactContext) {
super(reactContext);
mContext = reactContext;
}
@Override
public String getName() {
return BlobProviderModule.class.getName();
}
}
package kim.adoan.modules.blob;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
public class BlobProviderPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactApplicationContext) {
ArrayList<NativeModule> modules = new ArrayList<>();
modules.add(new BlobProviderModule(reactApplicationContext));
return modules;
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactApplicationContext) {
return Collections.emptyList();
}
}
@adoankim
Copy link
Author

And don't forget to import and add the BlobProviderPackage to the packages list in the MainApplication class.

import kim.adoan.modules.blob.BlobProviderPackage; 

public class MainApplication extends ExpoApplication {
///.....
 public List<ReactPackage> getPackages() {
    return Arrays.<ReactPackage>asList(
          /// other packages...
          new BlobProviderPackage()
    );
  }
//.....
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment