项目中视频的播放之前的设计一直是根据视频的宽高进行判断,以最大程度显示界面的方式来播放视频。目前打算适配横竖屏的切换,现在的设计是:若屏幕为竖屏锁定,播放视频就竖屏锁定;若屏幕为横屏锁定, 播放视频就横屏锁定。若屏幕自动旋转按钮打开,则横屏状态下就横屏播放,竖屏状态下就竖屏播放。下面讲解该功能的实现步骤:
一、获取屏幕锁的状态:
判断是否开启了重力感应:
public boolean screenIsOpenRotate(Context context) {
int gravity = 0;
try {
gravity = Settings.System.getInt(context.getContentResolver(),
Settings.System.ACCELEROMETER_ROTATION);
} catch (SettingNotFoundException e) {
e.printStackTrace();
}
if (gravity == 1) {
return true;
}
return false;
}
Settings.System.ACCELEROMETER_ROTATION):表示设置重力感应开关
若gravity的值为1,表示开启了重力感应,返回true。即屏幕自动旋转按钮为打开状态。反之为关闭状态。
二、监听Settings 下面的屏幕锁的值的变化
在开发Android应用的时候有时需要监听Settings下面的值(如蓝牙、飞行模式、屏幕锁 ...),这个时候可以通过ContentObserver 来监听值的变化。
1.首先自定义一个类继承ContentObserver , 在onChange()方法里面再次去获取Settings的值。
private class SettingsValueChangeContentObserver extends ContentObserver {
public SettingsValueChangeContentObserver() {
super(new Handler());
}
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
//调用一中的方法获取屏幕锁的状态
screenIsOpenRotate = screenIsOpenRotate(MovieActivity.this);
//若现在为屏幕锁定,根据屏幕的方向设置activity的方向。
if (!screenIsOpenRotate) {
if (MovieActivity.this.getResources().getConfiguration().orientation== Configuration.ORIENTATION_LANDSCAPE) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
} else if (MovieActivity.this.getResources().getConfiguration().orientation== Configuration.ORIENTATION_PORTRAIT) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
}
}
}
}
2.注册监听
mContentOb = new SettingsValueChangeContentObserver();
getContentResolver().registerContentObserver(Settings.System.getUriFor(
Settings.System.ACCELEROMETER_ROTATION),true, mContentOb);
3.当应用退出的时候取消监听
@Override
protected void onStop() {
super.onStop();
getContentResolver().unregisterContentObserver(mContentOb);
}
这时当用户在操作屏幕锁的时候就会回调 public void onChange(boolean selfChange) 方法,从而知道当前屏幕锁的状态。
PS: 大家可以去SDK中查看该类:android.provider.Settings.System。该类封装了对设置模块下所有值的存取,
比如:飞行模式状态、蓝牙状态、屏幕亮度值等,并且提供了相应的Uri。
三、处理横竖屏切换的屏幕适配
1、若当前屏幕锁未开启,即为自动旋转的状态,则使用OrientationEventListener处理自动旋转的屏幕适配。
mOrientationListener = new OrientationEventListener(this) {
@Override
public void onOrientationChanged(int rotation) {
//自动旋转按钮打开,Activity的方向由物理方向传感器来决定,按照用户旋转设备的方向来显示。
if (screenIsOpenRotate) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
}
}
};
mOrientationListener.enable();
当不需要监听了使用mOrientationListener.disable()取消监听。
附: 设定Activity主窗口的方向,数组中的方向会设定给R.attr类中的screenOrientation属性, screenOrientation的
属性值必须是以下常量值:
ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED:
不指定方向,让系统决定Activity的最佳方向。
ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
希望Activity在横向屏上显示,也就是说横向的宽度要大于纵向的高度,并且忽略方向传感器的影响。
ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
希望Activity在纵向屏上显示,也就是说纵向的高度要大于横向的宽度,并且忽略方向传感器的影响。
ActivityInfo.SCREEN_ORIENTATION_USER:
使用用户设备的当前首选方向。
ActivityInfo.SCREEN_ORIENTATION_BEHIND:
始终保持与屏幕一致的方向,不管这个Activity在前台还是后台。
ActivityInfo.SCREEN_ORIENTATION_SENSOR:
Activity的方向由物理方向传感器来决定,按照用户旋转设备的方向来显示。
ActivityInfo.SCREEN_ORIENTATION_NOSENSOR:
始终忽略方向传感器的判断,当用户旋转设备时,显示不跟着旋转。
ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE:
希望Activity在横向屏幕上显示,但是可以根据方向传感器指示的方向来进行改变。
ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT:
希望Activity在纵向屏幕上显示,但是可以根据方向传感器指示的方向来进行改变。
ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
希望Activity在横向屏幕上显示,但与正常的横向屏幕方向相反。
ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
希望Activity在纵向屏幕上显示,但与正常的纵向屏幕方向相反
ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR:
Activity的方向由方向传感器来决定,显示会根据用户设备的移动情况来旋转。
2、若当前屏幕锁开启,则根据屏幕的方向来锁定屏幕
(1) 在ContentObserver中的处理:
public void onChange(boolean selfChange) {
super.onChange(selfChange);
screenIsOpenRotate = screenIsOpenRotate(MovieActivity.this);
if (!screenIsOpenRotate) {
if (MovieActivity.this.getResources().getConfiguration().orientation== Configuration.ORIENTATION_LANDSCAPE) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
} else if (MovieActivity.this.getResources().getConfiguration().orientation== Configuration.ORIENTATION_PORTRAIT) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
}
}
}
(2)在MediaPlayer.OnVideoSizeChangedListener中的onVideoSizeChanged方法中的处理:
public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
super.onVideoSizeChanged(mp, width, height);
if (MovieActivity.this.getResources().getConfiguration().orientation ==Configuration.ORIENTATION_LANDSCAPE) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
} else if (MovieActivity.this.getResources().getConfiguration().orientation ==Configuration.ORIENTATION_PORTRAIT) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
}
}
四、注意事项:
(1)这里不能使用 public void onConfigurationChanged(Configuration newConfig) 方法来处理屏幕的适配,因为在setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);方法执行之后,onConfigurationChanged方法将不再被调用。
(2)若player所在的activity实现了SensorEventListener接口,记得注释掉,防止两个Listener之间的干扰。