2013-06-22 4 views
5

Ich mache eine einfache Demo, in der ich in meiner Aktivität die Kameravorschau an eine SurfaceView füttern kann. Ich habe erfahren, dass setParameters() fehlschlägt, wenn Sie keine unterstützte Größe festlegen. Aber selbst wenn ich das getan habe, bekomme ich die gleiche Fatale Ausnahme. Bitte helfen Sie!setParameters() schlägt trotz Einstellung der Vorschaugröße fehl

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

Und hier ist mein Layout XML-Datei:

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

Und schließlich die 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 

Bitte helfen Sie mir!

Antwort

7

Die documentation besagt, dass setParameters einen RuntimeException auslöst, wenn einer der Parameter ungültig oder nicht unterstützt wird.

Die Parameter, die Sie ändern, sind die Größe und das Format; Allerdings nehmen Sie die Größen von getSupportedPreviewSizes, so dass sie nicht das Problem sein müssen. Ich schätze das Problem ist mit setPreviewFormat(ImageFormat.JPEG).

+0

Wahrhaftig, du hast Recht! Ich habe setPreviewFormat() entfernt und es funktioniert nun einwandfrei. Bitte sagen Sie mir, wie ich Einblicke wie Ihre entwickeln kann? :) Vielen Dank. Nun, irgendeine Idee, warum dieses Problem? – dotslash

+0

Insight wird sich im Laufe der Zeit entwickeln, Sie müssen nur versuchen, Ihre Probleme auf eigene Faust zu lösen :) Ich habe keine Ahnung * warum * nicht unterstützt die Kamera JPEG-Vorschau, aber das ist das Problem hier. – Jong

+0

Hmmm. Nun, vielen Dank! – dotslash

0

Sie können nicht feststellen, welcher Parameter eine Laufzeitausnahme aus dem angezeigten Nachrichtentext verursacht. Sie sollten die Parameter nacheinander überprüfen.

4

Bei diesem Fehler ist es immer wichtig, dass Sie alle Parameter überprüfen, die die Kamera einstellen soll, um sicherzustellen, dass alle Parameter, auf die Sie die Kamera einstellen möchten, für die Kamera möglich sind.

Camera.Parameters parameters = myCamera.getParameters(); 

Mit der Vorschaugröße:

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

mit dem Blitz/Fokus-Modi:

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

usw. All dies in einem schönen Versuch gewickelten {} catch() {} funktioniert super. Viel Glück.

Hier ist die getOptimalPreview Größe von 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; 
    }