我知道,这个问题曾多次被问过,但我认为没有解决方案。我正在开发应针对具有android系统和后置摄像头的所有设备的应用程序。问题是我只能在两个设备上测试应用程序,并且必须确保它可以在所有设备上运行。 我认为,唯一合理的解决方案是找到可隔离在几乎所有设备上工作的相机api的代码示例。任何人都可以提供这样的资源吗……但实际上可以在maaaaany(ALL)设备上经过测试的资源吗? 我从头上掉了所有的毛...和..我在失去思想,我想...这是因为我发布了仅在我公司进行过测试的应用程序(仅用于公司中的测试)两个设备,并且以应该能使用相机api的方式工作,但似乎有些手机,例如HTC想要HD或HTC Evo 3d(带有3d相机),导致应用程序崩溃(因为相机无法正常工作)。 )或冻结(也是由于相机功能异常)。 如果有人拥有经过实际测试的相机api来源(定期在没有用户gui交互的情况下拍照),请耐心等待,如果可以的话,请发布来源或将我重定向到的正确位置。

嗯,也许这个问题听起来像是:“从技术上讲,是否可以在所有设备上使用camera api?”

也许我将描述我目前如何使用api。

1)初始化凸轮:

public void initCam()
{
    LoggingFacility.debug("Attempting to initialize camera",this);
    LoggingFacility.debug("Preview is enabled:"+isPreview,this);
    try {
        if (camera==null)
        {
            camera = Camera.open();
            camera.setPreviewDisplay(mHolder);

            if (camera!=null)
            {
                Camera.Parameters parameters = camera.getParameters();
                List<Size> sizes = parameters.getSupportedPictureSizes();
                if (sizes!=null)
                {
                    Size min = sizes.get(0);
                    for (Size size : sizes)
                        if (size.width<min.width) min = size;
                        {
                            parameters.setPictureSize(min.width, min.height);
                        }
                }

                camera.setParameters(parameters);
                setDisplayOrientation(90);
            }
        }
        startPreview(aps);
    } catch (Throwable e){
        if (exceptionsCallback!=null)
            exceptionsCallback.onException(e);
    }
}

2)开始预览:
private void startPreview(AfterPreviewStarted after)
{
    try {
        if (!isPreview)
        {
            LoggingFacility.debug("Starting preview",this);
            //camera.stopPreview();
            camera.startPreview();
            isPreview = true;
            LoggingFacility.debug("Preview is enabled:"+isPreview,this);
        }
        if (after!=null) after.doAfter();
    }catch(Throwable e)
    {
        if (exceptionsCallback!=null)
            exceptionsCallback.onException(e);
    }
}

3)拍照:
public void takePicture(final PictureCallback callback)
{
    LoggingFacility.debug("Attempting to take a picture",this);
    if (camera!=null)
    {
        if (isPreview)
        {
            try
            {
                LoggingFacility.debug("preview is enabled jut before taking picture",this);
                //AudioManager mgr = (AudioManager)ctx.getSystemService(Context.AUDIO_SERVICE);
                //mgr.setStreamMute(AudioManager.STREAM_SYSTEM, true);
                LoggingFacility.debug("Taking picture... preview will be stopped...",this);
    isPreview = false;
    camera.takePicture(null, new PictureCallback(){
        public void onPictureTaken(byte[] arg0, Camera arg1)
        {
            //LoggingFacility.debug("Picture has been taken - 1t callback",CameraPreview.this);
        }
    }, callback);

                //mgr.setStreamMute(AudioManager.STREAM_SYSTEM, false);
            } catch (Throwable e){
                if (exceptionsCallback!=null)
                    exceptionsCallback.onException(e);
            }
        }
    }

4)完成后或在表面处理后释放摄像机。
public void releaseCam()
{
    LoggingFacility.debug("Attempting to release camera",this);
    if (camera!=null)
    {
        isTakingPictures = false;
        camera.stopPreview();
        isPreview = false;
        camera.release();
        camera = null;
        LoggingFacility.debug("A camera connection has been released...",this);
    }
}

在回调方法的第3个代码段中,我再次调用startPreview,因为在拍照后,预览已禁用,并且某些智能手机要求启动预览才能制作图片。以上所有方法都是扩展 SurfaceView 和实现 SurfaceHolder.Callback 的类的一部分,并且是活动的一部分。

SurfaceHolder.Callback的实现如下:
public void surfaceCreated(SurfaceHolder holder) {
    initCam();

}

public void surfaceDestroyed(SurfaceHolder holder) {
    releaseCam();
}

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

}

类的构造函数
CameraPreview(Context context) {
    super(context);
    this.ctx = context;
    mHolder = getHolder();
    mHolder.addCallback(this);
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}

我也在考虑另一种方法-克服拍照的问题,而不是使用此方法注册onPreviewFrame回调,例如,在此回调中检查是否已请求图片的标志(如果是)-将图像转换为位图,并在进一步处理中使用它。我正在尝试这种方法,但是又遇到了另一个问题-即使我注册了空的回调,GUI的响应也会慢得多。

对于像我这样的所有人,在使用android camera API时遇到问题,请参考this link似乎此示例中的代码可在大多数智能手机上使用。

最佳答案

final int PICTURE_TAKEN = 1;

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(filename)));
startActivityForResult(intent, PICTURE_TAKEN);

这对我有用,没有抱怨过。

08-03 21:17
查看更多