2013-06-22 2 views
5

Я делаю простую демонстрацию, где могу подавать предварительный просмотр камеры SurfaceView в своей деятельности. Я узнал, что setParameters() терпит неудачу, если вы не установили поддерживаемый размер. Но даже когда я это сделал, я получаю то же FATAL EXCEPTION. Пожалуйста помоги!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 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 

Пожалуйста, помогите мне!

ответ

7

В documentation указано, что setParameters выбрасывает RuntimeException, если какой-либо из параметров недействителен или не поддерживается.

Параметры, которые вы меняете, - это размер и формат; Однако, вы делаете размеры от getSupportedPreviewSizes, поэтому они не должны быть проблемой. Я думаю, проблема связана с setPreviewFormat(ImageFormat.JPEG).

+0

By Jove, вы правы! Я удалил setPreviewFormat(), и теперь он работает безупречно. Скажите, пожалуйста, как я могу развить понимание, подобное вашему? :) Большое спасибо. Теперь любая идея, почему эта проблема? – dotslash

+0

Insight будет развиваться со временем, вам просто нужно попытаться решить свои проблемы самостоятельно :) Я понятия не имею * почему * камера не поддерживает предварительный просмотр JPEG, но в этом проблема. – Jong

+0

Хммм. Ну, спасибо большое! – dotslash

0

Вы не можете определить, какой параметр вызывает исключение из среды выполнения, отображаемое в тексте сообщения. Вам лучше проверить параметры один за другим.

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

и т.д. Все это завернутые в хорошей попытке {} уловом() {} прекрасно работает. Удачи.

Вот getOptimalPreview Размер от 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; 
    }