2011-01-28 15 views
5

Tengo un problema extraño. Estoy haciendo mis pruebas en un HTC EVO. He escrito una aplicación de cámara de demostración orientada a 2.2 y casi todo funciona correctamente. El problema es que después de tomar tres o cuatro imágenes, la aplicación se bloquea y me da los siguientes mensajes:Android: "Camera.takePicture failed" Excepción

D/QualcommCameraHardware( 64): takePicture(479) 
D/QualcommCameraHardware( 64): val_ril_status = 0,val_wimax_status = 0,val_hotspot_status = 0,val_low_temp_limit = 10.000000,val_batt_temp = 29.799999,val_low_temp_limit = 15,val_batt_cap = 96 
D/QualcommCameraHardware( 64): FLASHLIGHT is ENABLED 
D/QualcommCameraHardware( 64): stopPreviewInternal E: 1 
D/QualcommCameraHardware( 64): cancelAutoFocusInternal E 
D/QualcommCameraHardware( 64): cancelAutoFocusInternal X: 0 
I/QualcommCameraHardware( 64): deinitPreview E 
D/QualcommCameraHardware( 64): launch_watchdog_thread: 
D/QualcommCameraHardware( 64): watchdog_thread_id = 369048 
I/QualcommCameraHardware( 64): register_buf: camfd = 35, reg = 1 buffer = 0x4153f000 
I/QualcommCameraHardware( 64): register_buf: camfd = 35, reg = 1 buffer = 0x415bf000 
I/QualcommCameraHardware( 64): register_buf: camfd = 35, reg = 1 buffer = 0x4163f000 
I/QualcommCameraHardware( 64): register_buf: camfd = 35, reg = 1 buffer = 0x416bf000 
I/QualcommCameraHardware( 64): register_buf: camfd = 38, reg = 1 buffer = 0x4331d000 
I/QualcommCameraHardware( 64): register_buf: camfd = 38, reg = 1 buffer = 0x4351d000 
I/QualcommCameraHardware( 64): register_buf: camfd = 38, reg = 1 buffer = 0x4371d000 
I/QualcommCameraHardware( 64): register_buf: camfd = 38, reg = 1 buffer = 0x4391d000 
I/QualcommCameraHardware( 64): register_buf: camfd = 38, reg = 1 buffer = 0x43b1d000 
I/QualcommCameraHardware( 64): register_buf: camfd = 38, reg = 1 buffer = 0x43d1d000 
I/QualcommCameraHardware( 64): register_buf: camfd = 38, reg = 1 buffer = 0x43f1d000 
I/QualcommCameraHardware( 64): register_buf: camfd = 38, reg = 1 buffer = 0x4411d000 
I/QualcommCameraHardware( 64): deinitPreview X 
D/QualcommCameraHardware( 64): stopPreviewInternal X: 0 
D/QualcommCameraHardware( 64): initRaw E: raw size=3264x2448 
D/QualcommCameraHardware( 64): initRaw: raw ration = 0.750000, display size=768x432 
D/QualcommCameraHardware( 64): initRaw: thumbnail_width=768, thumbnail_height=576, thumbnail_buffer_size=663552 
D/QualcommCameraHardware( 64): native_access_parm: fd 24, type 1, length 32 
D/mm-camera-ov8810_u( 64): andy cam_mode_sel 0 
D/QualcommCameraHardware( 64): initRaw: initializing mRawHeap. 
E/MemoryHeapBase( 64): error opening /dev/pmem_camera: No such file or directory 
E/QualcommCameraHardware( 64): failed to construct master heap for pmem pool /dev/pmem_camera 
E/QualcommCameraHardware( 64): initRaw X failed with pmem_camera, trying with pmem_adsp 
D/QualcommCameraHardware( 64): frame_thread X 
D/QualcommCameraHardware( 64): watchdog_thread_id = 369048 
D/QualcommCameraHardware( 64): release_watchdog_thread: frame_thread_released = 1 
E/MemoryHeapBase( 64): mmap(fd=38, size=11988992) failed (Invalid argument) 
E/QualcommCameraHardware( 64): failed to construct master heap for pmem pool /dev/pmem_adsp 
E/QualcommCameraHardware( 64): initRaw X: error initializing mRawHeap 
E/QualcommCameraHardware( 64): initRaw failed. Not taking picture. 
D/AndroidRuntime(2650): Shutting down VM 
W/dalvikvm(2650): threadid=1: thread exiting with uncaught exception (group=0x400259f8) 
E/AndroidRuntime(2650): FATAL EXCEPTION: main 
E/AndroidRuntime(2650): java.lang.RuntimeException: takePicture failed 
E/AndroidRuntime(2650): at android.hardware.Camera.native_takePicture(Native Method) 
E/AndroidRuntime(2650): at android.hardware.Camera.takePicture(Camera.java:535) 
E/AndroidRuntime(2650): at android.hardware.Camera.takePicture(Camera.java:503) 
E/AndroidRuntime(2650): at spikes.cameraSpike03.MainActivity.takePicture(MainActivity.java:90) 
E/AndroidRuntime(2650): at spikes.cameraSpike03.MainActivity.access$3(MainActivity.java:87) 
E/AndroidRuntime(2650): at spikes.cameraSpike03.MainActivity$3.onClick(MainActivity.java:80) 
E/AndroidRuntime(2650): at android.view.View.performClick(View.java:2408) 
E/AndroidRuntime(2650): at android.view.View$PerformClick.run(View.java:8817) 
E/AndroidRuntime(2650): at android.os.Handler.handleCallback(Handler.java:587) 
E/AndroidRuntime(2650): at android.os.Handler.dispatchMessage(Handler.java:92) 
E/AndroidRuntime(2650): at android.os.Looper.loop(Looper.java:144) 
E/AndroidRuntime(2650): at android.app.ActivityThread.main(ActivityThread.java:4937) 
E/AndroidRuntime(2650): at java.lang.reflect.Method.invokeNative(Native Method) 
E/AndroidRuntime(2650): at java.lang.reflect.Method.invoke(Method.java:521) 
E/AndroidRuntime(2650): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 
E/AndroidRuntime(2650): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 
E/AndroidRuntime(2650): at dalvik.system.NativeStart.main(Native Method) 
W/ActivityManager( 107): Force finishing activity spikes.cameraSpike03/.MainActivity 
D/QualcommCameraHardware( 64): void* watchdog(void*), frame_thread_released = 1, cnt = 0 
D/QualcommCameraHardware( 64): void* watchdog(void*), exit, frame_thread_released=1 
D/QualcommCameraHardware( 64): void release_watchdog_thread(): pthread_join succeeded on watchdog. 

Podría ser esto un problema de gestión de memoria?

A continuación se muestra todo el código que estoy usando.

[AndroidManifest.xml]

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
     package="spikes.cameraSpike03" 
     android:versionCode="1" 
     android:versionName="1.0"> 
    <application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true"> 
     <activity android:name=".MainActivity" android:label="@string/app_name" android:screenOrientation="portrait"> 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 
       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
    </application> 

    <uses-sdk android:minSdkVersion="8" /> 

<uses-permission android:name="android.permission.CAMERA" /> 

<uses-feature android:name="android.hardware.camera" /> 
<uses-feature android:name="android.hardware.camera.autofocus" /> 
<uses-feature android:name="android.hardware.camera.flash" /> 
</manifest> 

[main.xml]

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> 
<SurfaceView android:id="@+id/svCameraView" android:layout_width="fill_parent" android:layout_height="fill_parent" /> 
<LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:background="#3000" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:gravity="center_horizontal"> 
    <Button android:id="@+id/btnCapture" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="capture" /> 
    <CheckBox android:id="@+id/chkAutofocus" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Autofocus" /> 
</LinearLayout> 
</RelativeLayout> 

[MainActivity.java]

package spikes.cameraSpike03; 

import java.util.List; 

import android.app.Activity; 
import android.content.pm.ActivityInfo; 
import android.content.res.Configuration; 
import android.graphics.PixelFormat; 
import android.hardware.Camera; 
import android.hardware.Camera.AutoFocusCallback; 
import android.hardware.Camera.Parameters; 
import android.hardware.Camera.PictureCallback; 
import android.hardware.Camera.ShutterCallback; 
import android.hardware.Camera.Size; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.SurfaceHolder; 
import android.view.SurfaceView; 
import android.view.View; 
import android.view.Window; 
import android.view.WindowManager; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
import android.widget.CheckBox; 

public class MainActivity extends Activity implements SurfaceHolder.Callback { 
private static final String LOG_TAG = MainActivity.class.getName(); 
private static final String LOG_LINE = "---------------------------------"; 

private Camera _camera; 
private boolean _previewIsRunning = false; 

private SurfaceView _svCameraView; 
private SurfaceHolder _surfaceHolder; 
private Button _btnCapture; 
private CheckBox _chkAutofocus; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     getWindow().setFormat(PixelFormat.TRANSLUCENT); 
     requestWindowFeature(Window.FEATURE_NO_TITLE); 
     getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); 

     setContentView(R.layout.main); 

     _svCameraView = (SurfaceView)findViewById(R.id.svCameraView); 

     _surfaceHolder = _svCameraView.getHolder(); 
     _surfaceHolder.addCallback(this); 
     _surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 

     _chkAutofocus = (CheckBox)findViewById(R.id.chkAutofocus); 

     _btnCapture = (Button)findViewById(R.id.btnCapture); 
     _btnCapture.setOnClickListener(new OnClickListener() { 
    @Override 
    public void onClick(View v) { 
    if(_camera != null){ 
    //Decide whether or not to use autofocus 
    if(_chkAutofocus.isChecked()){ 
     Log.d(LOG_TAG, LOG_LINE + "Preparing to take the picture using autofocus..."); 

     _camera.autoFocus(new AutoFocusCallback() { 
     @Override 
     public void onAutoFocus(boolean success, Camera camera) { 
     Log.d(LOG_TAG, LOG_LINE + "_camera.autoFocus.onAutoFocus(...) entered."); 

     takePicture(); 

     Log.d(LOG_TAG, LOG_LINE + "_camera.autoFocus.onAutoFocus(...) finished."); 
     } 
     }); 
    } 
    else{ 
     Log.d(LOG_TAG, LOG_LINE + "Preparing to take the picture without autofocus..."); 

     takePicture(); 
    } 
    } 
    } 
    }); 
    } 

    private void takePicture(){ 
    Log.d(LOG_TAG, LOG_LINE + "takePicture() entered."); 

    _camera.takePicture(_shutterCallback, null, _jpegCallback); 
    _previewIsRunning = false; 

    Log.d(LOG_TAG, LOG_LINE + "takePicture() finished."); 
    } 

    private ShutterCallback _shutterCallback = new ShutterCallback() { 
    @Override 
    public void onShutter() { 
    Log.d(LOG_TAG, LOG_LINE + "_shutterCallback.onShutter() called."); 
    } 
}; 

private PictureCallback _jpegCallback = new PictureCallback() { 
    @Override 
    public void onPictureTaken(byte[] data, Camera camera) { 
    Log.d(LOG_TAG, LOG_LINE + "_jpegCallback.onPictureTaken() called."); 

    _camera.startPreview(); 
    _previewIsRunning = true; 
    } 
}; 

@Override 
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 
    if(_previewIsRunning){ 
    Log.d(LOG_TAG, LOG_LINE + "About to stop preview..."); 

    _camera.stopPreview(); 

    Log.d(LOG_TAG, LOG_LINE + "Stopped preview."); 
    } 

    try{ 
    Log.d(LOG_TAG, LOG_LINE + "About to set up camera parameters..."); 

    Camera.Parameters parameters = _camera.getParameters(); 

    //Get the optimal preview size so we don't get an exception when setting the parameters 
    List<Size> supportedPreviewSizes = parameters.getSupportedPreviewSizes(); 
    Size optimalPreviewSize = CameraUtil.getOptimalPreviewSize(supportedPreviewSizes, width, height); 

    parameters.setPreviewSize(optimalPreviewSize.width, optimalPreviewSize.height); 
    parameters.setFocusMode(Parameters.FOCUS_MODE_AUTO); 
    parameters.setFlashMode(Parameters.FLASH_MODE_AUTO); 

    _camera.setDisplayOrientation(90); 

    _camera.setParameters(parameters); 

    _camera.setPreviewDisplay(holder); 

    Log.d(LOG_TAG, LOG_LINE + "Finished setting up camera parameters."); 
    } 
    catch(Exception ex){ 
    ex.printStackTrace(); 
    Log.e(LOG_TAG, ex.toString()); 
    } 

    Log.d(LOG_TAG, LOG_LINE + "About to start preview..."); 

    _camera.startPreview(); 
    _previewIsRunning = true; 

    Log.d(LOG_TAG, LOG_LINE + "Started preview."); 
} 

@Override 
public void surfaceCreated(SurfaceHolder holder) { 
    _camera = Camera.open(); 
} 

@Override 
public void surfaceDestroyed(SurfaceHolder holder) { 
    Log.d(LOG_TAG, LOG_LINE + "Tearing down camera because surface was destroyed..."); 

    _camera.stopPreview(); 
    _previewIsRunning = false; 
    _camera.release(); 

    Log.d(LOG_TAG, LOG_LINE + "Finished tearing down camera because surface was destroyed."); 
} 

@Override 
public void onConfigurationChanged(Configuration newConfig){ 
    Log.d(LOG_TAG, LOG_LINE + "About to set request orientation to SCREEN_ORIENTATION_PORTRAIT..."); 

    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 

    Log.d(LOG_TAG, LOG_LINE + "Successfully set request orientation to SCREEN_ORIENTATION_PORTRAIT."); 
} 
} 

[CameraUtil.java]

package spikes.cameraSpike03; 

import java.util.List; 

import android.hardware.Camera.Size; 

public class CameraUtil { 
private CameraUtil(){} 

/** 
    * Returns a Size object containing the dimensions for an optimal preview size for the current hardware. 
    * This code is based on that found at: http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/graphics/CameraPreview.html 
    * 
    * @param supportedSizes 
    * A list of Size objects representing all the known preview sizes supported by this hardware. 
    * 
    * @param w 
    * The surface width. 
    * 
    * @param h 
    * The surface height. 
    * 
    * @return 
    * Returns a Size object containing the dimensions for an optimal preview size for the current hardware. 
    */ 
public static Size getOptimalPreviewSize(List<Size> supportedSizes, int w, int h) { 
     final double ASPECT_TOLERANCE = 0.05; 
     double targetRatio = (double) w/h; 
     if (supportedSizes == null) return null; 

     Size optimalSize = null; 
     double minDiff = Double.MAX_VALUE; 

     int targetHeight = h; 

     // Try to find an size match aspect ratio and size 
     for (Size size : supportedSizes) { 
      double ratio = (double) size.width/size.height; 
      if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue; 
      if (Math.abs(size.height - targetHeight) < minDiff) { 
       optimalSize = size; 
       minDiff = Math.abs(size.height - targetHeight); 
      } 
     } 

     // Cannot find the one match the aspect ratio, ignore the requirement 
     if (optimalSize == null) { 
      minDiff = Double.MAX_VALUE; 
      for (Size size : supportedSizes) { 
       if (Math.abs(size.height - targetHeight) < minDiff) { 
        optimalSize = size; 
        minDiff = Math.abs(size.height - targetHeight); 
       } 
      } 
     } 
     return optimalSize; 
    } 
} 

Cualquier sugerencia sería muy apreciada.

Gracias.

+0

bien, más pruebas parecen indicar que estos problemas sólo ocurren cuando se utiliza el enfoque automático. Hmmm .... – mahdaeng

+0

Tengo el mismo problema. Traté de cerrar los params. Pero nada cambió. Creo que también se trata de memoria. – atasoyh

+0

Por favor, eche un vistazo a esta respuesta: http://stackoverflow.com/a/31167492/2968400 –

Respuesta