Better camera display in dialer
This commit is contained in:
parent
cb08478146
commit
ed53b8b62e
4 changed files with 199 additions and 65 deletions
|
@ -4,7 +4,7 @@
|
|||
android:layout_height="fill_parent"
|
||||
android:gravity="bottom|center_horizontal">
|
||||
|
||||
<SurfaceView
|
||||
<org.linphone.ui.CameraView
|
||||
android:id="@+id/video_background"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
android:layout_height="fill_parent"
|
||||
android:gravity="bottom|center_horizontal">
|
||||
|
||||
<SurfaceView
|
||||
<org.linphone.ui.CameraView
|
||||
android:id="@+id/video_background"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
|
|
|
@ -18,7 +18,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
*/
|
||||
package org.linphone;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
|
@ -31,6 +30,7 @@ import org.linphone.core.Log;
|
|||
import org.linphone.ui.AddressAware;
|
||||
import org.linphone.ui.AddressText;
|
||||
import org.linphone.ui.CallButton;
|
||||
import org.linphone.ui.CameraView;
|
||||
import org.linphone.ui.EraseButton;
|
||||
|
||||
import android.app.Activity;
|
||||
|
@ -40,20 +40,13 @@ import android.content.Intent;
|
|||
import android.content.SharedPreferences;
|
||||
import android.hardware.Camera;
|
||||
import android.hardware.Camera.CameraInfo;
|
||||
import android.hardware.Camera.Parameters;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.view.Display;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceHolder.Callback;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.Adapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.ListAdapter;
|
||||
|
@ -90,7 +83,7 @@ public class DialerActivity extends Activity implements LinphoneGuiListener {
|
|||
protected String username;
|
||||
private String key;
|
||||
|
||||
private SurfaceView mVideoCaptureViewReady;
|
||||
private CameraView mVideoCaptureView;
|
||||
private int mCurrentCameraId = 0;
|
||||
|
||||
private Camera mCamera;
|
||||
|
@ -268,52 +261,13 @@ public class DialerActivity extends Activity implements LinphoneGuiListener {
|
|||
}
|
||||
}
|
||||
|
||||
mVideoCaptureViewReady = (SurfaceView) findViewById(R.id.video_background);
|
||||
if (mVideoCaptureViewReady != null)
|
||||
mVideoCaptureView = (CameraView) findViewById(R.id.video_background);
|
||||
if (mVideoCaptureView != null)
|
||||
{
|
||||
if (mCamera == null)
|
||||
if (mCamera == null) {
|
||||
mCamera = Camera.open(mCurrentCameraId);
|
||||
|
||||
mVideoCaptureViewReady.getHolder().addCallback(new Callback() {
|
||||
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||
if (mCamera != null) {
|
||||
mCamera.stopPreview();
|
||||
}
|
||||
}
|
||||
|
||||
public void surfaceCreated(SurfaceHolder holder) {
|
||||
try {
|
||||
if (mCamera != null) {
|
||||
mCamera.setPreviewDisplay(holder);
|
||||
}
|
||||
} catch (IOException exception) {
|
||||
Log.e("IOException caused by setPreviewDisplay()", exception);
|
||||
}
|
||||
}
|
||||
|
||||
public void surfaceChanged(SurfaceHolder holder, int format, int width,
|
||||
int height) {
|
||||
Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
|
||||
|
||||
if(display.getRotation() == Surface.ROTATION_90)
|
||||
{
|
||||
mCamera.setDisplayOrientation(270);
|
||||
}
|
||||
else if(display.getRotation() == Surface.ROTATION_270)
|
||||
{
|
||||
mCamera.setDisplayOrientation(90);
|
||||
}
|
||||
else if (display.getRotation() == Surface.ROTATION_180)
|
||||
{
|
||||
mCamera.setDisplayOrientation(180);
|
||||
}
|
||||
|
||||
mVideoCaptureViewReady.requestLayout();
|
||||
if (mCamera != null)
|
||||
mCamera.startPreview();
|
||||
}
|
||||
|
||||
});
|
||||
mVideoCaptureView.setCamera(mCamera);
|
||||
mCamera.startPreview();
|
||||
}
|
||||
|
||||
|
@ -325,12 +279,13 @@ public class DialerActivity extends Activity implements LinphoneGuiListener {
|
|||
|
||||
switchCamera.setOnClickListener(new OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
try {
|
||||
mCamera.setPreviewDisplay(mVideoCaptureViewReady.getHolder());
|
||||
} catch (IOException exception) { }
|
||||
mCurrentCameraId = (mCurrentCameraId + 1) % numberOfCameras;
|
||||
mCamera.release();
|
||||
mVideoCaptureView.setCamera(null);
|
||||
|
||||
mCamera = Camera.open(mCurrentCameraId);
|
||||
mVideoCaptureView.switchCamera(mCamera);
|
||||
mCamera.startPreview();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -360,6 +315,7 @@ public class DialerActivity extends Activity implements LinphoneGuiListener {
|
|||
|
||||
if (mCamera != null) {
|
||||
mCamera.release();
|
||||
mVideoCaptureView.setCamera(null);
|
||||
mCamera = null;
|
||||
}
|
||||
}
|
||||
|
@ -489,14 +445,10 @@ public class DialerActivity extends Activity implements LinphoneGuiListener {
|
|||
|
||||
super.onResume();
|
||||
|
||||
if (mVideoCaptureViewReady != null && mCamera == null && !LinphoneManager.getLc().isIncall())
|
||||
if (mVideoCaptureView != null && mCamera == null && !LinphoneManager.getLc().isIncall())
|
||||
{
|
||||
mCamera = Camera.open(mCurrentCameraId);
|
||||
mVideoCaptureViewReady.requestLayout();
|
||||
try {
|
||||
mCamera.setPreviewDisplay(mVideoCaptureViewReady.getHolder());
|
||||
} catch (IOException e) {
|
||||
}
|
||||
mVideoCaptureView.switchCamera(mCamera);
|
||||
mCamera.startPreview();
|
||||
}
|
||||
}
|
||||
|
@ -507,5 +459,4 @@ public class DialerActivity extends Activity implements LinphoneGuiListener {
|
|||
if (LinphoneUtils.onKeyVolumeSoftAdjust(keyCode)) return true;
|
||||
return super.onKeyDown(keyCode, event);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
183
src/org/linphone/ui/CameraView.java
Normal file
183
src/org/linphone/ui/CameraView.java
Normal file
|
@ -0,0 +1,183 @@
|
|||
package org.linphone.ui;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import org.linphone.core.Log;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.Camera;
|
||||
import android.hardware.Camera.Size;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.Display;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowManager;
|
||||
|
||||
public class CameraView extends ViewGroup implements SurfaceHolder.Callback {
|
||||
|
||||
public CameraView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
|
||||
mSurfaceView = new SurfaceView(context);
|
||||
addView(mSurfaceView);
|
||||
|
||||
mHolder = mSurfaceView.getHolder();
|
||||
mHolder.addCallback(this);
|
||||
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
|
||||
}
|
||||
|
||||
CameraView(Context context) {
|
||||
super(context);
|
||||
|
||||
mSurfaceView = new SurfaceView(context);
|
||||
addView(mSurfaceView);
|
||||
|
||||
mHolder = mSurfaceView.getHolder();
|
||||
mHolder.addCallback(this);
|
||||
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
|
||||
}
|
||||
|
||||
SurfaceView mSurfaceView;
|
||||
SurfaceHolder mHolder;
|
||||
Size mPreviewSize;
|
||||
List<Size> mSupportedSizes;
|
||||
Camera mCamera;
|
||||
|
||||
public void setCamera(Camera camera) {
|
||||
mCamera = camera;
|
||||
if (mCamera != null) {
|
||||
mSupportedSizes = mCamera.getParameters().getSupportedPreviewSizes();
|
||||
requestLayout();
|
||||
}
|
||||
}
|
||||
|
||||
public void switchCamera(Camera camera) {
|
||||
setCamera(camera);
|
||||
try {
|
||||
camera.setPreviewDisplay(mHolder);
|
||||
} catch (IOException exception) {
|
||||
|
||||
}
|
||||
Camera.Parameters parameters = camera.getParameters();
|
||||
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
|
||||
requestLayout();
|
||||
|
||||
camera.setParameters(parameters);
|
||||
}
|
||||
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);;
|
||||
int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);;
|
||||
setMeasuredDimension(width, height);
|
||||
|
||||
if (mSupportedSizes != null) {
|
||||
mPreviewSize = getOptimalPreviewSize(mSupportedSizes, width, height);
|
||||
}
|
||||
Display display = ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
|
||||
if (display.getRotation() == Surface.ROTATION_90 || display.getRotation() == Surface.ROTATION_270) {
|
||||
Size tempSize = mPreviewSize;
|
||||
mPreviewSize.width = tempSize.height;
|
||||
mPreviewSize.height = tempSize.width;
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
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 (mPreviewSize != null) {
|
||||
previewWidth = mPreviewSize.width;
|
||||
previewHeight = mPreviewSize.height;
|
||||
}
|
||||
|
||||
// Center the surface view
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void surfaceCreated(SurfaceHolder holder) {
|
||||
try {
|
||||
if (mCamera != null) {
|
||||
mCamera.setPreviewDisplay(holder);
|
||||
}
|
||||
} catch (IOException exception) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||
if (mCamera != null) {
|
||||
mCamera.stopPreview();
|
||||
}
|
||||
}
|
||||
|
||||
private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
|
||||
final double ASPECT_TOLERANCE = 0.1;
|
||||
double targetRatio = (double) w / h;
|
||||
if (sizes == null) return null;
|
||||
|
||||
Size optimalSize = null;
|
||||
double minDiff = Double.MAX_VALUE;
|
||||
|
||||
int targetHeight = h;
|
||||
|
||||
for (Size size : sizes) {
|
||||
double ratio = (double) size.width / size.height;
|
||||
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
|
||||
if (Math.abs(size.height - targetHeight) < minDiff) {
|
||||
optimalSize = size;
|
||||
minDiff = Math.abs(size.height - targetHeight);
|
||||
}
|
||||
}
|
||||
|
||||
if (optimalSize == null) {
|
||||
minDiff = Double.MAX_VALUE;
|
||||
for (Size size : sizes) {
|
||||
if (Math.abs(size.height - targetHeight) < minDiff) {
|
||||
optimalSize = size;
|
||||
minDiff = Math.abs(size.height - targetHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
return optimalSize;
|
||||
}
|
||||
|
||||
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
|
||||
mCamera.stopPreview();
|
||||
Display display = ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
|
||||
Camera.Parameters parameters = mCamera.getParameters();
|
||||
|
||||
if(display.getRotation() == Surface.ROTATION_90) {
|
||||
mCamera.setDisplayOrientation(270);
|
||||
}
|
||||
else if(display.getRotation() == Surface.ROTATION_270) {
|
||||
mCamera.setDisplayOrientation(90);
|
||||
}
|
||||
else if (display.getRotation() == Surface.ROTATION_180) {
|
||||
mCamera.setDisplayOrientation(180);
|
||||
}
|
||||
requestLayout();
|
||||
|
||||
mCamera.setParameters(parameters);
|
||||
mCamera.startPreview();
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue