Girando el teléfono rápidamente 180 grados, la vista previa de la cámara se pone boca abajo

Tengo una aplicación de cámara personalizada. Cuando giro el teléfono 90, la vista previa de la cámara funciona bien. Pero cuando giro el teléfono rápidamente 180 grados, la vista previa de la cámara se pone boca abajo. Hay alguna solución…

Aquí está mi código a continuación:

public class CustomCameraActivity extends Activity implements SurfaceHolder.Callback { Camera camera; SurfaceView surfaceView; SurfaceHolder surfaceHolder; boolean previewing = false; LayoutInflater controlInflater = null; private Sensor mOrientaion1; int cameraId = 0; public final String TAG = "CustomCamera"; private SensorManager sensorManager; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(R.layout.main); context = this; sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); mOrientaion1 = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION); // setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); imageView = (ImageView) findViewById(R.id.imgError); getWindow().setFormat(PixelFormat.UNKNOWN); surfaceView = (SurfaceView) findViewById(R.id.camerapreview); surfaceHolder = surfaceView.getHolder(); surfaceHolder.addCallback(this); surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); controlInflater = LayoutInflater.from(getBaseContext()); View viewControl = controlInflater.inflate(R.layout.custom, null); LayoutParams layoutParamsControl = new LayoutParams( LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT); Button btn1 = (Button) viewControl.findViewById(R.id.Button01); Button btn2 = (Button) viewControl.findViewById(R.id.Button02); btn1.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // Toast.makeText(context, "1111111111111111111111111", // Toast.LENGTH_SHORT).show(); camera.takePicture(null, null, mPicture); Constant.rotationValueForCamera = Constant.rotationValue; } }); btn2.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // Toast.makeText(context, "22222222222222222222222222", // Toast.LENGTH_SHORT).show(); Log.e("0 imagePickerStatus", Constant.imagePickerStatus + ""); Constant.imagePickerStatus = 0; Log.e("0 imagePickerStatus", Constant.imagePickerStatus + ""); finish(); } }); this.addContentView(viewControl, layoutParamsControl); int ot = getResources().getConfiguration().orientation; if (Configuration.ORIENTATION_LANDSCAPE == ot) { imageView.setVisibility(View.GONE); Log.e("ori1111", "land"); } else { imageView.setVisibility(View.VISIBLE); Log.e("ori111", "port"); } } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); // Checks the orientation of the screen if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { // Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show(); findViewById(R.id.Button01).setVisibility(View.VISIBLE); findViewById(R.id.Button02).setVisibility(View.VISIBLE); imageView.setVisibility(View.GONE); Log.e("ori", "land"); } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) { // Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show(); findViewById(R.id.Button01).setVisibility(View.INVISIBLE); findViewById(R.id.Button02).setVisibility(View.INVISIBLE); imageView.setVisibility(View.VISIBLE); Log.e("ori", "port"); } } public String getPollDeviceAttitude() { return Constant.rotationValueForCamera; } private SensorEventListener sensorEventListener = new SensorEventListener() { public void onAccuracyChanged(Sensor sensor, int accuracy) { } }; protected void onPause() { super.onPause(); sensorManager.unregisterListener(sensorEventListener); } @Override public void onResume() { super.onResume(); sensorManager.registerListener(sensorEventListener, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL); sensorManager.registerListener(sensorEventListener, sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), SensorManager.SENSOR_DELAY_NORMAL); sensorManager.registerListener(sensorEventListener, sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), SensorManager.SENSOR_DELAY_NORMAL); if (Constant.isCapturedOk) { Constant.isCapturedOk = false; finish(); } } PictureCallback mPicture = new PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { Log.e("Camrera", "22222222222222222"); BitmapFactory.Options bfo = new BitmapFactory.Options(); bfo.inDither = false; // bfo.inJustDecodeBounds = true; bfo.inPurgeable = true; bfo.inTempStorage = new byte[16 * 1024]; Intent intent = new Intent(context, PreviewActivity.class); // intent.putExtra("data", data); Bitmap bitmapPicture = BitmapFactory.decodeByteArray(data, 0, data.length, bfo); Matrix matrix = new Matrix(); if (Constant.result == 180) { matrix.postRotate(270); } if (Constant.result == 270) { matrix.postRotate(180); } int height = bitmapPicture.getHeight(); int width = bitmapPicture.getWidth(); Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmapPicture, height, width, true); Bitmap rotatedBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true); ByteArrayOutputStream blob = new ByteArrayOutputStream(); Log.e("Camrera1", "22222222222222222"); rotatedBitmap.compress(CompressFormat.JPEG, 50 /* ignored for PNG */, blob); byte[] bitmapdata = blob.toByteArray(); Constant.imageData = bitmapdata; Log.e("Camrera2", "22222222222222222"); startActivity(intent); } }; @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { if (previewing) { camera.stopPreview(); previewing = false; } if (camera != null) { try { camera.setPreviewDisplay(holder); camera.startPreview(); setCameraDisplayOrientation(this, cameraId, camera); previewing = true; } catch (Exception e) { e.printStackTrace(); } } } public static void setCameraDisplayOrientation(Activity activity, int cameraId, android.hardware.Camera camera) { android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo(); android.hardware.Camera.getCameraInfo(cameraId, info); int rotation = activity.getWindowManager().getDefaultDisplay() .getRotation(); int degrees = 0; switch (rotation) { case Surface.ROTATION_0: degrees = 0; Constant.result = 0; break; case Surface.ROTATION_90: degrees = 90; Constant.result = 90; break; case Surface.ROTATION_180: degrees = 180; Constant.result = 180; break; case Surface.ROTATION_270: degrees = 270; Constant.result = 270; break; } int result; if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { result = (info.orientation + degrees) % 360; result = (360 - result) % 360; // compensate the mirror } else { // back-facing result = (info.orientation - degrees + 360) % 360; } camera.setDisplayOrientation(result); } @Override public void surfaceCreated(SurfaceHolder holder) { camera = Camera.open(); } @Override public void surfaceDestroyed(SurfaceHolder holder) { camera.stopPreview(); camera.release(); camera = null; previewing = false; } @Override protected void onStop() { super.onStop(); Log.e("Tab", "Stoping"); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { return true; } return super.onKeyDown(keyCode, event); } 

}

La aplicación bloquea la imagen

Puede usar OrientationEventListener para activar el recálculo de la rotación de la cámara.

Agrega a tu actividad:

 private OrientationEventListener orientationListener = null; 

a onCreate() :

 orientationListener = new OrientationEventListener(this) { public void onOrientationChanged(int orientation) { setCameraDisplayOrientation(CustomCameraActivity.this, cameraId, camera); } }; 

a surfaceCreated() :

 orientationListener.enable(); 

a surfaceDestroyed() :

 orientationListener.disable(); 

Ahora, casi funciona. Para hacer que setCameraDisplayOrientation() más robusto,

  1. agregar cheque para la camera != null
  2. solo llame a camera.setDisplayOrientation(result) (o realice cualquier trabajo pesado) si el result cambiado desde la última vez que se llamó a la función.

android: configChanges = “keyboardHidden | orientation | screenSize”

Agregue esta línea en su archivo de Manifiesto de Android después de declarar todas las actividades en las tags de actividad *

 like:  

Puede ser que te ayude.