diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1f5535a4..3971059b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -16,7 +16,7 @@ android:theme="@style/AppTheme"> + android:screenOrientation="landscape"> diff --git a/app/src/main/java/com/simplemobiletools/camera/MainActivity.java b/app/src/main/java/com/simplemobiletools/camera/MainActivity.java index 2f08730a..9df33b36 100644 --- a/app/src/main/java/com/simplemobiletools/camera/MainActivity.java +++ b/app/src/main/java/com/simplemobiletools/camera/MainActivity.java @@ -4,82 +4,50 @@ import android.hardware.Camera; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.util.Log; -import android.view.SurfaceHolder; import android.view.SurfaceView; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; +import android.widget.RelativeLayout; import butterknife.Bind; import butterknife.ButterKnife; -public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback { - private static final String TAG = MainActivity.class.getSimpleName(); +public class MainActivity extends AppCompatActivity { + @Bind(R.id.viewHolder) RelativeLayout viewHolder; - @Bind(R.id.surfaceView) SurfaceView surfaceView; - private Camera camera; - private boolean isOpen; - private SurfaceHolder surfaceHolder; + private static final String TAG = Preview.class.getSimpleName(); + private Preview preview; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + requestWindowFeature(Window.FEATURE_NO_TITLE); + getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); + setContentView(R.layout.activity_main); ButterKnife.bind(this); - surfaceHolder = surfaceView.getHolder(); - surfaceHolder.addCallback(this); + preview = new Preview(this, (SurfaceView) findViewById(R.id.surfaceView)); + preview.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); + viewHolder.addView(preview); } @Override protected void onResume() { super.onResume(); - openCamera(); + + try { + Camera camera = Camera.open(0); + preview.setCamera(camera); + } catch (Exception e) { + Log.e(TAG, "onResume IOException " + e.getMessage()); + } } @Override protected void onPause() { super.onPause(); - releaseCamera(); - } - - private void openCamera() { - isOpen = false; - - try { - releaseCamera(); - camera = Camera.open(); - - if (camera != null) { - isOpen = true; - camera.setDisplayOrientation(90); - camera.setPreviewDisplay(surfaceHolder); - camera.startPreview(); - } - } catch (Exception e) { - Log.e(TAG, "openCamera exception " + e.getMessage()); - } - } - - private void releaseCamera() { - if (camera != null) { - camera.release(); - camera = null; - } - } - - @Override - public void surfaceCreated(SurfaceHolder holder) { - surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); - openCamera(); - } - - @Override - public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { - - } - - @Override - public void surfaceDestroyed(SurfaceHolder holder) { - if (camera != null) { - camera.stopPreview(); - } + preview.releaseCamera(); } } diff --git a/app/src/main/java/com/simplemobiletools/camera/Preview.java b/app/src/main/java/com/simplemobiletools/camera/Preview.java new file mode 100644 index 00000000..3bd9ecd8 --- /dev/null +++ b/app/src/main/java/com/simplemobiletools/camera/Preview.java @@ -0,0 +1,159 @@ +package com.simplemobiletools.camera; + +import android.content.Context; +import android.hardware.Camera; +import android.util.Log; +import android.view.SurfaceHolder; +import android.view.SurfaceView; +import android.view.View; +import android.view.ViewGroup; + +import java.io.IOException; +import java.util.List; + +public class Preview extends ViewGroup implements SurfaceHolder.Callback { + private static final String TAG = Preview.class.getSimpleName(); + + private SurfaceHolder surfaceHolder; + private Camera camera; + private List supportedPreviewSizes; + private SurfaceView surfaceView; + private Camera.Size previewSize; + + public Preview(Context context) { + super(context); + } + + public Preview(Context context, SurfaceView sv) { + super(context); + + surfaceView = sv; + surfaceHolder = surfaceView.getHolder(); + surfaceHolder.addCallback(this); + surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); + } + + public void setCamera(Camera newCamera) { + if (camera == newCamera) { + return; + } + + releaseCamera(); + camera = newCamera; + + if (camera != null) { + supportedPreviewSizes = camera.getParameters().getSupportedPreviewSizes(); + requestLayout(); + + final Camera.Parameters params = camera.getParameters(); + params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); + camera.setParameters(params); + } + } + + public void releaseCamera() { + if (camera != null) { + camera.stopPreview(); + camera.release(); + camera = null; + } + } + + @Override + public void surfaceCreated(SurfaceHolder holder) { + try { + if (camera != null) { + camera.setPreviewDisplay(holder); + } + } catch (IOException e) { + Log.e(TAG, "surfaceCreated IOException " + e.getMessage()); + } + } + + @Override + public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { + if (camera != null) { + final Camera.Parameters parameters = camera.getParameters(); + parameters.setPreviewSize(previewSize.width, previewSize.height); + requestLayout(); + + camera.setParameters(parameters); + camera.startPreview(); + } + } + + @Override + public void surfaceDestroyed(SurfaceHolder holder) { + if (camera != null) { + camera.stopPreview(); + } + } + + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + if (changed && getChildCount() > 0) { + final View child = getChildAt(0); + + final int width = r - l; + final int height = b - t; + + int previewWidth = width; + int previewHeight = height; + if (previewSize != null) { + previewWidth = previewSize.width; + previewHeight = previewSize.height; + } + + if (width * previewHeight > height * previewWidth) { + final int scaledChildWidth = previewWidth * height / previewHeight; + child.layout((width - scaledChildWidth) / 2, 0, (width + scaledChildWidth) / 2, height); + } else { + final int scaledChildHeight = previewHeight * width / previewWidth; + child.layout(0, (height - scaledChildHeight) / 2, width, (height + scaledChildHeight) / 2); + } + } + } + + private Camera.Size getOptimalPreviewSize(List sizes, int w, int h) { + final double ASPECT_TOLERANCE = 0.1; + double targetRatio = (double) h / w; + + if (sizes == null) + return null; + + Camera.Size optimalSize = null; + double minDiff = Double.MAX_VALUE; + + for (Camera.Size size : sizes) { + double ratio = (double) size.width / size.height; + if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) + continue; + if (Math.abs(size.height - h) < minDiff) { + optimalSize = size; + minDiff = Math.abs(size.height - h); + } + } + + if (optimalSize == null) { + minDiff = Double.MAX_VALUE; + for (Camera.Size size : sizes) { + if (Math.abs(size.height - h) < minDiff) { + optimalSize = size; + minDiff = Math.abs(size.height - h); + } + } + } + return optimalSize; + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec); + final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec); + setMeasuredDimension(width, height); + + if (supportedPreviewSizes != null) { + previewSize = getOptimalPreviewSize(supportedPreviewSizes, width, height); + } + } +} diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 286eaf79..960109fa 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,12 +1,13 @@ + android:layout_width="wrap_content" + android:layout_height="wrap_content"/> diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 5885930d..c62b5531 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -1,8 +1,6 @@ - -