У меня есть пользовательский SurfaceView для предварительного просмотра камеры. Когда я запускаю Activity с ним, приложение вылетает с RuntimeException, которое говорит: startPreview failed
и Camera Error 1 в методе surfaceChanged. Что не так? Ниже мой взгляд на поверхность и активность.Android-камера startPreview не работает при запуске activiy
public class CameraView extends SurfaceView implements SurfaceHolder.Callback {
private Path mClipPath;
private Camera mCamera;
private Context mContext;
private SurfaceHolder mHolder;
public CameraView(Context context) {
super(context);
init(context);
}
public CameraView(Context context, Camera camera) {
super(context);
mCamera = camera;
mHolder = getHolder();
mHolder.addCallback(this);
init(context);
}
public CameraView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public CameraView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public CameraView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context);
}
private void init(Context context) {
mContext = context;
WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = manager.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
float radius;
float center;
if (display.getRotation() == Surface.ROTATION_0 || display.getRotation() == Surface.ROTATION_180) {
radius = size.x/2;
center = size.x/2;
} else {
radius = size.y/2;
center = size.y/2;
}
mClipPath = new Path();
mClipPath.addCircle(center, center, radius, Path.Direction.CW);
}
@Override
protected void dispatchDraw(Canvas canvas) {
canvas.clipPath(mClipPath);
super.dispatchDraw(canvas);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if (mHolder.getSurface() == null) {
return;
}
try {
mCamera.stopPreview();
} catch (Exception e) {
e.printStackTrace();
}
Camera.Parameters parameters = mCamera.getParameters();
Display display = ((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
if (display.getRotation() == Surface.ROTATION_0) {
parameters.setPreviewSize(height, width);
mCamera.setDisplayOrientation(90);
}
if (display.getRotation() == Surface.ROTATION_90) {
parameters.setPreviewSize(width, height);
}
if (display.getRotation() == Surface.ROTATION_180) {
parameters.setPreviewSize(height, width);
}
if (display.getRotation() == Surface.ROTATION_270) {
parameters.setPreviewSize(width, height);
mCamera.setDisplayOrientation(180);
}
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
}
и активность
public class CameraActivity extends AppCompatActivity {
public static final String EXTRA_PICTURE = "com.rcd.perfecto.extra.PICTURE";
@Bind(R.id.btn_photo_capture) Button mPhotoCaptureButton;
@Bind(R.id.fl_camera_preview) FrameLayout mCameraPreviewFrameLayout;
@Bind(R.id.btn_choose_from_gallery) Button mChooseFromGalleryButton;
@Bind(R.id.iv_avatar) RoundedImageView mAvatarImageView;
private Camera mCamera;
private CameraView mCameraView;
private boolean mCaptured = false;
private byte[] mData;
private Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
mData = data;
}
};
public CameraActivity() {
}
@OnClick(R.id.btn_photo_capture)
void takePicture() {
mCameraView.setVisibility(View.VISIBLE);
mAvatarImageView.setVisibility(View.GONE);
if (!mCaptured) {
mCamera.takePicture(null, null, mPictureCallback);
mPhotoCaptureButton.setText(R.string.reshoot);
}
else {
mCamera.startPreview();
mPhotoCaptureButton.setText(R.string.btn_photo_capture);
}
mCaptured = !mCaptured;
}
@OnClick(R.id.btn_choose_from_gallery)
void chooseFromGallery() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent, 0);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
ButterKnife.bind(this);
if (checkCameraHardware()) {
if (Camera.getNumberOfCameras() > 1) {
mCamera = getCameraInstance(Camera.CameraInfo.CAMERA_FACING_FRONT);
} else mCamera = getCameraInstance();
}
mCameraView = new CameraView(CameraActivity.this, mCamera);
mCameraPreviewFrameLayout.addView(mCameraView, 0);
}
@Override
protected void onDestroy() {
super.onDestroy();
mCamera.release();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_camera, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.me_done:
Intent intent = new Intent();
if (mData != null) {
intent.putExtra(EXTRA_PICTURE, mData);
}
setResult(RESULT_OK, intent);
finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private static Camera getCameraInstance() {
Camera c = null;
try {
c = Camera.open();
} catch (Exception e) {
e.printStackTrace();
}
return c;
}
private static Camera getCameraInstance(int id) {
Camera c = null;
try {
c = Camera.open(id);
} catch (Exception e) {
e.printStackTrace();
}
return c;
}
private boolean checkCameraHardware() {
return getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
Uri imageUri = data.getData();
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), imageUri);
mCameraView.setVisibility(View.GONE);
mAvatarImageView.setVisibility(View.VISIBLE);
mAvatarImageView.setImageBitmap(bitmap);
mCaptured = true;
mPhotoCaptureButton.setText(R.string.reshoot);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
mData = stream.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
EDIT: Добавлена полная трассировка стека:
03-03 12:03:28.158 29399-29399/com.rcd.perfecto W/System.err: java.lang.RuntimeException: startPreview failed
03-03 12:03:28.158 29399-29399/com.rcd.perfecto W/System.err: at android.hardware.Camera.startPreview(Native Method)
03-03 12:03:28.158 29399-29399/com.rcd.perfecto W/System.err: at com.rcd.perfecto.ui.custom.CameraView.surfaceChanged(CameraView.java:122)
03-03 12:03:28.158 29399-29399/com.rcd.perfecto W/System.err: at android.view.SurfaceView.updateWindow(SurfaceView.java:594)
03-03 12:03:28.159 29399-29399/com.rcd.perfecto W/System.err: at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:177)
03-03 12:03:28.159 29399-29399/com.rcd.perfecto W/System.err: at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:944)
03-03 12:03:28.159 29399-29399/com.rcd.perfecto W/System.err: at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2055)
03-03 12:03:28.159 29399-29399/com.rcd.perfecto W/System.err: at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1107)
03-03 12:03:28.159 29399-29399/com.rcd.perfecto W/System.err: at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6013)
03-03 12:03:28.159 29399-29399/com.rcd.perfecto W/System.err: at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)
03-03 12:03:28.159 29399-29399/com.rcd.perfecto W/System.err: at android.view.Choreographer.doCallbacks(Choreographer.java:670)
03-03 12:03:28.159 29399-29399/com.rcd.perfecto W/System.err: at android.view.Choreographer.doFrame(Choreographer.java:606)
03-03 12:03:28.159 29399-29399/com.rcd.perfecto W/System.err: at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)
03-03 12:03:28.159 29399-29399/com.rcd.perfecto W/System.err: at android.os.Handler.handleCallback(Handler.java:739)
03-03 12:03:28.159 29399-29399/com.rcd.perfecto W/System.err: at android.os.Handler.dispatchMessage(Handler.java:95)
03-03 12:03:28.159 29399-29399/com.rcd.perfecto W/System.err: at android.os.Looper.loop(Looper.java:148)
03-03 12:03:28.159 29399-29399/com.rcd.perfecto W/System.err: at android.app.ActivityThread.main(ActivityThread.java:5417)
03-03 12:03:28.159 29399-29399/com.rcd.perfecto W/System.err: at java.lang.reflect.Method.invoke(Native Method)
03-03 12:03:28.159 29399-29399/com.rcd.perfecto W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
03-03 12:03:28.159 29399-29399/com.rcd.perfecto W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
03-03 12:03:28.207 29399-29399/com.rcd.perfecto E/Camera: Error 1
Может пожалуйста, напишите полный LogCat исключительной ситуации? Благодаря! – fasteque
, который api вы используете после 21 камеры api устарел – RDY
Я знаю об этом, но он работал раньше и в API 21, я ничего не менял –