Android-加速传感器或者OrientationEventListener做横竖屏切换

2019-06-23 09:20:53

参考链接  Android-加速传感器或者OrientationEventListener做横竖屏切换

在播放视频的时候,可能要做横竖屏的切换,但是,用户可以设置自己的手机关掉屏幕旋转,这个时候就需要想其他的办法了,比如:加速传感器或者OrientationEventListener。


1、这是用加速传感器来实现:


public class ScreenSwitchUtils {

private static final String TAG = ScreenSwitchUtils.class.getSimpleName();

private volatile static ScreenSwitchUtils mInstance;

private Activity mActivity;

// 是否是竖屏

private boolean isPortrait = true;

private SensorManager sm;

private OrientationSensorListener listener;

private Sensor sensor;

 

private SensorManager sm1;

private Sensor sensor1;

private OrientationSensorListener1 listener1;

private Handler mHandler = new Handler() {

public void handleMessage(Message msg) {

switch (msg.what) {

case 888:

int orientation = msg.arg1;

if (orientation > 45 && orientation < 135) {

 

} else if (orientation > 135 && orientation < 225) {

 

} else if (orientation > 225 && orientation < 315) {

if (isPortrait) {

Log.e("test", "切换成横屏");

mActivity.setRequestedOrientation(0);

isPortrait = false;

}

} else if ((orientation > 315 && orientation < 360) || (orientation > 0 && orientation < 45)) {

if (!isPortrait) {

Log.e("test","切换成竖屏");

mActivity.setRequestedOrientation(1);

isPortrait = true;

}

}

break;

default:

break;

}

 

};

};

/** 返回ScreenSwitchUtils单例 **/

    public static ScreenSwitchUtils init(Context context) {

        if (mInstance == null) {

            synchronized (ScreenSwitchUtils.class) {

                if (mInstance == null) {

                    mInstance = new ScreenSwitchUtils(context);

                }

            }

        }

        return mInstance;

    }

 

    private ScreenSwitchUtils(Context context) {

        Log.d(TAG, "init orientation listener.");

        // 注册重力感应器,监听屏幕旋转

        sm = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);

        sensor = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

        listener = new OrientationSensorListener(mHandler);

 

        // 根据 旋转之后/点击全屏之后 两者方向一致,激活sm.

        sm1 = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);

        sensor1 = sm1.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

        listener1 = new OrientationSensorListener1();

    }

    

    /** 开始监听 */

    public void start(Activity activity) {

    Log.d(TAG, "start orientation listener.");

        mActivity = activity;

        sm.registerListener(listener, sensor, SensorManager.SENSOR_DELAY_UI);

    }

 

    /** 停止监听 */

    public void stop() {

    Log.d(TAG, "stop orientation listener.");

    sm.unregisterListener(listener);

sm1.unregisterListener(listener1);

    }

    

    /**

     * 手动横竖屏切换方向

     */

    public void toggleScreen() {

sm.unregisterListener(listener);

sm1.registerListener(listener1, sensor1,SensorManager.SENSOR_DELAY_UI);

if (isPortrait) {

isPortrait = false;

// 切换成横屏

mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

} else {

isPortrait = true;

// 切换成竖屏

mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

}

}

    

    public boolean isPortrait(){

    return this.isPortrait;

    }

    

    /**

* 重力感应监听者

*/

public class OrientationSensorListener implements SensorEventListener {

private static final int _DATA_X = 0;

private static final int _DATA_Y = 1;

private static final int _DATA_Z = 2;

 

public static final int ORIENTATION_UNKNOWN = -1;

 

private Handler rotateHandler;

 

public OrientationSensorListener(Handler handler) {

rotateHandler = handler;

}

 

public void onAccuracyChanged(Sensor arg0, int arg1) {

}

 

public void onSensorChanged(SensorEvent event) {

float[] values = event.values;

int orientation = ORIENTATION_UNKNOWN;

float X = -values[_DATA_X];

float Y = -values[_DATA_Y];

float Z = -values[_DATA_Z];

float magnitude = X * X + Y * Y;

// Don't trust the angle if the magnitude is small compared to the y

// value

if (magnitude * 4 >= Z * Z) {

// 屏幕旋转时

float OneEightyOverPi = 57.29577957855f;

float angle = (float) Math.atan2(-Y, X) * OneEightyOverPi;

orientation = 90 - (int) Math.round(angle);

// normalize to 0 - 359 range

while (orientation >= 360) {

orientation -= 360;

}

while (orientation < 0) {

orientation += 360;

}

}

if (rotateHandler != null) {

rotateHandler.obtainMessage(888, orientation, 0).sendToTarget();

}

}

}

 

public class OrientationSensorListener1 implements SensorEventListener {

private static final int _DATA_X = 0;

private static final int _DATA_Y = 1;

private static final int _DATA_Z = 2;

 

public static final int ORIENTATION_UNKNOWN = -1;

 

public OrientationSensorListener1() {

}

 

public void onAccuracyChanged(Sensor arg0, int arg1) {

}

 

public void onSensorChanged(SensorEvent event) {

float[] values = event.values;

int orientation = ORIENTATION_UNKNOWN;

float X = -values[_DATA_X];

float Y = -values[_DATA_Y];

float Z = -values[_DATA_Z];

float magnitude = X * X + Y * Y;

// Don't trust the angle if the magnitude is small compared to the y

// value

if (magnitude * 4 >= Z * Z) {

// 屏幕旋转时

float OneEightyOverPi = 57.29577957855f;

float angle = (float) Math.atan2(-Y, X) * OneEightyOverPi;

orientation = 90 - (int) Math.round(angle);

// normalize to 0 - 359 range

while (orientation >= 360) {

orientation -= 360;

}

while (orientation < 0) {

orientation += 360;

}

}

if (orientation > 225 && orientation < 315) {// 检测到当前实际是横屏

if (!isPortrait) {

sm.registerListener(listener, sensor,SensorManager.SENSOR_DELAY_UI);

sm1.unregisterListener(listener1);

}

} else if ((orientation > 315 && orientation < 360) || (orientation > 0 && orientation < 45)) {// 检测到当前实际是竖屏

if (isPortrait) {

sm.registerListener(listener, sensor,SensorManager.SENSOR_DELAY_UI);

sm1.unregisterListener(listener1);

}

}

}

}

}


转载请标明出处:http://blog.csdn.net/goldenfish1919/article/details/47423131


使用的时候:


public class MainActivity extends Activity implements OnClickListener {

 

private ScreenSwitchUtils instance;

 

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

instance = ScreenSwitchUtils.init(this.getApplicationContext());

}

 

@Override

protected void onStart() {

super.onStart();

instance.start(this);

}

 

@Override

protected void onStop() {

super.onStop();

instance.stop();

}

 

@SuppressLint("NewApi")

@Override

public void onConfigurationChanged(Configuration newConfig) {

super.onConfigurationChanged(newConfig);

Log.e("test", "onConfigurationChanged");

if (instance.isPortrait()) {

// 切换成竖屏

LayoutParams params1 = new RelativeLayout.LayoutParams(screenWidth, DensityUtil.dip2px(this, 160));

videoView.setLayoutParams(params1);

Toast.makeText(getApplicationContext(), "竖屏", 0).show();

Log.e("test", "竖屏");

} else {

// 切换成横屏

LayoutParams params1 = new RelativeLayout.LayoutParams(screenHeight, screenWidth);

videoView.setLayoutParams(params1);

Toast.makeText(getApplicationContext(), "横屏", 0).show();

Log.e("test", "横屏");

}

}

 

@Override

public void onClick(View arg0) {

switch (arg0.getId()) {

case R.id.iv_stretch:

instance.toggleScreen();

break;

}

}

}


调用了activity.setRequestedOrientation()以后,会触发activity.onConfigurationChanged();可以在这里面重新设置播放界面的大小。




参考:http://download.csdn.net/download/liubo080852/8446445




2.还有一种更简单的方式OrientationEventListener:


public class ScreenOrientationUtil {

private int mOrientation;

private OrientationEventListener mOrEventListener;

private int mOrientation1;

private OrientationEventListener mOrEventListener1;

private Activity mActivity;

private static ScreenOrientationUtil instance = new ScreenOrientationUtil();

public static ScreenOrientationUtil getInstance(){

return instance;

public void start(Activity activity){

this.mActivity = activity;

if(mOrEventListener == null){

initListener();

}

mOrEventListener.enable();

}

public void stop(){

if(mOrEventListener != null){

mOrEventListener.disable();

}

if(mOrEventListener1 != null){

mOrEventListener1.disable();

}

}

private void initListener(){

mOrEventListener = new OrientationEventListener(mActivity) {

        @Override

        public void onOrientationChanged(int rotation) {

        Log.e("test", ""+rotation);

            if (rotation == OrientationEventListener.ORIENTATION_UNKNOWN) {

                return;

            }

            int orientation = convert2Orientation(rotation);

            // 方向没有变化,跳过

            if (orientation == mOrientation) {

                return;

            }

            mOrientation = orientation;

            mActivity.setRequestedOrientation(mOrientation);

            

        }

    };

    

    mOrEventListener1 = new OrientationEventListener(mActivity) {

        @Override

        public void onOrientationChanged(int rotation) {

            if (rotation == OrientationEventListener.ORIENTATION_UNKNOWN) {

                return;

            }

            int orientation = convert2Orientation(rotation);

            // 方向没有变化,跳过

            if (orientation == mOrientation1) {

                return;

            }

            mOrientation1 = orientation;

            if(mOrientation1 == mOrientation){

            mOrEventListener1.disable();

            mOrEventListener.enable();

            }

        }

    };

}

public boolean isPortrait(){

if(mOrientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT || mOrientation == ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT){

return true;

}

return false;

}

public int getOrientation(){

return mOrientation;

}

public void toggleScreen(){

mOrEventListener.disable();

mOrEventListener1.enable();

int orientation = 0 ;

if(mOrientation ==  ActivityInfo.SCREEN_ORIENTATION_PORTRAIT){

orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;

}else if(mOrientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE){

orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;

}else if(mOrientation == ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE){

orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;

}else if(mOrientation == ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT){

orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;

}

mOrientation = orientation;

mActivity.setRequestedOrientation(mOrientation);

}

private int convert2Orientation(int rotation){

int orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;

        if (((rotation >= 0) && (rotation <= 45)) || (rotation > 315)) {

            orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;

        } else if ((rotation > 45) && (rotation <= 135)) {

            orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;

        } else if ((rotation > 135) && (rotation <= 225)) {

            orientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;

        } else if ((rotation > 225) && (rotation <= 315)) {

            orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;

        } else {

            orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;

        }

        return orientation;

}

}



  • 2019-01-29 14:33:07

    child_process中spawn和exec方法的使用

    child_process是nw.exe的一个内置模块,通过它可以实现创建多线程,并可实现主线程和子线程之间的通信。child_process模块中主要使用有两个方法spawn和exec,这两个方法都可以用来创建子线程。除了spawn和exec外,child_process模块还有execFile,fork,spawnSync,execFileSync,execSync,它们都是基于spawn的不同封装。 --------------------- 作者:黄泽平 来源:CSDN 原文:https://blog.csdn.net/zeping891103/article/details/52230175 版权声明:本文为博主原创文章,转载请附上博文链接!

  • 2019-01-29 14:50:51

    Node.js 编写跨平台 spawn 语句

    Node.js 是跨平台的,也就是说它能运行在 Windows、OSX 和 Linux 平台上。很多 Node.js 开发者都是在 OSX 上做开发的,然后再将代码部署到 Linux 服务器上。由于 OSX 和 Linux 都是基于 Unix 的,因此两者共性很多。Windows 也是 Node.js 官方支持的平台,只要你通过正确的方式写代码,就能在各个平台上毫无压力的跑起来。

  • 2019-01-30 17:53:21

    视图与临时表

    视图与表的不同之处:视图是一个虚表,即视图所对应的数据不进行实际存储,数据库只存储视图的定义,对视图的数据进行操作时,系统根据视图的定义去操作与视图相关联的基本表。

  • 2019-02-01 08:43:59

    JS 随机排序算法

    使用JS编写一个方法 让数组中的元素每次刷新随机排列

  • 2019-02-12 16:36:23

    图片工具GraphicsMagick的安装配置与基本使用

    GraphicsMagick是一个短小精悍的的图片处理工具和库集合。对于Java开发者来说,常用的图片处理工具有3个,JDK自带的图片处理库,ImageMagick,GraphicsMagick。JDK自带的图片处理库,虽稳定简单,性能却比较差;ImageMagick是目前最流行的图片处理工具,它的功能非常丰富;GraphicsMagick的功能略逊于ImageMagick,但是它的效率更强悍,但大多数情况下,GM的功能已经足够使用了。