I'm making a simple demo where I can feed the camera preview to a SurfaceView in my activity. I came to know that setParameters() fails if you don't set a supported size. But even when I did that, I'm getting the same FATAL EXCEPTION. Please help!
Code:
package ank.altcamera;
import java.io.IOException;
import java.util.List;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.Switch;
import android.widget.Toast;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.ImageFormat;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.Size;
public class CameraActivity extends Activity implements SurfaceHolder.Callback{
Switch sw_flash;
SeekBar sb_zoom;
Camera cam;
SurfaceView surf_view;
SurfaceHolder surf_holder;
boolean preview;
final int TAKE_PICTURE = 100;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
sw_flash = (Switch) findViewById(R.id.sw_flash);
sb_zoom = (SeekBar) findViewById(R.id.seekBar1);
//camera settings
surf_view = (SurfaceView) findViewById(R.id.surfaceView);
surf_holder = surf_view.getHolder();
surf_holder.addCallback(CameraActivity.this);
}
/* Must implement Interface methods */
//onClickListener for the button
public void takePicture (View v) {
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
if (preview) {
cam.stopPreview();
}
Camera.Parameters p = cam.getParameters();
//check for supported sizes to avoid exceptions
Size size = getBestPreviewSize(width, height, p);
p.setPreviewSize(size.width, size.height);
//move ahead
p.setPreviewFormat(ImageFormat.JPEG);
cam.setParameters(p);
//start the preview
try {
cam.setPreviewDisplay(surf_holder);
cam.startPreview();
preview = true;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
cam = Camera.open();
if (cam != null){
Camera.Parameters params = cam.getParameters();
cam.setParameters(params);
}
else {
Toast.makeText(getApplicationContext(), "Camera error.", Toast.LENGTH_LONG).show();
finish();
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
cam.stopPreview();
preview = false;
cam.release();
}
private Camera.Size getBestPreviewSize(int width, int height, Camera.Parameters parameters){
Size bestSize = null;
List<Camera.Size> sizeList = parameters.getSupportedPreviewSizes();
bestSize = sizeList.get(0);
for(int i = 1; i < sizeList.size(); i++){
if((sizeList.get(i).width * sizeList.get(i).height) >
(bestSize.width * bestSize.height)){
bestSize = sizeList.get(i);
}
}
return bestSize;
}
}
And here's my layout XML file:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/background_main"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".CameraActivity" >
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="18dp"
android:minWidth="100dp"
android:text="Awesome Camera"
android:textColor="#fff"
android:textSize="25sp"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:layout_marginTop="5dp"
android:text="Zoom"
android:textColor="#fff"
android:textStyle="bold" />
<SeekBar
android:id="@+id/seekBar1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp" />
</LinearLayout>
<Switch
android:id="@+id/sw_flash"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Flash"
android:textColor="#fff"
android:textStyle="bold" />
<SurfaceView
android:id="@+id/surfaceView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dp"
/>
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dp"
android:background="#fff"
android:onClick="takePicture"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:text="Take Picture" />
</LinearLayout>
And finally, the logcat ouput:
06-22 10:26:50.421: D/TextLayoutCache(12360): Using debug level: 0 - Debug Enabled: 0
06-22 10:26:50.511: D/libEGL(12360): loaded /system/lib/egl/libGLES_android.so
06-22 10:26:50.561: D/libEGL(12360): loaded /system/lib/egl/libEGL_adreno200.so
06-22 10:26:50.601: D/libEGL(12360): loaded /system/lib/egl/libGLESv1_CM_adreno200.so
06-22 10:26:50.601: D/libEGL(12360): loaded /system/lib/egl/libGLESv2_adreno200.so
06-22 10:26:50.701: I/Adreno200-EGLSUB(12360): <ConfigWindowMatch:2218>: Format RGBA_8888.
06-22 10:26:50.711: D/memalloc(12360): /dev/pmem: Mapped buffer base:0x516f6000 size:5775360 offset:4239360 fd:58
06-22 10:26:50.711: D/OpenGLRenderer(12360): Enabling debug mode 0
06-22 10:26:51.491: D/AndroidRuntime(12360): Shutting down VM
06-22 10:26:51.491: W/dalvikvm(12360): threadid=1: thread exiting with uncaught exception (group=0x40c28a68)
06-22 10:26:51.501: E/AndroidRuntime(12360): FATAL EXCEPTION: main
06-22 10:26:51.501: E/AndroidRuntime(12360): java.lang.RuntimeException: setParameters failed
06-22 10:26:51.501: E/AndroidRuntime(12360): at android.hardware.Camera.native_setParameters(Native Method)
06-22 10:26:51.501: E/AndroidRuntime(12360): at android.hardware.Camera.setParameters(Camera.java:1476)
06-22 10:26:51.501: E/AndroidRuntime(12360): at ank.altcamera.CameraActivity.surfaceChanged(CameraActivity.java:71)
06-22 10:26:51.501: E/AndroidRuntime(12360): at android.view.SurfaceView.updateWindow(SurfaceView.java:591)
06-22 10:26:51.501: E/AndroidRuntime(12360): at android.view.SurfaceView.access$000(SurfaceView.java:81)
06-22 10:26:51.501: E/AndroidRuntime(12360): at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:173)
06-22 10:26:51.501: E/AndroidRuntime(12360): at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:590)
06-22 10:26:51.501: E/AndroidRuntime(12360): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1799)
06-22 10:26:51.501: E/AndroidRuntime(12360): at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2632)
06-22 10:26:51.501: E/AndroidRuntime(12360): at android.os.Handler.dispatchMessage(Handler.java:99)
06-22 10:26:51.501: E/AndroidRuntime(12360): at android.os.Looper.loop(Looper.java:137)
06-22 10:26:51.501: E/AndroidRuntime(12360): at android.app.ActivityThread.main(ActivityThread.java:4517)
06-22 10:26:51.501: E/AndroidRuntime(12360): at java.lang.reflect.Method.invokeNative(Native Method)
06-22 10:26:51.501: E/AndroidRuntime(12360): at java.lang.reflect.Method.invoke(Method.java:511)
06-22 10:26:51.501: E/AndroidRuntime(12360): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:993)
06-22 10:26:51.501: E/AndroidRuntime(12360): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:760)
06-22 10:26:51.501: E/AndroidRuntime(12360): at dalvik.system.NativeStart.main(Native Method)
06-22 10:27:00.301: I/Process(12360): Sending signal. PID: 12360 SIG: 9
Please help me out!
The documentation states that setParameters
throws a RuntimeException
when any of the parameters are invalid or not supported.
The parameters you are changing are the size and the format; However, your're taking the sizes from getSupportedPreviewSizes
so they mustn't be the problem. I guess the problem is with setPreviewFormat(ImageFormat.JPEG)
.
It is always important with this error to make sure you check all of the parameters that the camera is asking to set to make sure that every parameter you are asking the camera to set itself to is possible for the camera.
Camera.Parameters parameters = myCamera.getParameters();
With the preview size:
if (myCamera.getParameters().getSupportedPreviewSizes() != null){
Camera.Size previewSize = getOptimalPreviewSize(myCamera.getParameters().getSupportedPreviewSizes(), width, height);;
parameters.setPreviewSize(previewSize.width, previewSize.height);
}
With the flash/focus modes:
if(parameters.getSupportedFocusModes() != null && parameters.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)){
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
}
if (parameters.getSupportedFlashModes() != null && parameters.getSupportedFlashModes().contains(Camera.Parameters.FLASH_MODE_AUTO)){
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
}
myCamera.setParameters(parameters);
etc. All of this wrapped in a nice try{}catch(){} works great. Good luck.
Here is the getOptimalPreview Size from this great tutorial:
private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int width, int height)
{
// Source: http://stackoverflow.com/questions/7942378/android-camera-will-not-work-startpreview-fails
Camera.Size optimalSize = null;
final double ASPECT_TOLERANCE = 0.1;
double targetRatio = (double) height / width;
// Try to find a size match which suits the whole screen minus the menu on the left.
for (Camera.Size size : sizes){
if (size.height != width) continue;
double ratio = (double) size.width / size.height;
if (ratio <= targetRatio + ASPECT_TOLERANCE && ratio >= targetRatio - ASPECT_TOLERANCE){
optimalSize = size;
}
}
// If we cannot find the one that matches the aspect ratio, ignore the requirement.
if (optimalSize == null) {
// TODO : Backup in case we don't get a size.
}
return optimalSize;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With