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:layout_height="fill_parent"
|
||||||
android:gravity="bottom|center_horizontal">
|
android:gravity="bottom|center_horizontal">
|
||||||
|
|
||||||
<SurfaceView
|
<org.linphone.ui.CameraView
|
||||||
android:id="@+id/video_background"
|
android:id="@+id/video_background"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="fill_parent"
|
android:layout_height="fill_parent"
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
android:layout_height="fill_parent"
|
android:layout_height="fill_parent"
|
||||||
android:gravity="bottom|center_horizontal">
|
android:gravity="bottom|center_horizontal">
|
||||||
|
|
||||||
<SurfaceView
|
<org.linphone.ui.CameraView
|
||||||
android:id="@+id/video_background"
|
android:id="@+id/video_background"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="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;
|
package org.linphone;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
@ -31,6 +30,7 @@ import org.linphone.core.Log;
|
||||||
import org.linphone.ui.AddressAware;
|
import org.linphone.ui.AddressAware;
|
||||||
import org.linphone.ui.AddressText;
|
import org.linphone.ui.AddressText;
|
||||||
import org.linphone.ui.CallButton;
|
import org.linphone.ui.CallButton;
|
||||||
|
import org.linphone.ui.CameraView;
|
||||||
import org.linphone.ui.EraseButton;
|
import org.linphone.ui.EraseButton;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
@ -40,20 +40,13 @@ import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.hardware.Camera;
|
import android.hardware.Camera;
|
||||||
import android.hardware.Camera.CameraInfo;
|
import android.hardware.Camera.CameraInfo;
|
||||||
import android.hardware.Camera.Parameters;
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.view.Display;
|
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.LayoutInflater;
|
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;
|
||||||
import android.view.View.OnClickListener;
|
import android.view.View.OnClickListener;
|
||||||
import android.view.WindowManager;
|
|
||||||
import android.widget.Adapter;
|
import android.widget.Adapter;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.ListAdapter;
|
import android.widget.ListAdapter;
|
||||||
|
@ -90,7 +83,7 @@ public class DialerActivity extends Activity implements LinphoneGuiListener {
|
||||||
protected String username;
|
protected String username;
|
||||||
private String key;
|
private String key;
|
||||||
|
|
||||||
private SurfaceView mVideoCaptureViewReady;
|
private CameraView mVideoCaptureView;
|
||||||
private int mCurrentCameraId = 0;
|
private int mCurrentCameraId = 0;
|
||||||
|
|
||||||
private Camera mCamera;
|
private Camera mCamera;
|
||||||
|
@ -268,52 +261,13 @@ public class DialerActivity extends Activity implements LinphoneGuiListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mVideoCaptureViewReady = (SurfaceView) findViewById(R.id.video_background);
|
mVideoCaptureView = (CameraView) findViewById(R.id.video_background);
|
||||||
if (mVideoCaptureViewReady != null)
|
if (mVideoCaptureView != null)
|
||||||
{
|
{
|
||||||
if (mCamera == null)
|
if (mCamera == null) {
|
||||||
mCamera = Camera.open(mCurrentCameraId);
|
mCamera = Camera.open(mCurrentCameraId);
|
||||||
|
}
|
||||||
mVideoCaptureViewReady.getHolder().addCallback(new Callback() {
|
mVideoCaptureView.setCamera(mCamera);
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
mCamera.startPreview();
|
mCamera.startPreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,12 +279,13 @@ public class DialerActivity extends Activity implements LinphoneGuiListener {
|
||||||
|
|
||||||
switchCamera.setOnClickListener(new OnClickListener() {
|
switchCamera.setOnClickListener(new OnClickListener() {
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
try {
|
|
||||||
mCamera.setPreviewDisplay(mVideoCaptureViewReady.getHolder());
|
|
||||||
} catch (IOException exception) { }
|
|
||||||
mCurrentCameraId = (mCurrentCameraId + 1) % numberOfCameras;
|
mCurrentCameraId = (mCurrentCameraId + 1) % numberOfCameras;
|
||||||
mCamera.release();
|
mCamera.release();
|
||||||
|
mVideoCaptureView.setCamera(null);
|
||||||
|
|
||||||
mCamera = Camera.open(mCurrentCameraId);
|
mCamera = Camera.open(mCurrentCameraId);
|
||||||
|
mVideoCaptureView.switchCamera(mCamera);
|
||||||
|
mCamera.startPreview();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -360,6 +315,7 @@ public class DialerActivity extends Activity implements LinphoneGuiListener {
|
||||||
|
|
||||||
if (mCamera != null) {
|
if (mCamera != null) {
|
||||||
mCamera.release();
|
mCamera.release();
|
||||||
|
mVideoCaptureView.setCamera(null);
|
||||||
mCamera = null;
|
mCamera = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -489,14 +445,10 @@ public class DialerActivity extends Activity implements LinphoneGuiListener {
|
||||||
|
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
|
||||||
if (mVideoCaptureViewReady != null && mCamera == null && !LinphoneManager.getLc().isIncall())
|
if (mVideoCaptureView != null && mCamera == null && !LinphoneManager.getLc().isIncall())
|
||||||
{
|
{
|
||||||
mCamera = Camera.open(mCurrentCameraId);
|
mCamera = Camera.open(mCurrentCameraId);
|
||||||
mVideoCaptureViewReady.requestLayout();
|
mVideoCaptureView.switchCamera(mCamera);
|
||||||
try {
|
|
||||||
mCamera.setPreviewDisplay(mVideoCaptureViewReady.getHolder());
|
|
||||||
} catch (IOException e) {
|
|
||||||
}
|
|
||||||
mCamera.startPreview();
|
mCamera.startPreview();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -507,5 +459,4 @@ public class DialerActivity extends Activity implements LinphoneGuiListener {
|
||||||
if (LinphoneUtils.onKeyVolumeSoftAdjust(keyCode)) return true;
|
if (LinphoneUtils.onKeyVolumeSoftAdjust(keyCode)) return true;
|
||||||
return super.onKeyDown(keyCode, event);
|
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