android录像摄像头卡死,Android用摄像头的那点破事

本文介绍了在Android中处理摄像头录像卡死的问题,主要涉及摄像头参数的适配,包括获取支持的预览尺寸和图片尺寸。通过反射方法解决在不同Android版本上的兼容性问题,确保在老版本系统上也能正常工作。同时,针对预览画面旋转问题提出了解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

摄像头不是所有随便的(w, h)都能够认识的,所以呢,我们有了下面这样的增强版:

List mSupportedPreviewSizes;

mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();

mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);

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

final double ASPECT_TOLERANCE = 0.1;

double targetRatio = (double) w / h;

if (sizes == 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 : 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);

}

}

// Cannot find the one match the aspect ratio, ignore the requirement

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;

}

后来的Sample里有了这段代码,看起来强大了不少。然而非常不幸的,首先getSupportedPreviewSizes()这个函数在2.1之后才有,我一开始是打算用1.6开发的……好吧我改,这个先不说,自己的手机已经刷到2.1了,这个函数的返回值居然是null?!如果确实想老版本上也用的话,怎么办??

有鉴于有软件可以达成,所以肯定是有方法的!得这么写:

public class SupportedSizesReflect {

private static Method Parameters_getSupportedPreviewSizes = null;

private static Method Parameters_getSupportedPictureSizes = null;

static {

initCompatibility();

};

private static void initCompatibility() {

try {

Parameters_getSupportedPreviewSizes = Camera.Parameters.class.getMethod(

"getSupportedPreviewSizes", new Class[] {});

Parameters_getSupportedPictureSizes = Camera.Parameters.class.getMethod(

"getSupportedPictureSizes", new Class[] {});

} catch (NoSuchMethodException nsme) {

nsme.printStackTrace();

Parameters_getSupportedPreviewSizes = Parameters_getSupportedPictureSizes = null;

}

}

/**

* Android 2.1之后有效

* @param p

* @return Android1.x返回null

*/

public static List getSupportedPreviewSizes(Camera.Parameters p) {

return getSupportedSizes(p, Parameters_getSupportedPreviewSizes);

}

public static List getSupportedPictureSizes(Camera.Parameters p){

return getSupportedSizes(p, Parameters_getSupportedPictureSizes);

}

@SuppressWarnings("unchecked")

private static List getSupportedSizes(Camera.Parameters p, Method method){

try {

if (method != null) {

return (List) method.invoke(p);

} else {

return null;

}

} catch (InvocationTargetException ite) {

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

return null;

}

}

}

啊啊~,リフレクションなんか、大嫌い……然后还要用类似这样的方法调用~

@Override

public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {

Camera.Parameters params = camera.getParameters();

List supportedPictureSizes

= SupportedSizesReflect.getSupportedPictureSizes(params);

List supportedPreviewSizes

= SupportedSizesReflect.getSupportedPreviewSizes(params);

if ( supportedPictureSizes != null &&

supportedPreviewSizes != null &&

supportedPictureSizes.size() > 0 &&

supportedPreviewSizes.size() > 0) {

//2.x

pictureSize = supportedPictureSizes.get(0);

int maxSize = 1280;

if(maxSize > 0){

for(Size size : supportedPictureSizes){

if(maxSize >= Math.max(size.width,size.height)){

pictureSize = size;

break;

}

}

}

WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);

Display display = windowManager.getDefaultDisplay();

DisplayMetrics displayMetrics = new DisplayMetrics();

display.getMetrics(displayMetrics);

previewSize = getOptimalPreviewSize(

supportedPreviewSizes,

display.getWidth(),

display.getHeight());

params.setPictureSize(pictureSize.width, pictureSize.height);

params.setPreviewSize(previewSize.width, previewSize.height);

}

this.camera.setParameters(params);

try {

this.camera.setPreviewDisplay(holder);

} catch (IOException e) {

e.printStackTrace();

}

this.camera.startPreview();

}

预览画面90°的,2.X后可以用parameters.set(“rotation”, “90″),之前的话得写成parameters.set(“orientation”, “portrait”)。但是据说不是所有的机器都可以的……

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值