拍照功能横竖屏切换问题

最近项目中要求针对拍照功能添加横竖屏切换,具体需求如下

1.横竖屏加载不同的布局;

2.只处理0度横屏和90度竖屏,180度横屏和270度竖屏不做处理;

3.能通过系统的自动旋转开关控制横竖屏切换功能的开启关闭;

起初打算利用的系统的横竖屏切换功能来实现,具体操作如下

1.清单文件中配置 android:configChanges

2.重写 onConfigurationChanged() 方法

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        
    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
        
    }
}

但是发现这样做存在一些问题,比如说

1.每次只能旋转90度,才能触发 onConfigurationChanged() 方法的回调,如果突然翻转180度,或者快速从0度到90度再到180度都是无法触发 onConfigurationChanged() 方法回调的;

2.无法满足只处理0度和90度的情况;

所以改用通过 OrientationEventListener 自己控制横竖屏的切换,核心代码如下

private class IOrientationEventListener extends OrientationEventListener {

	public IOrientationEventListener(Context context) {
		super(context);
	}

	@Override
	public void onOrientationChanged(int orientation) {
		if (ORIENTATION_UNKNOWN == orientation) {
			return;
		}
		
		//关联系统自动旋转开关
		if (!PhoneUtils.getRotateSwitchState(mContext)) return;
		if (orientation > 350 || orientation < 10) {
			//90度竖屏
			mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
		} else if (orientation > 260 && orientation < 280) {
			//0度横屏
			mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
		}
	}
}
public static boolean getRotateSwitchState(Context context) {
    try {
        //1 开启 0 关闭
        return Settings.System.getInt(context.getContentResolver(), Settings.System.ACCELEROMETER_ROTATION) == 1;
    } catch (Settings.SettingNotFoundException e) {
        e.printStackTrace();
        return false;
    }
}

然后在合适的位置通过 enable() 和 disable() 控制 OrientationEventListener 的开启和关闭就可以了。

 

本以为到此完事大吉,但是测试同事反馈横竖屏切换的时候太灵敏了,快速晃动手机的时候就可能触发横竖屏的切换,要求能否控制一下灵敏度。

 

既然提出了问题,身为猿的我们总要尝试寻求解决优化的办法不是,于是查找API,发现 OrientationEventListener 有一个构造方法

public OrientationEventListener(Context context, int rate)

其中第二个参数就可以控制获取传感器数据的速度,不幸的是实际测试好像并不能解决我的问题~,于是转变思路能否自己计算角度变化的速度呢?改进代码如下

private class IOrientationEventListener extends OrientationEventListener {

	long time1, time2;

	public IOrientationEventListener(Context context) {
		super(context);
		time1 = System.currentTimeMillis();
		time2 = System.currentTimeMillis();
	}

	@Override
	public void onOrientationChanged(int orientation) {
		if (ORIENTATION_UNKNOWN == orientation) {
			return;
		}
		
		if (!PhoneUtils.getRotateSwitchState(mContext)) return;
		if (orientation > 350 || orientation < 10) {
			time1 = System.currentTimeMillis();
			if (getOrienSpeed(time1, time2) > 0) return;
			mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
		} else if (orientation > 260 && orientation < 280) {
			time2 = System.currentTimeMillis();
			if (getOrienSpeed(time1, time2) > 0) return;
			mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
		}
	}
}
private long getOrienSpeed(long time1, long time2) {
    long time = Math.abs(time1 - time2);
    return 270 / time;
}

测试发现满足需求,到此算是告一段落。

代码没什么难度,记录下来主要是为了理一下思路,也希望能帮到遇到同样问题的猿友们。如果大家有什么更好的解决办法或思路欢迎留言,不胜感激~

你可能感兴趣的:(Android)