1

我遇到了我认为是特定于设备的问题,但我想看看其他人以前是否见过这种行为。下面是我用来在相机活动中捕获 JPEG 的代码:

surfaceView.setOnClickListener(new View.OnClickListener() {

    @Override
    public void onClick(View v) {
        camera.autoFocus(new AutoFocusCallback() {

            @Override
            public void onAutoFocus(boolean success, Camera camera) {
                if(success)
                {                           
                    Log.d(TAG, "Focusing...successful.");
                    camera.takePicture(null, null, null, jpegCallback);
                }
                else
                {
                    Log.d(TAG, "Focusing...failed.");
                }

            }

        });
    }
});

此代码在我的 Nexus 4 上运行良好,但今天下午我在三星 Galaxy S3 上尝试了它,相机服务器崩溃并显示以下错误消息:

Focusing...successful.
Camera server died!
ICamera died
Error 100

从 LogCat 中可以看出,失败发生在camera.takePicture(...)被调用时(即jpegCallback从未被调用)。后来我找了一个朋友用三星 Galaxy Note 试用它,它在他们的手机上运行良好。

我不应该从自动对焦回调中拍照吗?这似乎是放置它的合适位置。这里的任何见解都会很棒!

4

1 回答 1

3

我不久前想出了这个问题,并想让其他人知道如何解决这个问题。导致崩溃的原因是将预览尺寸设置为大于设备的屏幕尺寸。这就是为什么三星 Galaxy S3 会崩溃,而不是 Nexus 4。下面是我更改的相关代码:

private Camera.Size getBestPreviewSize(List<Camera.Size> previewSizes, int width, int height) {
                double targetAspect = (double)width / (double)height;

        ArrayList<Camera.Size> matchedPreviewSizes = new ArrayList<Camera.Size>();
        final double ASPECT_TOLERANCE = 0.1;
        for(Size previewSize : previewSizes) {
                double previewAspect = (double)previewSize.width / (double)previewSize.height;

                // Original broken code.
                //if(Math.abs(targetAspect - previewAspect) < ASPECT_TOLERANCE) {
                //        matchedPreviewSizes.add(previewSize);
                //}

                // Working code.
                if(Math.abs(targetAspect - previewAspect) < ASPECT_TOLERANCE &&
                            previewSize.width <= width && previewSize.height <= height) {
                        matchedPreviewSizes.add(previewSize);
                }
        }

        Camera.Size bestPreviewSize;
        if(!matchedPreviewSizes.isEmpty()) {
                bestPreviewSize = Collections.max(matchedPreviewSizes, sizeComparator);
        } else {
                bestPreviewSize = Collections.max(previewSizes, sizeComparator);
        }

        return bestPreviewSize;
}

private Comparator<Camera.Size> sizeComparator = new Comparator<Camera.Size>() {

    @Override
    public int compare(Size lhs, Size rhs) {
        long lhsArea = lhs.height*lhs.width;
        long rhsArea = rhs.height*rhs.width;

        if(lhsArea > rhsArea) {
            return 1;
        } else if(lhsArea < rhsArea) {
            return -1;
        } else {
            return 0;
        }
    }

};

在上面的代码中,我展示了原始损坏的代码以及导致我的函数尊重设备最大屏幕尺寸的工作代码。这样做修复了各种设备上发生的崩溃。

希望有帮助!

于 2013-04-20T22:34:55.930 回答