我知道,这个问题曾多次被问过,但我认为没有解决方案。我正在开发应针对具有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);
这对我有用,没有抱怨过。