Android开发遇到Camera StartPreview Failed 错误

闲来无事想用OpenCV做点东西。2.4.2的OpenCV在Android上推荐使用的Manager需要用户额外从Google Play上下载opencv的manager 。费了好大功夫才找到本地的方法,还得看官方的文档啊,想偷懒来着,结果兄弟们都是东抄西抄啊。。。http://docs.opencv.org/trunk/doc/tutorials/introduction/android_binary_package/dev_with_OCV_on_Android.html


进入正题,没有使用OpenCV的camera,使用SDK中的camera。加权限,创建SurfaceView绑定holder,一切顺利。在4.1中跑了一下。ok没问题。

昨晚手欠又将defy的4.1刷回2.3了(4.1还是不够稳定)。结果早晨来试了一下,悲剧。错误信息 RuntimeException: startPreview Failed。


找了N多的blog,兄弟们还是总是在抄。终于在stackoverflow中找到答案。

http://stackoverflow.com/questions/7942378/android-camera-will-not-work-startpreview-fails

添加

sufaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);


本来之前也怀疑了一下,但是轻信了Google 的document,结果。。。

这个deprecated的api会在低版本中导致crash。

打完收工。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
以下是使用Camera2 API进行录像并保存的相关代码: 1. 添加权限到 AndroidManifest.xml 文件中: ```xml <uses-feature android:name="android.hardware.camera"/> <uses-feature android:name="android.hardware.camera.autofocus"/> <uses-feature android:name="android.hardware.camera2.full"/> <uses-permission android:name="android.permission.CAMERA"/> <uses-permission android:name="android.permission.RECORD_AUDIO"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> ``` 2. 在布局文件中添加一个 SurfaceView 用于预览相机: ```xml <SurfaceView android:id="@+id/surface_view" android:layout_width="match_parent" android:layout_height="match_parent" /> ``` 3. 在 Activity 中定义相机设备和相机预览会话: ```java private CameraDevice mCameraDevice; private CameraCaptureSession mPreviewSession; ``` 4. 初始化相机设备并打开相机: ```java private void openCamera() { CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE); try { String cameraId = manager.getCameraIdList()[0]; CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId); StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); mVideoSize = chooseVideoSize(map.getOutputSizes(MediaRecorder.class)); mPreviewSize = chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class), mVideoSize.getWidth(), mVideoSize.getHeight()); mMediaRecorder = new MediaRecorder(); if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { return; } manager.openCamera(cameraId, mStateCallback, null); } catch (CameraAccessException e) { e.printStackTrace(); } } private CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() { @Override public void onOpened(CameraDevice camera) { mCameraDevice = camera; startPreview(); } @Override public void onDisconnected(CameraDevice camera) { camera.close(); mCameraDevice = null; } @Override public void onError(CameraDevice camera, int error) { camera.close(); mCameraDevice = null; } }; ``` 5. 创建相机预览会话: ```java private void startPreview() { SurfaceTexture texture = mTextureView.getSurfaceTexture(); texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight()); Surface surface = new Surface(texture); try { mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); mPreviewBuilder.addTarget(surface); mCameraDevice.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback() { @Override public void onConfigured(CameraCaptureSession session) { mPreviewSession = session; updatePreview(); } @Override public void onConfigureFailed(CameraCaptureSession session) { // failed } }, null); } catch (CameraAccessException e) { e.printStackTrace(); } } private void updatePreview() { if (null == mCameraDevice) { return; } mPreviewBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO); HandlerThread thread = new HandlerThread("CameraPreview"); thread.start(); Handler backgroundHandler = new Handler(thread.getLooper()); try { mPreviewSession.setRepeatingRequest(mPreviewBuilder.build(), null, backgroundHandler); } catch (CameraAccessException e) { e.printStackTrace(); } } ``` 6. 开始录像: ```java private void startRecordingVideo() { if (null == mCameraDevice || !mTextureView.isAvailable() || null == mPreviewSize) { return; } try { closePreviewSession(); setUpMediaRecorder(); SurfaceTexture texture = mTextureView.getSurfaceTexture(); texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight()); mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD); List<Surface> surfaces = new ArrayList<>(); Surface previewSurface = new Surface(texture); surfaces.add(previewSurface); mPreviewBuilder.addTarget(previewSurface); Surface recorderSurface = mMediaRecorder.getSurface(); surfaces.add(recorderSurface); mPreviewBuilder.addTarget(recorderSurface); mCameraDevice.createCaptureSession(surfaces, new CameraCaptureSession.StateCallback() { @Override public void onConfigured(CameraCaptureSession cameraCaptureSession) { mPreviewSession = cameraCaptureSession; updatePreview(); runOnUiThread(new Runnable() { @Override public void run() { mIsRecordingVideo = true; mMediaRecorder.start(); } }); } @Override public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) { // failed } }, null); } catch (Exception e) { e.printStackTrace(); } } private void setUpMediaRecorder() throws IOException { final Activity activity = this; if (null == activity) { return; } mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE); mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); mMediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString()); mMediaRecorder.setVideoEncodingBitRate(10000000); mMediaRecorder.setVideoFrameRate(30); mMediaRecorder.setVideoSize(mVideoSize.getWidth(), mVideoSize.getHeight()); mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); int rotation = activity.getWindowManager().getDefaultDisplay().getRotation(); switch (mSensorOrientation) { case SENSOR_ORIENTATION_DEFAULT_DEGREES: mMediaRecorder.setOrientationHint(DEFAULT_ORIENTATIONS.get(rotation)); break; case SENSOR_ORIENTATION_INVERSE_DEGREES: mMediaRecorder.setOrientationHint(INVERSE_ORIENTATIONS.get(rotation)); break; } mMediaRecorder.prepare(); } private void closePreviewSession() { if (mPreviewSession != null) { mPreviewSession.close(); mPreviewSession = null; } } private void stopRecordingVideo() { mIsRecordingVideo = false; mMediaRecorder.stop(); mMediaRecorder.reset(); startPreview(); } ``` 7. 释放相机: ```java private void releaseCamera() { if (null != mCameraDevice) { mCameraDevice.close(); mCameraDevice = null; } } ``` 8. 创建保存视频的文件: ```java private static File getOutputMediaFile(int type) { File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES), "MyCameraApp"); if (!mediaStorageDir.exists()) { if (!mediaStorageDir.mkdirs()) { return null; } } String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); File mediaFile; if (type == MEDIA_TYPE_VIDEO) { mediaFile = new File(mediaStorageDir.getPath() + File.separator + "VID_" + timeStamp + ".mp4"); } else { return null; } return mediaFile; } ``` 注意:需要在 Android 6.0 及以上版本动态请求相机和存储权限。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值