我有自定义相机应用程序.当我将手机旋转90度时,相机预览工作正常.但是当我将手机快速旋转180度时,相机预览会颠倒过来.有没有解决方案……
这是我的代码如下:
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.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,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,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); }
}
解决方法
您可以使用
OrientationEventListener触发重新计算相机旋转.
添加到您的活动:
private OrientationEventListener orientationListener = null;
到onCreate():
orientationListener = new OrientationEventListener(this) { public void onOrientationChanged(int orientation) { setCameraDisplayOrientation(CustomCameraActivity.this,camera); } };
到surfaceCreated():
orientationListener.enable();
到surfaceDestroyed():
orientationListener.disable();
现在,它几乎可以工作.要使setCameraDisplayOrientation()更健壮,
>添加相机检查!= null>如果自上次调用函数后结果发生更改,则仅调用camera.setDisplayOrientation(result)(或执行任何繁重的操作).