我正在使用稍微修改过的Camera API Demo版本,它可以在模拟器中使用。我正在使用我在其中一个邮件组中找到的反射类,但在我的Nexus One(Android 2.2.1)上测试时仍然出现此错误:
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;
}
}
}
答案 0 :(得分:2)
请求的预览尺寸无效: 320x402
您无法使用任意预览尺寸。您需要使用Camera.Parameters.getSupportedPreviewSizes()和Camera.Parameters.getSupportedPictureSizes()来查找最接近您所需尺寸的预览和图片大小。