2010-12-29 3 views
2

Ich benutze eine leicht modifizierte Version der Camera API Demo und es funktioniert im Emulator. Ich verwende eine Klasse reflektiert ich in einen der Mailing-Gruppen gefunden, aber ich habe immer diese Fehlermeldung erhalten, wenn auf meinem Nexus One (Android 2.2.1) Prüfung:Android 2.2 SDK - SetParameters fehlgeschlagen für Camera API auf Nexus One

12-29 13:22:04.027: ERROR/QualcommCameraHardware(2145): Invalid preview size requested: 320x402 
12-29 13:22:04.037: DEBUG/AndroidRuntime(16514): Shutting down VM 
12-29 13:22:04.037: WARN/dalvikvm(16514): threadid=1: thread exiting with uncaught exception (group=0x4001d7f0) 
12-29 13:22:04.047: ERROR/AndroidRuntime(16514): FATAL EXCEPTION: main 
12-29 13:22:04.047: ERROR/AndroidRuntime(16514): java.lang.RuntimeException: setParameters failed 
12-29 13:22:04.047: ERROR/AndroidRuntime(16514):  at android.hardware.Camera.native_setParameters(Native Method) 
12-29 13:22:04.047: ERROR/AndroidRuntime(16514):  at android.hardware.Camera.setParameters(Camera.java:647) 
12-29 13:22:04.047: ERROR/AndroidRuntime(16514):  at com.android.iwasthere.Preview.surfaceChanged(Preview.java:78) 
12-29 13:22:04.047: ERROR/AndroidRuntime(16514):  at android.view.SurfaceView.updateWindow(SurfaceView.java:538) 
12-29 13:22:04.047: ERROR/AndroidRuntime(16514):  at android.view.SurfaceView.dispatchDraw(SurfaceView.java:339) 
12-29 13:22:04.047: ERROR/AndroidRuntime(16514):  at android.view.ViewGroup.drawChild(ViewGroup.java:1638) 
12-29 13:22:04.047: ERROR/AndroidRuntime(16514):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367) 
12-29 13:22:04.047: ERROR/AndroidRuntime(16514):  at android.view.ViewGroup.drawChild(ViewGroup.java:1638) 
12-29 13:22:04.047: ERROR/AndroidRuntime(16514):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367) 
12-29 13:22:04.047: ERROR/AndroidRuntime(16514):  at android.view.ViewGroup.drawChild(ViewGroup.java:1638) 
12-29 13:22:04.047: ERROR/AndroidRuntime(16514):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367) 
12-29 13:22:04.047: ERROR/AndroidRuntime(16514):  at android.view.View.draw(View.java:6743) 
12-29 13:22:04.047: ERROR/AndroidRuntime(16514):  at android.widget.FrameLayout.draw(FrameLayout.java:352) 
12-29 13:22:04.047: ERROR/AndroidRuntime(16514):  at android.view.ViewGroup.drawChild(ViewGroup.java:1640) 
12-29 13:22:04.047: ERROR/AndroidRuntime(16514):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367) 
12-29 13:22:04.047: ERROR/AndroidRuntime(16514):  at android.view.ViewGroup.drawChild(ViewGroup.java:1638) 
12-29 13:22:04.047: ERROR/AndroidRuntime(16514):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367) 
12-29 13:22:04.047: ERROR/AndroidRuntime(16514):  at android.view.View.draw(View.java:6743) 
12-29 13:22:04.047: ERROR/AndroidRuntime(16514):  at android.widget.FrameLayout.draw(FrameLayout.java:352) 
12-29 13:22:04.047: ERROR/AndroidRuntime(16514):  at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1842) 
12-29 13:22:04.047: ERROR/AndroidRuntime(16514):  at android.view.ViewRoot.draw(ViewRoot.java:1407) 
12-29 13:22:04.047: ERROR/AndroidRuntime(16514):  at android.view.ViewRoot.performTraversals(ViewRoot.java:1163) 
12-29 13:22:04.047: ERROR/AndroidRuntime(16514):  at android.view.ViewRoot.handleMessage(ViewRoot.java:1727) 
12-29 13:22:04.047: ERROR/AndroidRuntime(16514):  at android.os.Handler.dispatchMessage(Handler.java:99) 
12-29 13:22:04.047: ERROR/AndroidRuntime(16514):  at android.os.Looper.loop(Looper.java:123) 
12-29 13:22:04.047: ERROR/AndroidRuntime(16514):  at android.app.ActivityThread.main(ActivityThread.java:4627) 
12-29 13:22:04.047: ERROR/AndroidRuntime(16514):  at java.lang.reflect.Method.invokeNative(Native Method) 
12-29 13:22:04.047: ERROR/AndroidRuntime(16514):  at java.lang.reflect.Method.invoke(Method.java:521) 
12-29 13:22:04.047: ERROR/AndroidRuntime(16514):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858) 
12-29 13:22:04.047: ERROR/AndroidRuntime(16514):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
12-29 13:22:04.047: ERROR/AndroidRuntime(16514):  at dalvik.system.NativeStart.main(Native Method) 

CameraPreview.java

package xxx; 
import android.app.Activity; 
import android.os.Bundle; 
import android.view.Window; 

public class CameraPreview extends Activity { 

    private Preview mPreview; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 

     super.onCreate(savedInstanceState); 
     requestWindowFeature(Window.FEATURE_NO_TITLE); 

     mPreview = new Preview(this); 
     setContentView(mPreview); 

    } 

} 

Preview.java

package xxx; 
import java.io.IOException; 
import java.util.List; 

import android.content.Context; 
import android.hardware.Camera; 
import android.hardware.Camera.Size; 
import android.view.SurfaceHolder; 
import android.view.SurfaceView; 

class Preview extends SurfaceView implements SurfaceHolder.Callback { 

    SurfaceHolder mHolder; 
    Camera mCamera; 

    Preview(Context context) { 
     super(context); 

     mHolder = getHolder(); 
     mHolder.addCallback(this); 
     mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 

    } 

    public void surfaceCreated(SurfaceHolder holder) { 

     mCamera = Camera.open(); 
     try { 

      mCamera.setPreviewDisplay(holder); 

     } catch (IOException exception) { 

      mCamera.release(); 
      mCamera = null; 

     } 

    } 

    public void surfaceDestroyed(SurfaceHolder holder) { 

     mCamera.stopPreview(); 
     mCamera.release(); 
     mCamera = null; 

    } 


    private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) { 

     final double ASPECT_TOLERANCE = 0.05; 
     double targetRatio = (double) w/h; 
     if (sizes == null) return null; 

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

     int targetHeight = h; 

     for (Size size : sizes) { 
      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); 
      } 
     } 

     if (optimalSize == null) { 
      minDiff = Double.MAX_VALUE; 
      for (Size size : sizes) { 
       if (Math.abs(size.height - targetHeight) < minDiff) { 
        optimalSize = size; 
        minDiff = Math.abs(size.height - targetHeight); 
       } 
      } 
     } 

     return optimalSize; 

    } 

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 

     Camera.Parameters parameters = mCamera.getParameters(); 

     //MODIFIED HERE 
     List<Size> sizes = Reflect.getSupportedPictureSizes(parameters); 
     //List<Size> sizes = parameters.getSupportedPreviewSizes(); 
     Size optimalSize = getOptimalPreviewSize(sizes, w, h); 
     parameters.setPreviewSize(optimalSize.width, optimalSize.height); 

     mCamera.setParameters(parameters); 
     mCamera.startPreview(); 

    } 

} 

Reflect.java

package xxx; 
import java.lang.reflect.InvocationTargetException; 
import java.lang.reflect.Method; 
import java.util.List; 

import android.hardware.Camera; 
import android.hardware.Camera.Size; 

public class Reflect { 

    private static Method Parameters_getSupportedPictureSizes; 
    private static Method Parameters_getSupportedPreviewSizes; 

    static { 
     initCompatibility(); 
    }; 

    private static void initCompatibility() { 
     try { 
      Parameters_getSupportedPictureSizes = Camera.Parameters.class 
        .getMethod("getSupportedPictureSizes", new Class[] {}); 
      /* success, this is a newer device */ 
     } catch (NoSuchMethodException nsme) { 
      /* failure, must be older device */ 
     } 
     try { 
      Parameters_getSupportedPreviewSizes = Camera.Parameters.class 
        .getMethod("getSupportedPreviewSizes", new Class[] {}); 
      /* success, this is a newer device */ 
     } catch (NoSuchMethodException nsme) { 
      /* failure, must be older device */ 
     } 
    } 

    @SuppressWarnings("unchecked") 
    public static List<Size> getSupportedPictureSizes(Camera.Parameters p) { 
     try { 
      if (Parameters_getSupportedPictureSizes != null) { 
       return (List<Size>) Parameters_getSupportedPictureSizes 
         .invoke(p); 
      } else { 
       return null; 
      } 
     } catch (InvocationTargetException ite) { 
      /* unpack original exception when possible */ 
      Throwable cause = ite.getCause(); 
      if (cause instanceof RuntimeException) { 
       throw (RuntimeException) cause; 
      } else if (cause instanceof Error) { 
       throw (Error) cause; 
      } else { 
       throw new RuntimeException(ite); 
      } 
     } catch (IllegalAccessException ie) { 
      System.err.println("unexpected " + ie); 
      return null; 
     } 
    } 

    @SuppressWarnings("unchecked") 
    public static List<Size> getSupportedPreviewSizes(Camera.Parameters p) { 
     try { 
      if (Parameters_getSupportedPreviewSizes != null) { 
       return (List<Size>) Parameters_getSupportedPreviewSizes 
         .invoke(p); 
      } else { 
       return null; 
      } 
     } catch (InvocationTargetException ite) { 
      /* unpack original exception when possible */ 
      Throwable cause = ite.getCause(); 
      if (cause instanceof RuntimeException) { 
       throw (RuntimeException) cause; 
      } else if (cause instanceof Error) { 
       throw (Error) cause; 
      } else { 
       /* 
       * unexpected checked exception; wrap and re-throw 
       */ 
       throw new RuntimeException(ite); 
      } 
     } catch (IllegalAccessException ie) { 
      return null; 
     } 
    } 
} 

Antwort

2

Ungültige Vorschaugröße angefordert: 320x402

Sie können nicht beliebig Vorschau Größen verwenden. Sie müssen Camera.Parameters.getSupportedPreviewSizes() und Camera.Parameters.getSupportedPictureSizes() verwenden, um die nächste Vorschau und die Bildgröße in der gewünschten Größe zu finden.

+0

Ich mache das in der reflect-Klasse. Die App funktioniert auch auf einem 2.3-Gerät. –

+0

320 x 402 wird nicht als unterstützte Vorschaugröße auf meinem Nexus One zurückgegeben, sodass entweder getOptimalPreviewSize nicht korrekt ist oder die Ausgabe von getSupportedPreview/PictureSize() auf Ihrem Gerät anders ist. Die Kameratreiber variieren stark auf Android-Geräten. Ihr 2.3-Gerät wird automatisch auf die nächste unterstützte Größe gerundet. –

+0

Guter Punkt. Ich werde sehen, was dort passiert und die Ergebnisse veröffentlichen. –