Android 视频播放适配横竖屏切换功能的实现

来源:互联网 发布:志强软件 编辑:程序博客网 时间:2024/04/28 13:20

项目中视频的播放之前的设计一直是根据视频的宽高进行判断,以最大程度显示界面的方式来播放视频。目前打算适配横竖屏的切换,现在的设计是:若屏幕为竖屏锁定,播放视频就竖屏锁定;若屏幕为横屏锁定, 播放视频就横屏锁定。若屏幕自动旋转按钮打开,则横屏状态下就横屏播放,竖屏状态下就竖屏播放。下面讲解该功能的实现步骤:

一、获取屏幕锁的状态:

判断是否开启了重力感应:

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.当应用退出的时候取消监听

@Overrideprotected 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之间的干扰。

0 0
原创粉丝点击