之前在平板上用zbar做的二维码扫描的,摄像头方向一直不对,由于当时项目是只支持横屏,我通过int rotation = ((Activity) context).getWindowManager().getDefaultDisplay().getRotation();这个方法测得两种平板获取的值是不一样的,当时也没想太多,就加了个判断rotation%2==0或者rotation%2==1来区分两种平板了。
这几天又做一个新的项目,还要用到摄像头,并且自适应各个方向,这问题就大了,两个平板四个方向简直天差地别,后来辛苦的寻找,终于找到一个靠谱的回答,先上图
原来安卓机器还分系统默认方向的,跟摄像头的角度是两个概念~(原谅我之前是做ios的,ios判断方向比安卓简单很多)
所以呢,不像网上各种复制粘贴的
int rotation = ((Activity) context).getWindowManager()
.getDefaultDisplay()
.getRotation();
switch(rotation)
//以下省略各种case,break
不是switch rotation一下,就可以的,而是首先要判断
CameraInfo cameraInfo = new CameraInfo();
int orientation = cameraInfo.orientation;
这样再判断rotation,让摄像头显示正确的方向才行
另外,我测rotation是放在OnAutoFocus里的,这样他每聚焦一次都能判断我的方向是不是正确的
,不然它只会在初始化的时候判断,后面再旋转平板或者手机就不行了
补充android api里的介绍,这个比较详细
引入自:API 级别9
The orientation of the camera image. The value is the angle that the camera image needs to be rotated clockwise so it shows correctly on the display in its natural orientation. It should be 0, 90, 180, or 270. For example, suppose a device has a naturally tall screen. The back-facing camera sensor is mounted in landscape. You are looking at the screen. If the top side of the camera sensor is aligned with the right edge of the screen in natural orientation, the value should be 90. If the top side of a front-facing camera sensor is aligned with the right of the screen, the value should be 270.
后来又测了一下,发现竟然还不行!
在stackoverflow上找到一个方法
private int getScreenOrientation() { int rotation = ((Activity)context).getWindowManager().getDefaultDisplay().getRotation(); DisplayMetrics dm = new DisplayMetrics(); ((Activity)context).getWindowManager().getDefaultDisplay().getMetrics(dm); int width = dm.widthPixels; int height = dm.heightPixels; int orientation; // if the device's natural orientation is portrait: if ((rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) && height > width || (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) && width > height) { switch(rotation) { case Surface.ROTATION_0: orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; break; case Surface.ROTATION_90: orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; break; case Surface.ROTATION_180: orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT; break; case Surface.ROTATION_270: orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE; break; default: Log.e("", "Unknown screen orientation. Defaulting to " + "portrait."); orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; break; } } // if the device's natural orientation is landscape or if the device // is square: else { switch(rotation) { case Surface.ROTATION_0: orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; break; case Surface.ROTATION_90: orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; break; case Surface.ROTATION_180: orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE; break; case Surface.ROTATION_270: orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT; break; default: Log.e("", "Unknown screen orientation. Defaulting to " + "landscape."); orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; break; } } return orientation; }
但是这个方法也是不管用的,这个方法测得两个平板各个方向分别如下图
用int rotation = ((Activity) context).getWindowManager() .getDefaultDisplay() .getRotation();
方法测的方向是下图
最后通过这两个结合一下
switch (getScreenOrientation()) { case 0: mCamera.setDisplayOrientation(0); break; case 8: mCamera.setDisplayOrientation(180); break; case 1: if (rotation == 1) { mCamera.setDisplayOrientation(270); }else { mCamera.setDisplayOrientation(90); } break; case 9: if (rotation == 3) { mCamera.setDisplayOrientation(90); }else { mCamera.setDisplayOrientation(270); } break; default: break; }
by yoyo