Latest Threat Research:SANDWORM_MODE: Shai-Hulud-Style npm Worm Hijacks CI Workflows and Poisons AI Toolchains.Details
Socket
Book a DemoInstallSign in
Socket

capacitor-plugin-camera-preview

Package Overview
Dependencies
Maintainers
1
Versions
2
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

capacitor-plugin-camera-preview - npm Package Compare versions

Comparing version
0.0.2
to
0.0.3
+633
android/src/main/j...yufu/camera/preview/Camera1Control.java
/*
* Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
*/
package com.yufu.camera.preview;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.ImageFormat;
import android.graphics.Rect;
import android.graphics.SurfaceTexture;
import android.graphics.YuvImage;
import android.hardware.Camera;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.TextureView;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* 5.0以下相机API的封装。
*/
@SuppressWarnings("deprecation")
public class Camera1Control implements ICameraControl {
private int displayOrientation = 0;
private int cameraId = 0;
private int flashMode;
private AtomicBoolean takingPicture = new AtomicBoolean(false);
private AtomicBoolean abortingScan = new AtomicBoolean(false);
private Context context;
private Camera camera;
private Camera.Parameters parameters;
private PermissionCallback permissionCallback;
private Rect previewFrame = new Rect();
private PreviewView previewView;
private View displayView;
private int rotation = 0;
private OnDetectPictureCallback detectCallback;
private int previewFrameCount = 0;
private Camera.Size optSize;
/*
* 非扫描模式
*/
private final int MODEL_NOSCAN = 0;
/*
* 本地质量控制扫描模式
*/
private final int MODEL_SCAN = 1;
private int detectType = MODEL_NOSCAN;
public int getCameraRotation() {
return rotation;
}
public AtomicBoolean getAbortingScan() {
return abortingScan;
}
@Override
public void setDetectCallback(OnDetectPictureCallback callback) {
detectType = MODEL_SCAN;
detectCallback = callback;
}
private void onRequestDetect(byte[] data) {
// 相机已经关闭
if (camera == null || data == null || optSize == null) {
return;
}
YuvImage img = new YuvImage(data, ImageFormat.NV21, optSize.width, optSize.height, null);
ByteArrayOutputStream os = null;
try {
os = new ByteArrayOutputStream(data.length);
img.compressToJpeg(new Rect(0, 0, optSize.width, optSize.height), 80, os);
byte[] jpeg = os.toByteArray();
int status = detectCallback.onDetect(jpeg, getCameraRotation());
if (status == 0) {
clearPreviewCallback();
}
} catch (OutOfMemoryError e) {
// 内存溢出则取消当次操作
} finally {
try {
os.close();
} catch (Throwable e) {
e.printStackTrace();
}
}
}
@Override
public void setDisplayOrientation(@CameraPreview.Orientation int displayOrientation) {
this.displayOrientation = displayOrientation;
switch (displayOrientation) {
case CameraPreview.ORIENTATION_PORTRAIT:
rotation = 90;
break;
case CameraPreview.ORIENTATION_HORIZONTAL:
rotation = 0;
break;
case CameraPreview.ORIENTATION_INVERT:
rotation = 180;
break;
default:
rotation = 0;
}
previewView.requestLayout();
}
/**
* {@inheritDoc}
*/
@Override
public void refreshPermission() {
startPreview(true);
}
/**
* {@inheritDoc}
*/
@Override
public void setFlashMode(@FlashMode int flashMode) {
if (this.flashMode == flashMode) {
return;
}
this.flashMode = flashMode;
updateFlashMode(flashMode);
}
@Override
public int getFlashMode() {
return flashMode;
}
@Override
public void start() {
startPreview(false);
}
@Override
public void stop() {
if (camera != null) {
camera.setPreviewCallback(null);
stopPreview();
// 避免同步代码,为了先设置null后release
Camera tempC = camera;
camera = null;
tempC.release();
camera = null;
buffer = null;
}
}
private void stopPreview() {
if (camera != null) {
camera.stopPreview();
}
}
@Override
public void pause() {
if (camera != null) {
stopPreview();
}
setFlashMode(FLASH_MODE_OFF);
}
@Override
public void resume() {
takingPicture.set(false);
if (camera == null) {
openCamera();
} else {
System.out.println("-------------------------==");
System.out.println(previewView.textureView == null);
System.out.println(previewView.surfaceView == null);
previewView.textureView.setSurfaceTextureListener(surfaceTextureListener);
if (previewView.textureView.isAvailable()) {
startPreview(false);
}
}
}
@Override
public View getDisplayView() {
return displayView;
}
@Override
public void takePicture(final OnTakePictureCallback onTakePictureCallback) {
if (takingPicture.get()) {
return;
}
switch (displayOrientation) {
case CameraPreview.ORIENTATION_PORTRAIT:
parameters.setRotation(90);
break;
case CameraPreview.ORIENTATION_HORIZONTAL:
parameters.setRotation(0);
break;
case CameraPreview.ORIENTATION_INVERT:
parameters.setRotation(180);
break;
}
try {
Camera.Size picSize = getOptimalSize(camera.getParameters().getSupportedPictureSizes());
parameters.setPictureSize(picSize.width, picSize.height);
camera.setParameters(parameters);
takingPicture.set(true);
cancelAutoFocus();
CameraThreadPool.execute(new Runnable() {
@Override
public void run() {
camera.takePicture(null, null, new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
startPreview(false);
takingPicture.set(false);
if (onTakePictureCallback != null) {
onTakePictureCallback.onPictureTaken(data);
}
}
});
}
});
} catch (RuntimeException e) {
e.printStackTrace();
startPreview(false);
;
takingPicture.set(false);
}
}
@Override
public void setPermissionCallback(PermissionCallback callback) {
this.permissionCallback = callback;
}
public Camera1Control(Context context) {
this.context = context;
previewView = new PreviewView(context);
openCamera();
}
private void openCamera() {
setupDisplayView();
}
private void setupDisplayView() {
// final TextureView textureView = new TextureView(context);
// previewView.textureView = textureView;
// previewView.setTextureView(textureView);
// displayView = previewView;
// textureView.setSurfaceTextureListener(surfaceTextureListener);
final SurfaceView surfaceView = new SurfaceView(context);
previewView.surfaceView = surfaceView;
previewView.setSurfaceView(surfaceView);
displayView = previewView;
SurfaceHolder holder = surfaceView.getHolder();
holder.addCallback(surfaceHolderCallback);
}
private SurfaceTexture surfaceCache;
private byte[] buffer = null;
private void setPreviewCallbackImpl() {
if (buffer == null) {
buffer = new byte[displayView.getWidth()
* displayView.getHeight() * ImageFormat.getBitsPerPixel(ImageFormat.NV21) / 8];
}
if (camera != null && detectType == MODEL_SCAN) {
camera.addCallbackBuffer(buffer);
camera.setPreviewCallback(previewCallback);
}
}
private void clearPreviewCallback() {
if (camera != null && detectType == MODEL_SCAN) {
camera.setPreviewCallback(null);
stopPreview();
}
}
Camera.PreviewCallback previewCallback = new Camera.PreviewCallback() {
@Override
public void onPreviewFrame(final byte[] data, Camera camera) {
// 扫描成功阻止打开新线程处理
if (abortingScan.get()) {
return;
}
// 节流
if (previewFrameCount++ % 5 != 0) {
return;
}
// 在某些机型和某项项目中,某些帧的data的数据不符合nv21的格式,需要过滤,否则后续处理会导致crash
if (data.length != parameters.getPreviewSize().width * parameters.getPreviewSize().height * 1.5) {
return;
}
camera.addCallbackBuffer(buffer);
CameraThreadPool.execute(new Runnable() {
@Override
public void run() {
Camera1Control.this.onRequestDetect(data);
}
});
}
};
private void initCamera() {
try {
if (camera == null) {
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
for (int i = 0; i < Camera.getNumberOfCameras(); i++) {
Camera.getCameraInfo(i, cameraInfo);
if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
cameraId = i;
}
}
try {
camera = Camera.open(cameraId);
} catch (Throwable e) {
e.printStackTrace();
startPreview(true);
return;
}
}
if (parameters == null) {
parameters = camera.getParameters();
parameters.setPreviewFormat(ImageFormat.NV21);
}
opPreviewSize(previewView.getWidth(), previewView.getHeight());
camera.setPreviewTexture(surfaceCache);
setPreviewCallbackImpl();
startPreview(false);
} catch (IOException e) {
e.printStackTrace();
}
}
private SurfaceHolder.Callback surfaceHolderCallback = new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(@NonNull SurfaceHolder holder) {
}
@Override
public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
}
};
private TextureView.SurfaceTextureListener surfaceTextureListener = new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
surfaceCache = surface;
initCamera();
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
opPreviewSize(previewView.getWidth(), previewView.getHeight());
startPreview(false);
setPreviewCallbackImpl();
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
return false;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
setPreviewCallbackImpl();
}
};
// 开启预览
private void startPreview(boolean checkPermission) {
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
if (checkPermission && permissionCallback != null) {
permissionCallback.onRequestPermission();
}
return;
}
if (camera == null) {
initCamera();
} else {
camera.startPreview();
startAutoFocus();
}
}
private void cancelAutoFocus() {
camera.cancelAutoFocus();
CameraThreadPool.cancelAutoFocusTimer();
}
private void startAutoFocus() {
CameraThreadPool.createAutoFocusTimerTask(new Runnable() {
@Override
public void run() {
synchronized (Camera1Control.this) {
if (camera != null && !takingPicture.get()) {
try {
camera.autoFocus(new Camera.AutoFocusCallback() {
@Override
public void onAutoFocus(boolean success, Camera camera) {
}
});
} catch (Throwable e) {
// startPreview是异步实现,可能在某些机器上前几次调用会autofocus failß
}
}
}
}
});
}
private void opPreviewSize(int width, @SuppressWarnings("unused") int height) {
if (parameters != null && camera != null && width > 0) {
optSize = getOptimalSize(camera.getParameters().getSupportedPreviewSizes());
parameters.setPreviewSize(optSize.width, optSize.height);
previewView.setRatio(1.0f * optSize.width / optSize.height);
camera.setDisplayOrientation(getSurfaceOrientation());
stopPreview();
try {
camera.setParameters(parameters);
} catch (RuntimeException e) {
e.printStackTrace();
}
}
}
private Camera.Size getOptimalSize(List<Camera.Size> sizes) {
// int width = previewView.textureView.getWidth();
// int height = previewView.textureView.getHeight();
int width = previewView.surfaceView.getWidth();
int height = previewView.surfaceView.getHeight();
System.out.println("------------------------- getOptimalSize");
System.out.println(width);
System.out.println(height);
Camera.Size pictureSize = sizes.get(0);
List<Camera.Size> candidates = new ArrayList<>();
for (Camera.Size size : sizes) {
if (size.width >= width && size.height >= height && size.width * height == size.height * width) {
// 比例相同
candidates.add(size);
} else if (size.height >= width && size.width >= height && size.width * width == size.height * height) {
// 反比例
candidates.add(size);
}
}
if (!candidates.isEmpty()) {
return Collections.min(candidates, sizeComparator);
}
for (Camera.Size size : sizes) {
if (size.width > width && size.height > height) {
return size;
}
}
return pictureSize;
}
private Comparator<Camera.Size> sizeComparator = new Comparator<Camera.Size>() {
@Override
public int compare(Camera.Size lhs, Camera.Size rhs) {
return Long.signum((long) lhs.width * lhs.height - (long) rhs.width * rhs.height);
}
};
private void updateFlashMode(int flashMode) {
switch (flashMode) {
case FLASH_MODE_TORCH:
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
break;
case FLASH_MODE_OFF:
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
break;
case ICameraControl.FLASH_MODE_AUTO:
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
break;
default:
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
break;
}
camera.setParameters(parameters);
}
private int getSurfaceOrientation() {
@CameraPreview.Orientation
int orientation = displayOrientation;
switch (orientation) {
case CameraPreview.ORIENTATION_PORTRAIT:
return 90;
case CameraPreview.ORIENTATION_HORIZONTAL:
return 0;
case CameraPreview.ORIENTATION_INVERT:
return 180;
default:
return 90;
}
}
/**
* 有些相机匹配不到完美的比例。比如。我们的layout是4:3的。预览只有16:9
* 的,如果直接显示图片会拉伸,变形。缩放的话,又有黑边。所以我们采取的策略
* 是,等比例放大。这样预览的有一部分会超出屏幕。拍照后再进行裁剪处理。
*/
private class PreviewView extends RelativeLayout {
private TextureView textureView;
private SurfaceView surfaceView;
private float ratio = 0.75f;
void setTextureView(TextureView textureView) {
this.textureView = textureView;
removeAllViews();
addView(textureView);
}
void setSurfaceView(SurfaceView surfaceView) {
this.surfaceView = surfaceView;
removeAllViews();
addView(surfaceView);
}
void setRatio(float ratio) {
this.ratio = ratio;
requestLayout();
relayout(getWidth(), getHeight());
}
public PreviewView(Context context) {
super(context);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
relayout(w, h);
}
private void relayout(int w, int h) {
int width = w;
int height = h;
if (w < h) {
// 垂直模式,高度固定。
height = (int) (width * ratio);
} else {
// 水平模式,宽度固定。
width = (int) (height * ratio);
}
int l = (getWidth() - width) / 2;
int t = (getHeight() - height) / 2;
previewFrame.left = l;
previewFrame.top = t;
previewFrame.right = l + width;
previewFrame.bottom = t + height;
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
System.out.println("-------------------------== onLayout");
System.out.println(previewView.textureView != null);
System.out.println(previewView.surfaceView != null);
System.out.println(previewFrame.left);
System.out.println(previewFrame.top);
System.out.println(previewFrame.right);
System.out.println(previewFrame.bottom);
if(textureView != null){
textureView.layout(previewFrame.left, previewFrame.top, previewFrame.right, previewFrame.bottom);
}
if(surfaceView != null){
surfaceView.layout(previewFrame.left, previewFrame.top, previewFrame.right, previewFrame.bottom);
}
}
}
@Override
public Rect getPreviewFrame() {
return previewFrame;
}
}
/*
* Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
*/
package com.yufu.camera.preview;
import android.Manifest;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.CaptureFailure;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.TotalCaptureResult;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.media.Image;
import android.media.ImageReader;
import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
import android.util.Size;
import android.util.SparseIntArray;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.view.WindowManager;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class Camera2Control implements ICameraControl {
@Override
public void setDetectCallback(OnDetectPictureCallback callback) {
// TODO 暂时只用camera
}
@Override
public AtomicBoolean getAbortingScan() {
// TODO 暂时只用camera
return null;
}
/**
* Conversion from screen rotation to JPEG orientation.
*/
private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
private static final int MAX_PREVIEW_SIZE = 2048;
static {
ORIENTATIONS.append(Surface.ROTATION_0, 90);
ORIENTATIONS.append(Surface.ROTATION_90, 0);
ORIENTATIONS.append(Surface.ROTATION_180, 270);
ORIENTATIONS.append(Surface.ROTATION_270, 180);
}
private static final int STATE_PREVIEW = 0;
private static final int STATE_WAITING_FOR_LOCK = 1;
private static final int STATE_WAITING_FOR_CAPTURE = 2;
private static final int STATE_CAPTURING = 3;
private static final int STATE_PICTURE_TAKEN = 4;
private static final int MAX_PREVIEW_WIDTH = 1920;
private static final int MAX_PREVIEW_HEIGHT = 1080;
private int flashMode;
private int orientation = 0;
private int state = STATE_PREVIEW;
private Context context;
private OnTakePictureCallback onTakePictureCallback;
private PermissionCallback permissionCallback;
private String cameraId;
private TextureView textureView;
private Size previewSize;
private Rect previewFrame = new Rect();
private HandlerThread backgroundThread;
private Handler backgroundHandler;
private ImageReader imageReader;
private CameraCaptureSession captureSession;
private CameraDevice cameraDevice;
private CaptureRequest.Builder previewRequestBuilder;
private CaptureRequest previewRequest;
private Semaphore cameraLock = new Semaphore(1);
private int sensorOrientation;
@Override
public void start() {
startBackgroundThread();
if (textureView.isAvailable()) {
openCamera(textureView.getWidth(), textureView.getHeight());
textureView.setSurfaceTextureListener(surfaceTextureListener);
} else {
textureView.setSurfaceTextureListener(surfaceTextureListener);
}
}
@Override
public void stop() {
textureView.setSurfaceTextureListener(null);
closeCamera();
stopBackgroundThread();
}
@Override
public void pause() {
setFlashMode(FLASH_MODE_OFF);
}
@Override
public void resume() {
state = STATE_PREVIEW;
}
@Override
public View getDisplayView() {
return textureView;
}
@Override
public Rect getPreviewFrame() {
return previewFrame;
}
@Override
public void takePicture(OnTakePictureCallback callback) {
this.onTakePictureCallback = callback;
// 拍照第一步,对焦
lockFocus();
}
@Override
public void setPermissionCallback(PermissionCallback callback) {
this.permissionCallback = callback;
}
@Override
public void setDisplayOrientation(@CameraPreview.Orientation int displayOrientation) {
this.orientation = displayOrientation / 90;
}
@Override
public void refreshPermission() {
openCamera(textureView.getWidth(), textureView.getHeight());
}
@Override
public void setFlashMode(@FlashMode int flashMode) {
if (this.flashMode == flashMode) {
return;
}
this.flashMode = flashMode;
try {
previewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
updateFlashMode(flashMode, previewRequestBuilder);
previewRequest = previewRequestBuilder.build();
captureSession.setRepeatingRequest(previewRequest, captureCallback, backgroundHandler);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public int getFlashMode() {
return flashMode;
}
public Camera2Control(Context activity) {
this.context = activity;
textureView = new TextureView(activity);
}
private final TextureView.SurfaceTextureListener surfaceTextureListener = new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture texture, int width, int height) {
openCamera(width, height);
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture texture, int width, int height) {
configureTransform(width, height);
previewFrame.left = 0;
previewFrame.top = 0;
previewFrame.right = width;
previewFrame.bottom = height;
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture texture) {
stop();
return true;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture texture) {
}
};
private void openCamera(int width, int height) {
// 6.0+的系统需要检查系统权限 。
if (ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
requestCameraPermission();
return;
}
setUpCameraOutputs(width, height);
configureTransform(width, height);
CameraManager manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
try {
if (!cameraLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {
throw new RuntimeException("Time out waiting to lock camera opening.");
}
manager.openCamera(cameraId, deviceStateCallback, backgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
} catch (InterruptedException e) {
throw new RuntimeException("Interrupted while trying to lock camera opening.", e);
}
}
private final CameraDevice.StateCallback deviceStateCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened(@NonNull CameraDevice cameraDevice) {
cameraLock.release();
Camera2Control.this.cameraDevice = cameraDevice;
createCameraPreviewSession();
}
@Override
public void onDisconnected(@NonNull CameraDevice cameraDevice) {
cameraLock.release();
cameraDevice.close();
Camera2Control.this.cameraDevice = null;
}
@Override
public void onError(@NonNull CameraDevice cameraDevice, int error) {
cameraLock.release();
cameraDevice.close();
Camera2Control.this.cameraDevice = null;
}
};
private void createCameraPreviewSession() {
try {
SurfaceTexture texture = textureView.getSurfaceTexture();
assert texture != null;
texture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());
Surface surface = new Surface(texture);
previewRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
previewRequestBuilder.addTarget(surface);
updateFlashMode(this.flashMode, previewRequestBuilder);
cameraDevice.createCaptureSession(Arrays.asList(surface, imageReader.getSurface()),
new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
// The camera is already closed
if (null == cameraDevice) {
return;
}
captureSession = cameraCaptureSession;
try {
previewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
previewRequest = previewRequestBuilder.build();
captureSession.setRepeatingRequest(previewRequest,
captureCallback, backgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onConfigureFailed(
@NonNull CameraCaptureSession cameraCaptureSession) {
// TODO
}
}, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private final ImageReader.OnImageAvailableListener onImageAvailableListener = new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
if (onTakePictureCallback != null) {
Image image = reader.acquireNextImage();
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
image.close();
onTakePictureCallback.onPictureTaken(bytes);
}
}
};
private CameraCaptureSession.CaptureCallback captureCallback = new CameraCaptureSession.CaptureCallback() {
private void process(CaptureResult result) {
switch (state) {
case STATE_PREVIEW: {
break;
}
case STATE_WAITING_FOR_LOCK: {
Integer afState = result.get(CaptureResult.CONTROL_AF_STATE);
if (afState == null) {
captureStillPicture();
return;
}
switch (afState) {
case CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED:
case CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
case CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED: {
Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
if (aeState == null
|| aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED) {
captureStillPicture();
} else {
runPreCaptureSequence();
}
break;
}
default:
captureStillPicture();
}
break;
}
case STATE_WAITING_FOR_CAPTURE: {
Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
if (aeState == null
|| aeState == CaptureResult.CONTROL_AE_STATE_PRECAPTURE
|| aeState == CaptureRequest.CONTROL_AE_STATE_FLASH_REQUIRED) {
state = STATE_CAPTURING;
} else {
if (aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED) {
captureStillPicture();
}
}
break;
}
case STATE_CAPTURING: {
Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
if (aeState == null || aeState != CaptureResult.CONTROL_AE_STATE_PRECAPTURE) {
captureStillPicture();
}
break;
}
default:
break;
}
}
@Override
public void onCaptureProgressed(@NonNull CameraCaptureSession session,
@NonNull CaptureRequest request,
@NonNull CaptureResult partialResult) {
process(partialResult);
}
@Override
public void onCaptureCompleted(@NonNull CameraCaptureSession session,
@NonNull CaptureRequest request,
@NonNull TotalCaptureResult result) {
process(result);
}
};
private Size getOptimalSize(Size[] choices, int textureViewWidth,
int textureViewHeight, int maxWidth, int maxHeight, Size aspectRatio) {
List<Size> bigEnough = new ArrayList<>();
List<Size> notBigEnough = new ArrayList<>();
int w = aspectRatio.getWidth();
int h = aspectRatio.getHeight();
for (Size option : choices) {
if (option.getWidth() <= maxWidth && option.getHeight() <= maxHeight
&& option.getHeight() == option.getWidth() * h / w) {
if (option.getWidth() >= textureViewWidth
&& option.getHeight() >= textureViewHeight) {
bigEnough.add(option);
} else {
notBigEnough.add(option);
}
}
}
// Pick the smallest of those big enough. If there is no one big enough, pick
// the
// largest of those not big enough.
if (bigEnough.size() > 0) {
return Collections.min(bigEnough, sizeComparator);
}
for (Size option : choices) {
if (option.getWidth() >= maxWidth && option.getHeight() >= maxHeight) {
return option;
}
}
if (notBigEnough.size() > 0) {
return Collections.max(notBigEnough, sizeComparator);
}
return choices[0];
}
private Comparator<Size> sizeComparator = new Comparator<Size>() {
@Override
public int compare(Size lhs, Size rhs) {
return Long.signum((long) lhs.getWidth() * lhs.getHeight() - (long) rhs.getWidth() * rhs.getHeight());
}
};
private void requestCameraPermission() {
if (permissionCallback != null) {
permissionCallback.onRequestPermission();
}
}
@SuppressWarnings("SuspiciousNameCombination")
private void setUpCameraOutputs(int width, int height) {
CameraManager manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
try {
for (String cameraId : manager.getCameraIdList()) {
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);
if (facing != null && facing == CameraCharacteristics.LENS_FACING_FRONT) {
continue;
}
StreamConfigurationMap map = characteristics.get(
CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
if (map == null) {
continue;
}
// int preferredPictureSize = (int) (Math.max(textureView.getWidth(),
// textureView
// .getHeight()) * 1.5);
// preferredPictureSize = Math.min(preferredPictureSize, 2560);
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Point screenSize = new Point();
windowManager.getDefaultDisplay().getSize(screenSize);
int maxImageSize = Math.max(MAX_PREVIEW_SIZE, screenSize.y * 3 / 2);
Size size = getOptimalSize(map.getOutputSizes(ImageFormat.JPEG), textureView.getWidth(),
textureView.getHeight(), maxImageSize, maxImageSize, new Size(4, 3));
imageReader = ImageReader.newInstance(size.getWidth(), size.getHeight(),
ImageFormat.JPEG, 1);
imageReader.setOnImageAvailableListener(
onImageAvailableListener, backgroundHandler);
int displayRotation = orientation;
// noinspection ConstantConditions
sensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
boolean swappedDimensions = false;
switch (displayRotation) {
case Surface.ROTATION_0:
case Surface.ROTATION_180:
if (sensorOrientation == 90 || sensorOrientation == 270) {
swappedDimensions = true;
}
break;
case Surface.ROTATION_90:
case Surface.ROTATION_270:
if (sensorOrientation == 0 || sensorOrientation == 180) {
swappedDimensions = true;
}
break;
default:
}
int rotatedPreviewWidth = width;
int rotatedPreviewHeight = height;
int maxPreviewWidth = screenSize.x;
int maxPreviewHeight = screenSize.y;
if (swappedDimensions) {
rotatedPreviewWidth = height;
rotatedPreviewHeight = width;
maxPreviewWidth = screenSize.y;
maxPreviewHeight = screenSize.x;
}
maxPreviewWidth = Math.min(maxPreviewWidth, MAX_PREVIEW_WIDTH);
maxPreviewHeight = Math.min(maxPreviewHeight, MAX_PREVIEW_HEIGHT);
previewSize = getOptimalSize(map.getOutputSizes(SurfaceTexture.class),
rotatedPreviewWidth, rotatedPreviewHeight, maxPreviewWidth,
maxPreviewHeight, size);
this.cameraId = cameraId;
return;
}
} catch (CameraAccessException | NullPointerException e) {
e.printStackTrace();
}
}
private void closeCamera() {
try {
cameraLock.acquire();
if (null != captureSession) {
captureSession.close();
captureSession = null;
}
if (null != cameraDevice) {
cameraDevice.close();
cameraDevice = null;
}
if (null != imageReader) {
imageReader.close();
imageReader = null;
}
} catch (InterruptedException e) {
throw new RuntimeException("Interrupted while trying to lock camera closing.", e);
} finally {
cameraLock.release();
}
}
private void startBackgroundThread() {
backgroundThread = new HandlerThread("ocr_camera");
backgroundThread.start();
backgroundHandler = new Handler(backgroundThread.getLooper());
}
private void stopBackgroundThread() {
if (backgroundThread != null) {
backgroundThread.quitSafely();
backgroundThread = null;
backgroundHandler = null;
}
}
private void configureTransform(int viewWidth, int viewHeight) {
if (null == textureView || null == previewSize || null == context) {
return;
}
int rotation = orientation;
Matrix matrix = new Matrix();
RectF viewRect = new RectF(0, 0, viewWidth, viewHeight);
RectF bufferRect = new RectF(0, 0, previewSize.getHeight(), previewSize.getWidth());
float centerX = viewRect.centerX();
float centerY = viewRect.centerY();
if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) {
bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY());
matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);
float scale = Math.max(
(float) viewHeight / previewSize.getHeight(),
(float) viewWidth / previewSize.getWidth());
matrix.postScale(scale, scale, centerX, centerY);
matrix.postRotate(90 * (rotation - 2), centerX, centerY);
} else if (Surface.ROTATION_180 == rotation) {
matrix.postRotate(180, centerX, centerY);
}
textureView.setTransform(matrix);
}
// 拍照前,先对焦
private void lockFocus() {
if (captureSession != null && state == STATE_PREVIEW) {
try {
previewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
CameraMetadata.CONTROL_AF_TRIGGER_START);
state = STATE_WAITING_FOR_LOCK;
captureSession.capture(previewRequestBuilder.build(), captureCallback,
backgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
}
private void runPreCaptureSequence() {
try {
previewRequestBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
state = STATE_WAITING_FOR_CAPTURE;
captureSession.capture(previewRequestBuilder.build(), captureCallback,
backgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
// 拍照session
private void captureStillPicture() {
try {
if (null == context || null == cameraDevice) {
return;
}
final CaptureRequest.Builder captureBuilder = cameraDevice
.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
captureBuilder.addTarget(imageReader.getSurface());
captureBuilder.set(CaptureRequest.CONTROL_AF_MODE,
CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, getOrientation(orientation));
updateFlashMode(this.flashMode, captureBuilder);
CameraCaptureSession.CaptureCallback captureCallback = new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(@NonNull CameraCaptureSession session,
@NonNull CaptureRequest request,
@NonNull TotalCaptureResult result) {
unlockFocus();
}
@Override
public void onCaptureFailed(@NonNull CameraCaptureSession session,
@NonNull CaptureRequest request,
@NonNull CaptureFailure failure) {
super.onCaptureFailed(session, request, failure);
}
};
// 停止预览
captureSession.stopRepeating();
captureSession.capture(captureBuilder.build(), captureCallback, backgroundHandler);
state = STATE_PICTURE_TAKEN;
// unlockFocus();
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private int getOrientation(int rotation) {
return (ORIENTATIONS.get(rotation) + sensorOrientation + 270) % 360;
}
// 停止对焦
private void unlockFocus() {
try {
previewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
captureSession.capture(previewRequestBuilder.build(), captureCallback,
backgroundHandler);
state = STATE_PREVIEW;
// 预览
captureSession.setRepeatingRequest(previewRequest, captureCallback,
backgroundHandler);
textureView.setSurfaceTextureListener(surfaceTextureListener);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void updateFlashMode(@FlashMode int flashMode, CaptureRequest.Builder builder) {
switch (flashMode) {
case FLASH_MODE_TORCH:
builder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_TORCH);
break;
case FLASH_MODE_OFF:
builder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_OFF);
break;
case ICameraControl.FLASH_MODE_AUTO:
default:
builder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_SINGLE);
break;
}
}
}
package com.yufu.camera.preview;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.media.AudioManager;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.util.Base64;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.GestureDetector;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import androidx.fragment.app.Fragment;
public class CameraActivity extends Fragment {
public interface CameraPreviewListener {
void onPictureTaken(String originalPicture);
void onPictureTakenError(String message);
void onSnapshotTaken(String originalPicture);
void onSnapshotTakenError(String message);
void onFocusSet(int pointX, int pointY);
void onFocusSetError(String message);
void onBackButton();
void onCameraStarted();
void onStartRecordVideo();
void onStartRecordVideoError(String message);
void onStopRecordVideo(String file);
void onStopRecordVideoError(String error);
}
private CameraPreviewListener eventListener;
private static final String TAG = "CameraActivity";
public FrameLayout mainLayout;
public FrameLayout frameContainerLayout;
private boolean canTakePicture = true;
private View view;
private Camera.Parameters cameraParameters;
private Camera mCamera;
private int numberOfCameras;
private int cameraCurrentlyLocked;
private int currentQuality;
private enum RecordingState {
INITIALIZING,
STARTED,
STOPPED
}
private RecordingState mRecordingState = RecordingState.INITIALIZING;
private MediaRecorder mRecorder = null;
private String recordFilePath;
private float opacity;
// The first rear facing camera
private int defaultCameraId;
public String defaultCamera;
public boolean tapToTakePicture;
public boolean dragEnabled;
public boolean tapToFocus;
public boolean disableExifHeaderStripping;
public boolean storeToFile;
public boolean toBack;
public boolean enableOpacity = false;
public boolean enableZoom = false;
public int width;
public int height;
public int x;
public int y;
public void setEventListener(CameraPreviewListener listener) {
eventListener = listener;
}
private String appResourcesPackage;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
appResourcesPackage = getActivity().getPackageName();
// Inflate the layout for this fragment
view = inflater.inflate(getResources().getIdentifier("camera_activity", "layout", appResourcesPackage), container, false);
createCameraPreview();
return view;
}
private void createCameraPreview() {
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(width, height);
layoutParams.setMargins(x, y, 0, 0);
frameContainerLayout =
(FrameLayout) view.findViewById(getResources().getIdentifier("frame_container", "id", appResourcesPackage));
frameContainerLayout.setLayoutParams(layoutParams);
//video view
// mPreview = new Preview(getActivity(), enableOpacity);
ICameraControl iCameraControl = new Camera1Control(getActivity());
View preview = iCameraControl.getDisplayView();
mainLayout = (FrameLayout) view.findViewById(getResources().getIdentifier("video_view", "id", appResourcesPackage));
mainLayout.setLayoutParams(
new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT)
);
mainLayout.addView(preview);
mainLayout.setEnabled(false);
}
@Override
public void onResume() {
super.onResume();
}
@Override
public void onPause() {
super.onPause();
}
}
/*
* Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
*/
package com.yufu.camera.preview;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CameraThreadPool {
static Timer timerFocus = null;
/*
* 对焦频率
*/
static final long cameraScanInterval = 2000;
/*
* 线程池大小
*/
private static int poolCount = Runtime.getRuntime().availableProcessors();
private static ExecutorService fixedThreadPool = Executors.newFixedThreadPool(poolCount);
/**
* 给线程池添加任务
* @param runnable 任务
*/
public static void execute(Runnable runnable) {
fixedThreadPool.execute(runnable);
}
/**
* 创建一个定时对焦的timer任务
* @param runnable 对焦代码
* @return Timer Timer对象,用来终止自动对焦
*/
public static Timer createAutoFocusTimerTask(final Runnable runnable) {
if (timerFocus != null) {
return timerFocus;
}
timerFocus = new Timer();
TimerTask task = new TimerTask() {
@Override
public void run() {
runnable.run();
}
};
timerFocus.scheduleAtFixedRate(task, 0, cameraScanInterval);
return timerFocus;
}
/**
* 终止自动对焦任务,实际调用了cancel方法并且清空对象
* 但是无法终止执行中的任务,需额外处理
*
*/
public static void cancelAutoFocusTimer() {
if (timerFocus != null) {
timerFocus.cancel();
timerFocus = null;
}
}
}
package com.yufu.camera.preview;
import android.content.Context;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
class CustomSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
private final String TAG = "CustomSurfaceView";
CustomSurfaceView(Context context) {
super(context);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {}
}
package com.yufu.camera.preview;
import android.content.Context;
import android.graphics.SurfaceTexture;
import android.view.TextureView;
class CustomTextureView extends TextureView implements TextureView.SurfaceTextureListener {
private final String TAG = "CustomTextureView";
CustomTextureView(Context context) {
super(context);
}
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
return true;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {}
}
/*
* Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
*/
package com.yufu.camera.preview;
import android.graphics.Rect;
import android.view.View;
import androidx.annotation.IntDef;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* Android 5.0 相机的API发生很大的变化。些类屏蔽掉了 api的变化。相机的操作和功能,抽象剥离出来。
*/
public interface ICameraControl {
/**
* 闪光灯关 {@link #setFlashMode(int)}
*/
int FLASH_MODE_OFF = 0;
/**
* 闪光灯开 {@link #setFlashMode(int)}
*/
int FLASH_MODE_TORCH = 1;
/**
* 闪光灯自动 {@link #setFlashMode(int)}
*/
int FLASH_MODE_AUTO = 2;
@IntDef({FLASH_MODE_TORCH, FLASH_MODE_OFF, FLASH_MODE_AUTO})
@interface FlashMode {
}
/**
* 照相回调。
*/
interface OnTakePictureCallback {
void onPictureTaken(byte[] data);
}
/**
* 设置本地质量控制回调,如果不设置则视为不扫描调用本地质量控制代码。
*/
void setDetectCallback(OnDetectPictureCallback callback);
/**
* 预览回调
*/
interface OnDetectPictureCallback {
int onDetect(byte[] data, int rotation);
}
/**
* 打开相机。
*/
void start();
/**
* 关闭相机
*/
void stop();
void pause();
void resume();
/**
* 相机对应的预览视图。
* @return 预览视图
*/
View getDisplayView();
/**
* 看到的预览可能不是照片的全部。返回预览视图的全貌。
* @return 预览视图frame;
*/
Rect getPreviewFrame();
/**
* 拍照。结果在回调中获取。
* @param callback 拍照结果回调
*/
void takePicture(OnTakePictureCallback callback);
/**
* 设置权限回调,当手机没有拍照权限时,可在回调中获取。
* @param callback 权限回调
*/
void setPermissionCallback(PermissionCallback callback);
/**
* 设置水平方向
* @param displayOrientation 参数值见 {@link CameraPreview.Orientation}
*/
void setDisplayOrientation(@CameraPreview.Orientation int displayOrientation);
/**
* 获取到拍照权限时,调用些函数以继续。
*/
void refreshPermission();
/**
* 获取已经扫描成功,处理中
*/
AtomicBoolean getAbortingScan();
/**
* 设置闪光灯状态。
* @param flashMode {@link #FLASH_MODE_TORCH,#FLASH_MODE_OFF,#FLASH_MODE_AUTO}
*/
void setFlashMode(@FlashMode int flashMode);
/**
* 获取当前闪光灯状态
* @return 当前闪光灯状态 参见 {@link #setFlashMode(int)}
*/
@FlashMode
int getFlashMode();
}
/*
* Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
*/
package com.yufu.camera.preview;
public interface PermissionCallback {
boolean onRequestPermission();
}
+18
-5
package com.yufu.camera.preview;
import android.util.Log;
import androidx.annotation.IntDef;
public class CameraPreview {
public String echo(String value) {
Log.i("Echo", value);
return value;
}
/**
* 垂直方向 {@link #setOrientation(int)}
*/
public static final int ORIENTATION_PORTRAIT = 0;
/**
* 水平方向 {@link #setOrientation(int)}
*/
public static final int ORIENTATION_HORIZONTAL = 90;
/**
* 水平翻转方向 {@link #setOrientation(int)}
*/
public static final int ORIENTATION_INVERT = 270;
@IntDef({ORIENTATION_PORTRAIT, ORIENTATION_HORIZONTAL, ORIENTATION_INVERT})
public @interface Orientation {
}
}
package com.yufu.camera.preview;
import android.content.Context;
import android.graphics.Color;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraManager;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import com.getcapacitor.JSObject;

@@ -9,15 +19,54 @@ import com.getcapacitor.Plugin;

import java.util.Arrays;
@CapacitorPlugin(name = "CameraPreview")
public class CameraPreviewPlugin extends Plugin {
private CameraPreview implementation = new CameraPreview();
private final int containerViewId = 20;
@PluginMethod
public void echo(PluginCall call) {
String value = call.getString("value");
@PluginMethod
public void echo(PluginCall call) {
String value = call.getString("value");
JSObject ret = new JSObject();
call.resolve(ret);
}
JSObject ret = new JSObject();
ret.put("value", implementation.echo(value));
call.resolve(ret);
}
@PluginMethod
public void start(PluginCall call) throws CameraAccessException {
// CameraManager cameraManager = (CameraManager) getActivity().getSystemService(Context.CAMERA_SERVICE);
// String[] cameraIds = cameraManager.getCameraIdList();
//
// System.out.println("11111--------");
// System.out.println(Arrays.toString(cameraIds));
// System.out.println("11111--------");
bridge.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
FrameLayout containerView = getBridge().getActivity().findViewById(containerViewId);
if(containerView == null){
containerView = new FrameLayout(getActivity().getApplicationContext());
containerView.setId(containerViewId);
getBridge().getWebView().setBackgroundColor(Color.TRANSPARENT);
((ViewGroup) getBridge().getWebView().getParent()).addView(containerView);
CameraActivity fragment = new CameraActivity();
FragmentManager fragmentManager = bridge.getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(containerView.getId(),fragment);
fragmentTransaction.commit();
} else {
call.reject("camera already started");
}
}
});
}
@PluginMethod
public void stop(PluginCall call) {
}
}

@@ -0,0 +0,0 @@ export interface CameraPreviewPlugin {

export {};
//# sourceMappingURL=definitions.js.map

@@ -0,0 +0,0 @@ import type { CameraPreviewPlugin } from './definitions';

@@ -0,0 +0,0 @@ import { registerPlugin } from '@capacitor/core';

@@ -0,0 +0,0 @@ import { WebPlugin } from '@capacitor/core';

@@ -0,0 +0,0 @@ import { WebPlugin } from '@capacitor/core';

@@ -0,0 +0,0 @@ 'use strict';

@@ -1,1 +0,1 @@

{"version":3,"file":"plugin.cjs.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\r\nconst CameraPreview = registerPlugin('CameraPreview', {\r\n web: () => import('./web').then(m => new m.CameraPreviewWeb()),\r\n});\r\nexport * from './definitions';\r\nexport { CameraPreview };\r\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\r\nexport class CameraPreviewWeb extends WebPlugin {\r\n async echo(options) {\r\n console.log('ECHO', options);\r\n return options;\r\n }\r\n}\r\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":";;;;;;AACK,MAAC,aAAa,GAAGA,mBAAc,CAAC,eAAe,EAAE;AACtD,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,gBAAgB,EAAE,CAAC;AAClE,CAAC;;ACFM,MAAM,gBAAgB,SAASC,cAAS,CAAC;AAChD,IAAI,MAAM,IAAI,CAAC,OAAO,EAAE;AACxB,QAAQ,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AACrC,QAAQ,OAAO,OAAO,CAAC;AACvB,KAAK;AACL;;;;;;;;;"}
{"version":3,"file":"plugin.cjs.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst CameraPreview = registerPlugin('CameraPreview', {\n web: () => import('./web').then(m => new m.CameraPreviewWeb()),\n});\nexport * from './definitions';\nexport { CameraPreview };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nexport class CameraPreviewWeb extends WebPlugin {\n async echo(options) {\n console.log('ECHO', options);\n return options;\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":";;;;;;AACK,MAAC,aAAa,GAAGA,mBAAc,CAAC,eAAe,EAAE;AACtD,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,gBAAgB,EAAE,CAAC;AAClE,CAAC;;ACFM,MAAM,gBAAgB,SAASC,cAAS,CAAC;AAChD,IAAI,MAAM,IAAI,CAAC,OAAO,EAAE;AACxB,QAAQ,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AACrC,QAAQ,OAAO,OAAO,CAAC;AACvB,KAAK;AACL;;;;;;;;;"}

@@ -0,0 +0,0 @@ var capacitorCameraPreview = (function (exports, core) {

@@ -1,1 +0,1 @@

{"version":3,"file":"plugin.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\r\nconst CameraPreview = registerPlugin('CameraPreview', {\r\n web: () => import('./web').then(m => new m.CameraPreviewWeb()),\r\n});\r\nexport * from './definitions';\r\nexport { CameraPreview };\r\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\r\nexport class CameraPreviewWeb extends WebPlugin {\r\n async echo(options) {\r\n console.log('ECHO', options);\r\n return options;\r\n }\r\n}\r\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":";;;AACK,UAAC,aAAa,GAAGA,mBAAc,CAAC,eAAe,EAAE;IACtD,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,gBAAgB,EAAE,CAAC;IAClE,CAAC;;ICFM,MAAM,gBAAgB,SAASC,cAAS,CAAC;IAChD,IAAI,MAAM,IAAI,CAAC,OAAO,EAAE;IACxB,QAAQ,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,QAAQ,OAAO,OAAO,CAAC;IACvB,KAAK;IACL;;;;;;;;;;;;;;;;;"}
{"version":3,"file":"plugin.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst CameraPreview = registerPlugin('CameraPreview', {\n web: () => import('./web').then(m => new m.CameraPreviewWeb()),\n});\nexport * from './definitions';\nexport { CameraPreview };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nexport class CameraPreviewWeb extends WebPlugin {\n async echo(options) {\n console.log('ECHO', options);\n return options;\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":";;;AACK,UAAC,aAAa,GAAGA,mBAAc,CAAC,eAAe,EAAE;IACtD,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,gBAAgB,EAAE,CAAC;IAClE,CAAC;;ICFM,MAAM,gBAAgB,SAASC,cAAS,CAAC;IAChD,IAAI,MAAM,IAAI,CAAC,OAAO,EAAE;IACxB,QAAQ,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,QAAQ,OAAO,OAAO,CAAC;IACvB,KAAK;IACL;;;;;;;;;;;;;;;;;"}
{
"name": "capacitor-plugin-camera-preview",
"version": "0.0.2",
"version": "0.0.3",
"description": "相机预览",

@@ -5,0 +5,0 @@ "main": "dist/plugin.cjs.js",