From 497a703964e925b6e3e62e39a54a9734a7ed6c40 Mon Sep 17 00:00:00 2001 From: Joao Fidelis Date: Thu, 31 May 2018 14:26:56 -0300 Subject: [PATCH] feat(preview): add android code --- .../google/android/cameraview/Camera1.java | 54 ++++++++++++-- .../google/android/cameraview/Camera2.java | 51 ++++++++++++- .../google/android/cameraview/CameraView.java | 40 ++++++++++ .../android/cameraview/CameraViewImpl.java | 11 +++ .../com/google/android/cameraview/Size.java | 42 ++++++++++- .../org/reactnative/camera/CameraModule.java | 73 ++++++++++++++++++- .../reactnative/camera/CameraViewManager.java | 9 ++- .../org/reactnative/camera/RNCameraView.java | 21 +++++- .../camera/RNCameraViewHelper.java | 8 ++ .../camera/events/PictureSavedEvent.java | 46 ++++++++++++ .../camera/tasks/PictureSavedDelegate.java | 7 ++ .../tasks/ResolveTakenPictureAsyncTask.java | 19 +++-- 12 files changed, 360 insertions(+), 21 deletions(-) create mode 100644 android/src/main/java/org/reactnative/camera/events/PictureSavedEvent.java create mode 100644 android/src/main/java/org/reactnative/camera/tasks/PictureSavedDelegate.java diff --git a/android/src/main/java/com/google/android/cameraview/Camera1.java b/android/src/main/java/com/google/android/cameraview/Camera1.java index 5ccb3fbd1..fdbddee1f 100644 --- a/android/src/main/java/com/google/android/cameraview/Camera1.java +++ b/android/src/main/java/com/google/android/cameraview/Camera1.java @@ -77,8 +77,12 @@ class Camera1 extends CameraViewImpl implements MediaRecorder.OnInfoListener, private boolean mIsRecording; private final SizeMap mPreviewSizes = new SizeMap(); + + private boolean mIsPreviewActive = false; private final SizeMap mPictureSizes = new SizeMap(); + + private Size mPictureSize; private AspectRatio mAspectRatio; @@ -107,6 +111,7 @@ class Camera1 extends CameraViewImpl implements MediaRecorder.OnInfoListener, public void onSurfaceChanged() { if (mCamera != null) { setUpPreview(); + mIsPreviewActive = false; adjustCameraParameters(); } } @@ -164,6 +169,7 @@ void setUpPreview() { final boolean needsToStopPreview = mShowingPreview && Build.VERSION.SDK_INT < 14; if (needsToStopPreview) { mCamera.stopPreview(); + mIsPreviewActive = false; } mCamera.setPreviewDisplay(mPreview.getSurfaceHolder()); if (needsToStopPreview) { @@ -179,10 +185,22 @@ void setUpPreview() { private void startCameraPreview() { mCamera.startPreview(); + mIsPreviewActive = true; if (mIsScanning) { mCamera.setPreviewCallback(this); } } + + @Override + public void resumePreview() { + startCameraPreview(); + } + + @Override + public void pausePreview() { + mCamera.stopPreview(); + mIsPreviewActive = false; + } @Override boolean isCameraOpened() { @@ -216,6 +234,25 @@ Set getSupportedAspectRatios() { } return idealAspectRatios.ratios(); } + + @Override + SortedSet getAvailablePictureSizes(AspectRatio ratio) { + return mPictureSizes.sizes(ratio); + } + + @Override + void setPictureSize(Size size) { + mPictureSize = size; + if (mCameraParameters != null && mCamera != null) { + mCameraParameters.setPictureSize(size.getWidth(), size.getHeight()); + mCamera.setParameters(mCameraParameters); + } + } + + @Override + Size getPictureSize() { + return mPictureSize; + } @Override boolean setAspectRatio(AspectRatio ratio) { @@ -334,6 +371,9 @@ void takePicture() { throw new IllegalStateException( "Camera is not ready. Call start() before takePicture()."); } + if (!mIsPreviewActive) { + throw new IllegalStateException("Preview is paused - resume it before taking a picture."); + } if (getAutoFocus()) { mCamera.cancelAutoFocus(); mCamera.autoFocus(new Camera.AutoFocusCallback() { @@ -355,6 +395,7 @@ public void onPictureTaken(byte[] data, Camera camera) { isPictureCaptureInProgress.set(false); camera.cancelAutoFocus(); camera.startPreview(); + mIsPreviewActive = true; if (mIsScanning) { camera.setPreviewCallback(Camera1.this); } @@ -403,6 +444,7 @@ void setDisplayOrientation(int displayOrientation) { final boolean needsToStopPreview = mShowingPreview && Build.VERSION.SDK_INT < 14; if (needsToStopPreview) { mCamera.stopPreview(); + mIsPreviewActive = false; } mCamera.setDisplayOrientation(calcDisplayOrientation(displayOrientation)); if (needsToStopPreview) { @@ -420,6 +462,7 @@ public void setPreviewTexture(SurfaceTexture surfaceTexture) { } mCamera.stopPreview(); + mIsPreviewActive = false; if (surfaceTexture == null) { mCamera.setPreviewTexture((SurfaceTexture) mPreview.getSurfaceTexture()); @@ -504,13 +547,15 @@ void adjustCameraParameters() { Size size = chooseOptimalSize(sizes); // Always re-apply camera parameters - // Largest picture size in this ratio - final Size pictureSize = mPictureSizes.sizes(mAspectRatio).last(); + if (mPictureSize == null) { + mPictureSize = mPictureSizes.sizes(mAspectRatio).last(); + } if (mShowingPreview) { mCamera.stopPreview(); + mIsPreviewActive = false; } mCameraParameters.setPreviewSize(size.getWidth(), size.getHeight()); - mCameraParameters.setPictureSize(pictureSize.getWidth(), pictureSize.getHeight()); + mCameraParameters.setPictureSize(mPictureSize.getWidth(), mPictureSize.getHeight()); mCameraParameters.setRotation(calcCameraRotation(mDisplayOrientation)); setAutoFocusInternal(mAutoFocus); setFlashInternal(mFlash); @@ -555,6 +600,7 @@ private void releaseCamera() { if (mCamera != null) { mCamera.release(); mCamera = null; + mPictureSize = null; mCallback.onCameraClosed(); } } @@ -646,7 +692,6 @@ private boolean setFlashInternal(int flash) { String currentMode = FLASH_MODES.get(mFlash); if (modes == null || !modes.contains(currentMode)) { mCameraParameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); - mFlash = Constants.FLASH_OFF; return true; } return false; @@ -687,7 +732,6 @@ private boolean setWhiteBalanceInternal(int whiteBalance) { String currentMode = WB_MODES.get(mWhiteBalance); if (modes == null || !modes.contains(currentMode)) { mCameraParameters.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_AUTO); - mWhiteBalance = Constants.WB_AUTO; return true; } return false; diff --git a/android/src/main/java/com/google/android/cameraview/Camera2.java b/android/src/main/java/com/google/android/cameraview/Camera2.java index 585d1c9fa..2b7047885 100644 --- a/android/src/main/java/com/google/android/cameraview/Camera2.java +++ b/android/src/main/java/com/google/android/cameraview/Camera2.java @@ -216,6 +216,8 @@ public void onImageAvailable(ImageReader reader) { private final SizeMap mPictureSizes = new SizeMap(); + private Size mPictureSize; + private int mFacing; private AspectRatio mAspectRatio = Constants.DEFAULT_ASPECT_RATIO; @@ -345,6 +347,35 @@ Set getSupportedAspectRatios() { return mPreviewSizes.ratios(); } + @Override + SortedSet getAvailablePictureSizes(AspectRatio ratio) { + return mPictureSizes.sizes(ratio); + } + + @Override + void setPictureSize(Size size) { + if (mCaptureSession != null) { + try { + mCaptureSession.stopRepeating(); + } catch (CameraAccessException e) { + e.printStackTrace(); + } + mCaptureSession.close(); + mCaptureSession = null; + } + if (mStillImageReader != null) { + mStillImageReader.close(); + } + mPictureSize = size; + prepareStillImageReader(); + startCaptureSession(); + } + + @Override + Size getPictureSize() { + return mPictureSize; + } + @Override boolean setAspectRatio(AspectRatio ratio) { if (ratio != null && mPreviewSizes.isEmpty()) { @@ -653,6 +684,9 @@ private void collectCameraInfo() { } mPictureSizes.clear(); collectPictureSizes(mPictureSizes, map); + if (mPictureSize == null) { + mPictureSize = mPictureSizes.sizes(mAspectRatio).last(); + } for (AspectRatio ratio : mPreviewSizes.ratios()) { if (!mPictureSizes.ratios().contains(ratio)) { mPreviewSizes.remove(ratio); @@ -674,8 +708,7 @@ private void prepareStillImageReader() { if (mStillImageReader != null) { mStillImageReader.close(); } - Size largest = mPictureSizes.sizes(mAspectRatio).last(); - mStillImageReader = ImageReader.newInstance(largest.getWidth(), largest.getHeight(), + mStillImageReader = ImageReader.newInstance(mPictureSize.getWidth(), mPictureSize.getHeight(), ImageFormat.JPEG, 1); mStillImageReader.setOnImageAvailableListener(mOnImageAvailableListener, null); } @@ -728,6 +761,20 @@ void startCaptureSession() { } } + @Override + public void resumePreview() { + startCaptureSession(); + } + + @Override + public void pausePreview() { + try { + mCaptureSession.stopRepeating(); + } catch (CameraAccessException e) { + e.printStackTrace(); + } + } + public Surface getPreviewSurface() { if (mPreviewSurface != null) { return mPreviewSurface; diff --git a/android/src/main/java/com/google/android/cameraview/CameraView.java b/android/src/main/java/com/google/android/cameraview/CameraView.java index 43297b6fe..f307527c5 100644 --- a/android/src/main/java/com/google/android/cameraview/CameraView.java +++ b/android/src/main/java/com/google/android/cameraview/CameraView.java @@ -37,6 +37,7 @@ import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Set; +import java.util.SortedSet; public class CameraView extends FrameLayout { @@ -219,6 +220,7 @@ protected Parcelable onSaveInstanceState() { state.zoom = getZoom(); state.whiteBalance = getWhiteBalance(); state.scanning = getScanning(); + state.pictureSize = getPictureSize(); return state; } @@ -238,6 +240,7 @@ protected void onRestoreInstanceState(Parcelable state) { setZoom(ss.zoom); setWhiteBalance(ss.whiteBalance); setScanning(ss.scanning); + setPictureSize(ss.pictureSize); } public void setUsingCamera2Api(boolean useCamera2) { @@ -402,6 +405,31 @@ public void setAspectRatio(@NonNull AspectRatio ratio) { public AspectRatio getAspectRatio() { return mImpl.getAspectRatio(); } + + /** + * Gets all the picture sizes for particular ratio supported by the current camera. + * + * @param ratio {@link AspectRatio} for which the available image sizes will be returned. + */ + public SortedSet getAvailablePictureSizes(@NonNull AspectRatio ratio) { + return mImpl.getAvailablePictureSizes(ratio); + } + + /** + * Sets the size of taken pictures. + * + * @param size The {@link Size} to be set. + */ + public void setPictureSize(@NonNull Size size) { + mImpl.setPictureSize(size); + } + + /** + * Gets the size of pictures that will be taken. + */ + public Size getPictureSize() { + return mImpl.getPictureSize(); + } /** * Enables or disables the continuous auto-focus mode. When the current camera doesn't support @@ -494,6 +522,14 @@ public boolean record(String path, int maxDuration, int maxFileSize, public void stopRecording() { mImpl.stopRecording(); } + + public void resumePreview() { + mImpl.resumePreview(); + } + + public void pausePreview() { + mImpl.pausePreview(); + } public void setPreviewTexture(SurfaceTexture surfaceTexture) { mImpl.setPreviewTexture(surfaceTexture); @@ -590,6 +626,8 @@ protected static class SavedState extends BaseSavedState { int whiteBalance; boolean scanning; + + Size pictureSize; @SuppressWarnings("WrongConstant") public SavedState(Parcel source, ClassLoader loader) { @@ -602,6 +640,7 @@ public SavedState(Parcel source, ClassLoader loader) { zoom = source.readFloat(); whiteBalance = source.readInt(); scanning = source.readByte() != 0; + pictureSize = source.readParcelable(loader); } public SavedState(Parcelable superState) { @@ -619,6 +658,7 @@ public void writeToParcel(Parcel out, int flags) { out.writeFloat(zoom); out.writeInt(whiteBalance); out.writeByte((byte) (scanning ? 1 : 0)); + out.writeParcelable(pictureSize, flags); } public static final Creator CREATOR diff --git a/android/src/main/java/com/google/android/cameraview/CameraViewImpl.java b/android/src/main/java/com/google/android/cameraview/CameraViewImpl.java index 3a332969f..306c65c1d 100644 --- a/android/src/main/java/com/google/android/cameraview/CameraViewImpl.java +++ b/android/src/main/java/com/google/android/cameraview/CameraViewImpl.java @@ -21,6 +21,7 @@ import android.graphics.SurfaceTexture; import java.util.Set; +import java.util.SortedSet; abstract class CameraViewImpl { @@ -51,6 +52,12 @@ View getView() { abstract int getFacing(); abstract Set getSupportedAspectRatios(); + + abstract SortedSet getAvailablePictureSizes(AspectRatio ratio); + + abstract void setPictureSize(Size size); + + abstract Size getPictureSize(); /** * @return {@code true} if the aspect ratio was changed. @@ -91,6 +98,10 @@ abstract boolean record(String path, int maxDuration, int maxFileSize, abstract void setScanning(boolean isScanning); abstract boolean getScanning(); + + abstract public void resumePreview(); + + abstract public void pausePreview(); abstract public void setPreviewTexture(SurfaceTexture surfaceTexture); diff --git a/android/src/main/java/com/google/android/cameraview/Size.java b/android/src/main/java/com/google/android/cameraview/Size.java index d221bcbd3..d80a12db1 100644 --- a/android/src/main/java/com/google/android/cameraview/Size.java +++ b/android/src/main/java/com/google/android/cameraview/Size.java @@ -16,12 +16,14 @@ package com.google.android.cameraview; +import android.os.Parcel; +import android.os.Parcelable; import android.support.annotation.NonNull; /** * Immutable class for describing width and height dimensions in pixels. */ -public class Size implements Comparable { +public class Size implements Comparable, Parcelable { private final int mWidth; private final int mHeight; @@ -36,6 +38,20 @@ public Size(int width, int height) { mWidth = width; mHeight = height; } + + public static Size parse(String s) { + int position = s.indexOf('x'); + if (position == -1) { + throw new IllegalArgumentException("Malformed size: " + s); + } + try { + int width = Integer.parseInt(s.substring(0, position)); + int height = Integer.parseInt(s.substring(position + 1)); + return new Size(width, height); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("Malformed size: " + s, e); + } + } public int getWidth() { return mWidth; @@ -75,5 +91,29 @@ public int hashCode() { public int compareTo(@NonNull Size another) { return mWidth * mHeight - another.mWidth * another.mHeight; } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(mWidth); + dest.writeInt(mHeight); + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + @Override + public Size createFromParcel(Parcel source) { + int width = source.readInt(); + int height = source.readInt(); + return new Size(width, height); + } + @Override + public Size[] newArray(int size) { + return new Size[size]; + } + }; } diff --git a/android/src/main/java/org/reactnative/camera/CameraModule.java b/android/src/main/java/org/reactnative/camera/CameraModule.java index 99aa93af7..b4d0f2940 100644 --- a/android/src/main/java/org/reactnative/camera/CameraModule.java +++ b/android/src/main/java/org/reactnative/camera/CameraModule.java @@ -12,6 +12,7 @@ import org.reactnative.camera.tasks.ResolveTakenPictureAsyncTask; import org.reactnative.camera.utils.ScopedContext; import org.reactnative.facedetector.RNFaceDetector; +import com.google.android.cameraview.Size; import javax.annotation.Nullable; import java.io.ByteArrayOutputStream; @@ -20,6 +21,7 @@ import java.util.HashMap; import java.util.Map; import java.util.Set; +import java.util.SortedSet; public class CameraModule extends ReactContextBaseJavaModule { private static final String TAG = "CameraModule"; @@ -179,6 +181,48 @@ private Map getBarCodeConstants() { } }); } + + @ReactMethod + public void pausePreview(final int viewTag) { + final ReactApplicationContext context = getReactApplicationContext(); + UIManagerModule uiManager = context.getNativeModule(UIManagerModule.class); + uiManager.addUIBlock(new UIBlock() { + @Override + public void execute(NativeViewHierarchyManager nativeViewHierarchyManager) { + final RNCameraView cameraView; + + try { + cameraView = (RNCameraView) nativeViewHierarchyManager.resolveView(viewTag); + if (cameraView.isCameraOpened()) { + cameraView.pausePreview(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + } + + @ReactMethod + public void resumePreview(final int viewTag) { + final ReactApplicationContext context = getReactApplicationContext(); + UIManagerModule uiManager = context.getNativeModule(UIManagerModule.class); + uiManager.addUIBlock(new UIBlock() { + @Override + public void execute(NativeViewHierarchyManager nativeViewHierarchyManager) { + final RNCameraView cameraView; + + try { + cameraView = (RNCameraView) nativeViewHierarchyManager.resolveView(viewTag); + if (cameraView.isCameraOpened()) { + cameraView.resumePreview(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + } @ReactMethod public void takePicture(final ReadableMap options, final int viewTag, final Promise promise) { @@ -221,7 +265,7 @@ public void execute(NativeViewHierarchyManager nativeViewHierarchyManager) { promise.reject("E_CAMERA_UNAVAILABLE", "Camera is not running"); } } catch (Exception e) { - promise.reject("E_CAMERA_BAD_VIEWTAG", "recordAsync: Expected a Camera component"); + promise.reject("E_CAPTURE_FAILED", e.getMessage()); } } }); @@ -274,4 +318,31 @@ public void execute(NativeViewHierarchyManager nativeViewHierarchyManager) { } }); } + @ReactMethod + public void getAvailablePictureSizes(final String ratio, final int viewTag, final Promise promise) { + final ReactApplicationContext context = getReactApplicationContext(); + UIManagerModule uiManager = context.getNativeModule(UIManagerModule.class); + uiManager.addUIBlock(new UIBlock() { + @Override + public void execute(NativeViewHierarchyManager nativeViewHierarchyManager) { + final RNCameraView cameraView; + + try { + cameraView = (RNCameraView) nativeViewHierarchyManager.resolveView(viewTag); + WritableArray result = Arguments.createArray(); + if (cameraView.isCameraOpened()) { + SortedSet sizes = cameraView.getAvailablePictureSizes(AspectRatio.parse(ratio)); + for (Size size : sizes) { + result.pushString(size.toString()); + } + promise.resolve(result); + } else { + promise.reject("E_CAMERA_UNAVAILABLE", "Camera is not running"); + } + } catch (Exception e) { + promise.reject("E_CAMERA_BAD_VIEWTAG", "getAvailablePictureSizesAsync: Expected a Camera component"); + } + } + }); + } } diff --git a/android/src/main/java/org/reactnative/camera/CameraViewManager.java b/android/src/main/java/org/reactnative/camera/CameraViewManager.java index 445360c2e..157678c7a 100644 --- a/android/src/main/java/org/reactnative/camera/CameraViewManager.java +++ b/android/src/main/java/org/reactnative/camera/CameraViewManager.java @@ -7,6 +7,7 @@ import com.facebook.react.uimanager.ViewGroupManager; import com.facebook.react.uimanager.annotations.ReactProp; import com.google.android.cameraview.AspectRatio; +import com.google.android.cameraview.Size; import java.util.ArrayList; import java.util.List; @@ -21,7 +22,8 @@ public enum Events { EVENT_ON_BARCODES_DETECTED("onGoogleVisionBarcodesDetected"), EVENT_ON_FACE_DETECTION_ERROR("onFaceDetectionError"), EVENT_ON_BARCODE_DETECTION_ERROR("onGoogleVisionBarcodeDetectionError"), - EVENT_ON_TEXT_RECOGNIZED("onTextRecognized"); + EVENT_ON_TEXT_RECOGNIZED("onTextRecognized"), + EVENT_ON_PICTURE_SAVED("onPictureSaved"); private final String mName; @@ -98,6 +100,11 @@ public void setZoom(RNCameraView view, float zoom) { public void setWhiteBalance(RNCameraView view, int whiteBalance) { view.setWhiteBalance(whiteBalance); } + + @ReactProp(name = "pictureSize") + public void setPictureSize(RNCameraView view, String size) { + view.setPictureSize(Size.parse(size)); + } @ReactProp(name = "barCodeTypes") public void setBarCodeTypes(RNCameraView view, ReadableArray barCodeTypes) { diff --git a/android/src/main/java/org/reactnative/camera/RNCameraView.java b/android/src/main/java/org/reactnative/camera/RNCameraView.java index 764b2d446..78d8bcb45 100644 --- a/android/src/main/java/org/reactnative/camera/RNCameraView.java +++ b/android/src/main/java/org/reactnative/camera/RNCameraView.java @@ -34,7 +34,7 @@ import java.util.concurrent.ConcurrentLinkedQueue; public class RNCameraView extends CameraView implements LifecycleEventListener, BarCodeScannerAsyncTaskDelegate, FaceDetectorAsyncTaskDelegate, - BarcodeDetectorAsyncTaskDelegate, TextRecognizerAsyncTaskDelegate { + BarcodeDetectorAsyncTaskDelegate, TextRecognizerAsyncTaskDelegate, PictureSavedDelegate { private ThemedReactContext mThemedReactContext; private Queue mPictureTakenPromises = new ConcurrentLinkedQueue<>(); private Map mPictureTakenOptions = new ConcurrentHashMap<>(); @@ -86,8 +86,11 @@ public void onMountError(CameraView cameraView) { public void onPictureTaken(CameraView cameraView, final byte[] data) { Promise promise = mPictureTakenPromises.poll(); ReadableMap options = mPictureTakenOptions.remove(promise); + if (options.hasKey("fastMode") && options.getBoolean("fastMode")) { + promise.resolve(null); + } final File cacheDirectory = mPictureTakenDirectories.remove(promise); - new ResolveTakenPictureAsyncTask(data, promise, options, cacheDirectory).execute(); + new ResolveTakenPictureAsyncTask(data, promise, options, cacheDirectory, RNCameraView.this).execute(); } @Override @@ -223,7 +226,19 @@ public void takePicture(ReadableMap options, final Promise promise, File cacheDi MediaActionSound sound = new MediaActionSound(); sound.play(MediaActionSound.SHUTTER_CLICK); } - super.takePicture(); + try { + super.takePicture(); + } catch (Exception e) { + mPictureTakenPromises.remove(promise); + mPictureTakenOptions.remove(promise); + mPictureTakenDirectories.remove(promise); + throw e; + } + } + + @Override + public void onPictureSaved(WritableMap response) { + RNCameraViewHelper.emitPictureSavedEvent(this, response); } public void record(ReadableMap options, final Promise promise, File cacheDirectory) { diff --git a/android/src/main/java/org/reactnative/camera/RNCameraViewHelper.java b/android/src/main/java/org/reactnative/camera/RNCameraViewHelper.java index 6e73af26d..3934c6dd3 100644 --- a/android/src/main/java/org/reactnative/camera/RNCameraViewHelper.java +++ b/android/src/main/java/org/reactnative/camera/RNCameraViewHelper.java @@ -175,6 +175,14 @@ public static void emitCameraReadyEvent(ViewGroup view) { reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher().dispatchEvent(event); } + // Picture saved event + + public static void emitPictureSavedEvent(ViewGroup view, WritableMap response) { + PictureSavedEvent event = PictureSavedEvent.obtain(view.getId(), response); + ReactContext reactContext = (ReactContext) view.getContext(); + reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher().dispatchEvent(event); + } + // Face detection events public static void emitFacesDetectedEvent( diff --git a/android/src/main/java/org/reactnative/camera/events/PictureSavedEvent.java b/android/src/main/java/org/reactnative/camera/events/PictureSavedEvent.java new file mode 100644 index 000000000..3ca64437a --- /dev/null +++ b/android/src/main/java/org/reactnative/camera/events/PictureSavedEvent.java @@ -0,0 +1,46 @@ +package org.reactnative.camera.events; + +import android.support.v4.util.Pools; + +import com.facebook.react.bridge.WritableMap; +import com.facebook.react.uimanager.events.Event; +import com.facebook.react.uimanager.events.RCTEventEmitter; + +import org.reactnative.camera.CameraViewManager; + +public class PictureSavedEvent extends Event { + private static final Pools.SynchronizedPool EVENTS_POOL = new Pools.SynchronizedPool<>(5); + private PictureSavedEvent() {} + + private WritableMap mResponse; + + public static PictureSavedEvent obtain(int viewTag, WritableMap response) { + PictureSavedEvent event = EVENTS_POOL.acquire(); + if (event == null) { + event = new PictureSavedEvent(); + } + event.init(viewTag, response); + return event; + } + + private void init(int viewTag, WritableMap response) { + super.init(viewTag); + mResponse = response; + } + + @Override + public short getCoalescingKey() { + int hashCode = mResponse.getMap("data").getString("uri").hashCode() % Short.MAX_VALUE; + return (short) hashCode; + } + + @Override + public String getEventName() { + return CameraViewManager.Events.EVENT_ON_PICTURE_SAVED.toString(); + } + + @Override + public void dispatch(RCTEventEmitter rctEventEmitter) { + rctEventEmitter.receiveEvent(getViewTag(), getEventName(), mResponse); + } +} diff --git a/android/src/main/java/org/reactnative/camera/tasks/PictureSavedDelegate.java b/android/src/main/java/org/reactnative/camera/tasks/PictureSavedDelegate.java new file mode 100644 index 000000000..47a98bd95 --- /dev/null +++ b/android/src/main/java/org/reactnative/camera/tasks/PictureSavedDelegate.java @@ -0,0 +1,7 @@ +package org.reactnative.camera.tasks; + +import com.facebook.react.bridge.WritableMap; + +public interface PictureSavedDelegate { + void onPictureSaved(WritableMap response); +} diff --git a/android/src/main/java/org/reactnative/camera/tasks/ResolveTakenPictureAsyncTask.java b/android/src/main/java/org/reactnative/camera/tasks/ResolveTakenPictureAsyncTask.java index 4582cc138..e02fb539a 100644 --- a/android/src/main/java/org/reactnative/camera/tasks/ResolveTakenPictureAsyncTask.java +++ b/android/src/main/java/org/reactnative/camera/tasks/ResolveTakenPictureAsyncTask.java @@ -30,18 +30,14 @@ public class ResolveTakenPictureAsyncTask extends AsyncTask