5

我正在制作一个简单的演示,我可以在我的活动中将相机预览提供给 SurfaceView。我知道如果您不设置支持的大小, setParameters() 会失败。但即使我这样做了,我也会遇到同样的致命异常。请帮忙!

代码:

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;
        }
}

这是我的布局 XML 文件:

<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>

最后,logcat 输出:

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

请帮帮我!

4

3 回答 3

8

文档指出,当任何参数无效或不受支持时setParameters会抛出 a 。RuntimeException

您正在更改的参数是大小和格式;但是,您要从中获取尺寸,getSupportedPreviewSizes因此它们一定不是问题。我想问题出在setPreviewFormat(ImageFormat.JPEG).

于 2013-06-22T07:30:00.243 回答
4

对于此错误,务必检查相机要求设置的所有参数,以确保您要求相机设置的每个参数都适用于相机。

Camera.Parameters parameters = myCamera.getParameters();

使用预览尺寸:

if (myCamera.getParameters().getSupportedPreviewSizes() != null){
     Camera.Size previewSize = getOptimalPreviewSize(myCamera.getParameters().getSupportedPreviewSizes(), width, height);;
     parameters.setPreviewSize(previewSize.width, previewSize.height);
}

使用闪光灯/对焦模式:

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);

等等。所有这些都包含在一个不错的 try{}catch(){} 中,效果很好。祝你好运。

这是这个很棒的教程中的 getOptimalPreview 大小:

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;
    }
于 2015-03-30T03:37:38.967 回答
0

您无法从它显示的消息文本中分辨出哪个参数导致运行时异常。最好一一检查参数。

于 2013-10-23T10:12:20.867 回答