Control commit
This commit is contained in:
parent
fbe834b8e2
commit
0f11ca12bc
13 changed files with 314 additions and 18 deletions
|
@ -20,6 +20,9 @@
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/Theme.CameraXTestAppJava"
|
android:theme="@style/Theme.CameraXTestAppJava"
|
||||||
tools:targetApi="31">
|
tools:targetApi="31">
|
||||||
|
<activity
|
||||||
|
android:name=".SegpassCameraActivity"
|
||||||
|
android:exported="false" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".CameraActivityNew"
|
android:name=".CameraActivityNew"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
|
|
|
@ -76,7 +76,7 @@ public class CameraActivityNew extends AppCompatActivity implements ActivityComp
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUpListeners() {
|
private void setUpListeners() {
|
||||||
binding.inCamera2.btnTakepicture.setOnClickListener(v -> mSegpassCamera.takePicture());
|
binding.inCamera2.btnTakePhoto.setOnClickListener(v -> mSegpassCamera.takePicture());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -39,7 +39,7 @@ public class MainActivity extends AppCompatActivity {
|
||||||
|
|
||||||
private void setListeners() {
|
private void setListeners() {
|
||||||
binding.goToCamera.setOnClickListener(v -> {
|
binding.goToCamera.setOnClickListener(v -> {
|
||||||
Intent intent = new Intent(this, CameraActivityNew.class);
|
Intent intent = new Intent(this, SegpassCameraActivity.class);
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,119 @@
|
||||||
|
package com.example.cameraxtestappjava;
|
||||||
|
|
||||||
|
import static com.example.cameraxtestappjava.segpass.SegpassCamera.REQUEST_CAMERA_PERMISSION;
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.content.pm.ActivityInfo;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import androidx.activity.EdgeToEdge;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.core.app.ActivityCompat;
|
||||||
|
import androidx.core.graphics.Insets;
|
||||||
|
import androidx.core.view.ViewCompat;
|
||||||
|
import androidx.core.view.WindowInsetsCompat;
|
||||||
|
|
||||||
|
import com.example.cameraxtestappjava.databinding.ActivitySegpassCameraBinding;
|
||||||
|
import com.example.cameraxtestappjava.segpass.camera.utils.SegpassCameraCallback;
|
||||||
|
import com.example.cameraxtestappjava.segpass.camera.utils.SegpassPermissionCallback;
|
||||||
|
import com.example.cameraxtestappjava.segpass.camera.view.SegpassCameraLayout;
|
||||||
|
|
||||||
|
public class SegpassCameraActivity extends AppCompatActivity implements ActivityCompat.OnRequestPermissionsResultCallback, SegpassCameraCallback, SegpassPermissionCallback {
|
||||||
|
|
||||||
|
ActivitySegpassCameraBinding binding;
|
||||||
|
SegpassCameraLayout cameraLayout;
|
||||||
|
|
||||||
|
@SuppressLint("SourceLockedOrientationActivity")
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
EdgeToEdge.enable(this);
|
||||||
|
|
||||||
|
binding = ActivitySegpassCameraBinding.inflate(getLayoutInflater());
|
||||||
|
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
|
||||||
|
setContentView(binding.getRoot());
|
||||||
|
|
||||||
|
setCamera();
|
||||||
|
|
||||||
|
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
|
||||||
|
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
|
||||||
|
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
|
||||||
|
return insets;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setCamera() {
|
||||||
|
cameraLayout = binding.sclCameraLayout;
|
||||||
|
cameraLayout.initSegpassCamera(this, this, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
cameraLayout.resumeCamera();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPause() {
|
||||||
|
cameraLayout.pauseCamera();
|
||||||
|
super.onPause();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
|
||||||
|
@NonNull int[] grantResults) {
|
||||||
|
if (requestCode == REQUEST_CAMERA_PERMISSION) {
|
||||||
|
if (grantResults.length != 2 || grantResults[0] != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
onPermissionDenied();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Camera callback
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPictureTakenSuccess(String base64) {
|
||||||
|
cameraLayout.showToast("Base64 generated.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPictureTakenFailError(String error) {
|
||||||
|
cameraLayout.showToast(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Camera state callback (just to validate if there was an error while initializing the camera)
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCameraInitError(String errorMessage) {
|
||||||
|
cameraLayout.showToast(errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Permissions callbck
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPermissionRequest() {
|
||||||
|
requestPermissions(new String[]{android.Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CAMERA_PERMISSION);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPermissionGranted() {
|
||||||
|
// Do nothing, use camera.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPermissionDenied() {
|
||||||
|
cameraLayout.showToast("No permissions granted, closing camera.");
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
}
|
|
@ -46,6 +46,7 @@ import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.concurrent.Semaphore;
|
import java.util.concurrent.Semaphore;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@ -57,7 +58,7 @@ public class SegpassCamera {
|
||||||
private static final String TAG = "SegpassCamera";
|
private static final String TAG = "SegpassCamera";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class variabels
|
* Class variables
|
||||||
*/
|
*/
|
||||||
AppCompatActivity mActivity;
|
AppCompatActivity mActivity;
|
||||||
SegpassPermissionCallback mPermissionListener;
|
SegpassPermissionCallback mPermissionListener;
|
||||||
|
@ -403,6 +404,13 @@ public class SegpassCamera {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates whether the camera's current rotation is different from the output shown in the
|
||||||
|
* preview {@link AutoFitTextureView}
|
||||||
|
*
|
||||||
|
* @param characteristics Camera characteristics
|
||||||
|
* @return boolean value for display rotation
|
||||||
|
*/
|
||||||
private boolean isSwappedDimensions(CameraCharacteristics characteristics) {
|
private boolean isSwappedDimensions(CameraCharacteristics characteristics) {
|
||||||
// Find out if we need to swap dimension to get the preview size relative to sensor
|
// Find out if we need to swap dimension to get the preview size relative to sensor
|
||||||
// coordinate.
|
// coordinate.
|
||||||
|
@ -429,12 +437,18 @@ public class SegpassCamera {
|
||||||
return swappedDimensions;
|
return swappedDimensions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtains configuration map to be applied to the preview surface
|
||||||
|
*
|
||||||
|
* @param characteristics Camera characteristics
|
||||||
|
* @return the configuration map for the {@link AutoFitTextureView}
|
||||||
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
private static StreamConfigurationMap getStreamConfigurationMap(CameraCharacteristics characteristics) {
|
private static StreamConfigurationMap getStreamConfigurationMap(CameraCharacteristics characteristics) {
|
||||||
// We don't use a back facing camera.
|
// We don't use a back facing camera.
|
||||||
Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);
|
Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);
|
||||||
|
|
||||||
// If facis is null, return
|
// If facing is null, return
|
||||||
if (facing == null) return null;
|
if (facing == null) return null;
|
||||||
if (facing == CameraMetadata.LENS_FACING_BACK) return null;
|
if (facing == CameraMetadata.LENS_FACING_BACK) return null;
|
||||||
|
|
||||||
|
@ -442,6 +456,15 @@ public class SegpassCamera {
|
||||||
CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
|
CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtains optimal preview size to be shown in {@link AutoFitTextureView}
|
||||||
|
*
|
||||||
|
* @param width Current {@link AutoFitTextureView} width
|
||||||
|
* @param height Current {@link AutoFitTextureView} height
|
||||||
|
* @param swappedDimensions Whether the preview surface is rotate in relation to the previwe
|
||||||
|
* @param map Configuration map to be applies to the preview surface
|
||||||
|
* @param largest Largest display (i.e. image) {@link Size} supported by the preview.
|
||||||
|
*/
|
||||||
private void getOptimalPreviewSize(int width, int height, boolean swappedDimensions, StreamConfigurationMap map, Size largest) {
|
private void getOptimalPreviewSize(int width, int height, boolean swappedDimensions, StreamConfigurationMap map, Size largest) {
|
||||||
Point displaySize = new Point();
|
Point displaySize = new Point();
|
||||||
mActivity.getWindowManager().getDefaultDisplay().getSize(displaySize);
|
mActivity.getWindowManager().getDefaultDisplay().getSize(displaySize);
|
||||||
|
@ -473,6 +496,11 @@ public class SegpassCamera {
|
||||||
maxPreviewHeight, largest);
|
maxPreviewHeight, largest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set image reader listeners
|
||||||
|
*
|
||||||
|
* @param largest Largest display (i.e. image) {@link Size} supported by the preview.
|
||||||
|
*/
|
||||||
private void setImageReaderListeners(Size largest) {
|
private void setImageReaderListeners(Size largest) {
|
||||||
mImageReader = ImageReader.newInstance(largest.getWidth(), largest.getHeight(),
|
mImageReader = ImageReader.newInstance(largest.getWidth(), largest.getHeight(),
|
||||||
ImageFormat.JPEG, /*maxImages*/2);
|
ImageFormat.JPEG, /*maxImages*/2);
|
||||||
|
@ -480,6 +508,9 @@ public class SegpassCamera {
|
||||||
mOnImageAvailableListener, mBackgroundHandler);
|
mOnImageAvailableListener, mBackgroundHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the preview surface aspect ratio considering the screen orientation/
|
||||||
|
*/
|
||||||
private void setPreviewAspectRatio() {
|
private void setPreviewAspectRatio() {
|
||||||
// We fit the aspect ratio of TextureView to the size of preview we picked.
|
// We fit the aspect ratio of TextureView to the size of preview we picked.
|
||||||
int orientation = mActivity.getResources().getConfiguration().orientation;
|
int orientation = mActivity.getResources().getConfiguration().orientation;
|
||||||
|
@ -647,8 +678,8 @@ public class SegpassCamera {
|
||||||
CameraManager manager = (CameraManager) mActivity.getSystemService(Context.CAMERA_SERVICE);
|
CameraManager manager = (CameraManager) mActivity.getSystemService(Context.CAMERA_SERVICE);
|
||||||
CameraCharacteristics characteristics = manager.getCameraCharacteristics(mCameraId);
|
CameraCharacteristics characteristics = manager.getCameraCharacteristics(mCameraId);
|
||||||
|
|
||||||
//
|
// Obtains list of image size supported by the selected camera sensor.
|
||||||
Size[] jpegSizes = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP).getOutputSizes(ImageFormat.JPEG);
|
Size[] jpegSizes = Objects.requireNonNull(characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)).getOutputSizes(ImageFormat.JPEG);
|
||||||
if (jpegSizes == null) throw new NullPointerException("Error taking picture");
|
if (jpegSizes == null) throw new NullPointerException("Error taking picture");
|
||||||
|
|
||||||
// Default dimensions
|
// Default dimensions
|
||||||
|
@ -677,6 +708,7 @@ public class SegpassCamera {
|
||||||
int rotation = mActivity.getWindowManager().getDefaultDisplay().getRotation();
|
int rotation = mActivity.getWindowManager().getDefaultDisplay().getRotation();
|
||||||
captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, getOrientation(rotation));
|
captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, getOrientation(rotation));
|
||||||
|
|
||||||
|
// Listens when the image is finally taken.
|
||||||
mCaptureImageReader.setOnImageAvailableListener(mOnImageAvailableListener, mBackgroundHandler);
|
mCaptureImageReader.setOnImageAvailableListener(mOnImageAvailableListener, mBackgroundHandler);
|
||||||
final CameraCaptureSession.CaptureCallback captureListener = new CameraCaptureSession.CaptureCallback() {
|
final CameraCaptureSession.CaptureCallback captureListener = new CameraCaptureSession.CaptureCallback() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -694,6 +726,7 @@ public class SegpassCamera {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Initialized the session to listen to a picture capture event.
|
||||||
mCameraDevice.createCaptureSession(outputSurfaces, new CameraCaptureSession.StateCallback() {
|
mCameraDevice.createCaptureSession(outputSurfaces, new CameraCaptureSession.StateCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onConfigured(@NonNull CameraCaptureSession session) {
|
public void onConfigured(@NonNull CameraCaptureSession session) {
|
||||||
|
@ -717,11 +750,24 @@ public class SegpassCamera {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the ImageReader for capturing a still picture.
|
||||||
|
*
|
||||||
|
* @param width Supported image width by surface and sensor.
|
||||||
|
* @param height Supported image height by surface and sensor.
|
||||||
|
* @return {@link ImageReader} object for the preview surface.
|
||||||
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
private static ImageReader getCaptureImageReader(int width, int height) {
|
private static ImageReader getCaptureImageReader(int width, int height) {
|
||||||
return ImageReader.newInstance(width, height, ImageFormat.JPEG, 1);
|
return ImageReader.newInstance(width, height, ImageFormat.JPEG, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtains orientation that will be applied to the captured image.
|
||||||
|
*
|
||||||
|
* @param rotation Rotation angle.
|
||||||
|
* @return Orientation value.
|
||||||
|
*/
|
||||||
private int getOrientation(int rotation) {
|
private int getOrientation(int rotation) {
|
||||||
// Sensor orientation is 90 for most devices, or 270 for some devices (eg. Nexus 5X)
|
// Sensor orientation is 90 for most devices, or 270 for some devices (eg. Nexus 5X)
|
||||||
// We have to take that into account and rotate JPEG properly.
|
// We have to take that into account and rotate JPEG properly.
|
||||||
|
|
|
@ -1,16 +1,29 @@
|
||||||
package com.example.cameraxtestappjava.segpass.camera.utils;
|
package com.example.cameraxtestappjava.segpass.camera.utils;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
import android.media.Image;
|
import android.media.Image;
|
||||||
import android.util.Base64;
|
import android.util.Base64;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
public class ImageSaverUtil implements Runnable {
|
public class ImageSaverUtil implements Runnable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tag for the {@link Log}
|
||||||
|
*/
|
||||||
|
private static final String TAG = "ImageSaverUtil";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The JPEG image
|
* The JPEG image
|
||||||
*/
|
*/
|
||||||
private final Image mImage;
|
private final Image mImage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback to return encoded image value in {@link Base64}
|
||||||
|
*/
|
||||||
private final ImageEncodingCallback mCallback;
|
private final ImageEncodingCallback mCallback;
|
||||||
|
|
||||||
public ImageSaverUtil(Image image, ImageEncodingCallback callback) {
|
public ImageSaverUtil(Image image, ImageEncodingCallback callback) {
|
||||||
|
@ -21,12 +34,35 @@ public class ImageSaverUtil implements Runnable {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
// Get image as byte data buffer
|
||||||
ByteBuffer buffer = mImage.getPlanes()[0].getBuffer();
|
ByteBuffer buffer = mImage.getPlanes()[0].getBuffer();
|
||||||
byte[] bytes = new byte[buffer.capacity()];
|
byte[] bytes = new byte[buffer.capacity()];
|
||||||
buffer.get(bytes);
|
buffer.get(bytes);
|
||||||
mCallback.onImageEncodeSuccess(Base64.encodeToString(bytes, Base64.NO_WRAP));
|
|
||||||
|
// Convert byte data to a Bitmap
|
||||||
|
Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
|
||||||
|
|
||||||
|
// Create a ByteArrayOutputStream to capture the compressed image data
|
||||||
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
// Compress the bitmap with JPEG format and desired quality (25% will do for this use case)
|
||||||
|
bitmap.compress(Bitmap.CompressFormat.JPEG, 25, outputStream);
|
||||||
|
|
||||||
|
// Get the compressed image data as a byte array
|
||||||
|
byte[] compressedImageData = outputStream.toByteArray();
|
||||||
|
|
||||||
|
// Encode the compressed data to Base64 string
|
||||||
|
String base64String = Base64.encodeToString(compressedImageData, Base64.NO_WRAP);
|
||||||
|
|
||||||
|
// Close the stream (optional, as ByteArrayOutputStream should close automatically)
|
||||||
|
outputStream.close();
|
||||||
|
|
||||||
|
// Return Base64 string on callback
|
||||||
|
mCallback.onImageEncodeSuccess(base64String);
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
Log.e(TAG, "Error encoding photo: " + e.getMessage());
|
||||||
mCallback.onImageEncodeFail(e.getMessage());
|
mCallback.onImageEncodeFail(e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
package com.example.cameraxtestappjava.segpass.camera.view;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
import android.widget.ImageButton;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
|
||||||
|
import com.example.cameraxtestappjava.R;
|
||||||
|
import com.example.cameraxtestappjava.segpass.SegpassCamera;
|
||||||
|
import com.example.cameraxtestappjava.segpass.camera.utils.SegpassCameraCallback;
|
||||||
|
import com.example.cameraxtestappjava.segpass.camera.utils.SegpassPermissionCallback;
|
||||||
|
|
||||||
|
public class SegpassCameraLayout extends FrameLayout {
|
||||||
|
private AppCompatActivity mActivity;
|
||||||
|
private AutoFitTextureView mTextureView;
|
||||||
|
private SegpassPermissionCallback mPermissionListener;
|
||||||
|
private SegpassCameraCallback mCameraCallback;
|
||||||
|
private SegpassCamera mCamera;
|
||||||
|
private ImageButton mTakePicture;
|
||||||
|
|
||||||
|
private final View rootView;
|
||||||
|
|
||||||
|
public SegpassCameraLayout(@NonNull Context context) {
|
||||||
|
super(context);
|
||||||
|
rootView = inflate(context, R.layout.segpass_camera_view, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SegpassCameraLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
rootView = inflate(context, R.layout.segpass_camera_view, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SegpassCameraLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||||
|
super(context, attrs, defStyleAttr);
|
||||||
|
rootView = inflate(context, R.layout.segpass_camera_view, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SegpassCameraLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||||
|
super(context, attrs, defStyleAttr, defStyleRes);
|
||||||
|
rootView = inflate(context, R.layout.segpass_camera_view, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param activity Parent activity where the camera is called from.
|
||||||
|
* @param listener {@link SegpassPermissionCallback} that deals with camera and storage permissions.
|
||||||
|
* @param cameraCallback {@link SegpassCameraCallback} that deals with operation results.
|
||||||
|
*/
|
||||||
|
public void initSegpassCamera(AppCompatActivity activity, SegpassPermissionCallback listener, SegpassCameraCallback cameraCallback) {
|
||||||
|
mActivity = activity;
|
||||||
|
mPermissionListener = listener;
|
||||||
|
mCameraCallback = cameraCallback;
|
||||||
|
mTextureView = rootView.findViewById(R.id.tvCameraTextureView);
|
||||||
|
mCamera = new SegpassCamera(mActivity, mTextureView, mPermissionListener, mCameraCallback);
|
||||||
|
mCamera.resumeCamera();
|
||||||
|
setUpListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setUpListeners() {
|
||||||
|
mTakePicture = rootView.findViewById(R.id.btnTakePhoto);
|
||||||
|
mTakePicture.setOnClickListener(v -> mCamera.takePicture());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resumeCamera() {
|
||||||
|
mCamera.resumeCamera();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void pauseCamera() {
|
||||||
|
mCamera.pauseCamera();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void showToast(String message) {
|
||||||
|
mCamera.showToast(message);
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
<include
|
<include
|
||||||
android:id="@+id/inCamera2"
|
android:id="@+id/inCamera2"
|
||||||
layout="@layout/camera_autofit_view"
|
layout="@layout/segpass_camera_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent" />
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
<include
|
<include
|
||||||
android:id="@+id/inCamera2"
|
android:id="@+id/inCamera2"
|
||||||
layout="@layout/camera_autofit_view"
|
layout="@layout/segpass_camera_view"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent" />
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
|
|
14
app/src/main/res/layout/activity_segpass_camera.xml
Normal file
14
app/src/main/res/layout/activity_segpass_camera.xml
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/main"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context=".SegpassCameraActivity">
|
||||||
|
|
||||||
|
<com.example.cameraxtestappjava.segpass.camera.view.SegpassCameraLayout
|
||||||
|
android:id="@+id/sclCameraLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -11,11 +11,11 @@
|
||||||
android:id="@+id/tvCameraTextureView"
|
android:id="@+id/tvCameraTextureView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_above="@id/btn_takepicture"
|
android:layout_above="@id/btnTakePhoto"
|
||||||
android:layout_alignParentTop="true" />
|
android:layout_alignParentTop="true" />
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/btn_takepicture"
|
android:id="@+id/btnTakePhoto"
|
||||||
android:layout_width="80dip"
|
android:layout_width="80dip"
|
||||||
android:layout_height="80dip"
|
android:layout_height="80dip"
|
||||||
android:layout_alignParentBottom="true"
|
android:layout_alignParentBottom="true"
|
||||||
|
@ -24,6 +24,6 @@
|
||||||
android:contentDescription="take_photo"
|
android:contentDescription="take_photo"
|
||||||
android:padding="10dip"
|
android:padding="10dip"
|
||||||
android:scaleType="fitCenter"
|
android:scaleType="fitCenter"
|
||||||
android:src="@drawable/capture_button_video" />
|
android:src="@drawable/capture_picture_button" />
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="#000000"
|
android:background="#000000"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical">
|
||||||
tools:context=".MainActivity">
|
|
||||||
|
|
||||||
<com.example.cameraxtestappjava.segpass.camera.view.AutoFitTextureView
|
<com.example.cameraxtestappjava.segpass.camera.view.AutoFitTextureView
|
||||||
android:id="@+id/tvCameraTextureView"
|
android:id="@+id/tvCameraTextureView"
|
||||||
|
@ -14,13 +12,13 @@
|
||||||
android:layout_height="wrap_content"/>
|
android:layout_height="wrap_content"/>
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/btn_takepicture"
|
android:id="@+id/btnTakePhoto"
|
||||||
android:layout_width="80dip"
|
android:layout_width="80dip"
|
||||||
android:layout_height="80dip"
|
android:layout_height="80dip"
|
||||||
android:background="?android:selectableItemBackground"
|
android:background="?android:selectableItemBackground"
|
||||||
android:padding="10dip"
|
android:padding="10dip"
|
||||||
android:layout_gravity="bottom|center"
|
android:layout_gravity="bottom|center"
|
||||||
android:scaleType="fitCenter"
|
android:scaleType="fitCenter"
|
||||||
android:src="@drawable/capture_button_video" />
|
android:src="@drawable/capture_picture_button" />
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
Loading…
Reference in a new issue