2013-06-22 13 views
5

Sto facendo una semplice demo in cui posso alimentare l'anteprima della fotocamera a SurfaceView nella mia attività. Sono venuto a sapere che setParameters() ha esito negativo se non si imposta una dimensione supportata. Ma anche quando l'ho fatto, sto ricevendo la stessa ECCEZIONE FATALE. Per favore aiuto!setParameters() non riesce malgrado l'impostazione della dimensione dell'anteprima

Codice:

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

Ed ecco il mio layout di file 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> 

E, infine, l'ouput 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 

Please help me out!

risposta

7

Il documentation indica che setParameters genera uno RuntimeException quando uno dei parametri non è valido o non è supportato.

I parametri che si stanno modificando sono la dimensione e il formato; Tuttavia, stai prendendo le misure dal getSupportedPreviewSizes quindi non devono essere il problema. Immagino che il problema sia con setPreviewFormat(ImageFormat.JPEG).

+0

Per Giove, hai ragione! Ho rimosso setPreviewFormat() e ora funziona perfettamente. Per favore dimmi come posso sviluppare intuizioni come la tua? :) Grazie mille. Ora, qualche idea del perché questo problema? – dotslash

+0

Insight si svilupperà nel tempo, devi solo provare a risolvere i tuoi problemi da solo :) Non ho idea * perché * la fotocamera non supporta l'anteprima JPEG, ma questo è il problema qui. – Jong

+0

Hmmm. Bene, grazie mille! – dotslash

0

Non è possibile indicare quale parametro causa l'eccezione di runtime dal testo del messaggio visualizzato. È meglio controllare i parametri uno per uno.

4

È sempre importante con questo errore assicurarsi di controllare tutti i parametri che la telecamera sta chiedendo di impostare per assicurarsi che ogni parametro che si sta chiedendo alla telecamera di impostarsi sia possibile per la telecamera.

Camera.Parameters parameters = myCamera.getParameters(); 

Con le dimensioni di anteprima:

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

Con le modalità Flash/di messa a fuoco:

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

ecc Tutto questo avvolto in un bel try {} catch() {} funziona alla grande. In bocca al lupo.

Ecco la getOptimalPreview formato da 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; 
    } 
Problemi correlati