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;

}

}



  • 2020-05-20 22:29:05

    javascript中为何在匿名function函数后面还外加

    它可以解释成为“匿名函数自调用”,也就是说,定义一个匿名函数,然后马上调用它(因为它是匿名的,如果不立即调用就获取不到该函数的引用了)。通常它被应用在一些大型的JS框架中(如上面所说的),因为这个匿名函数的函数体相当于提供一个匿名的名字空间,这样就不会再与用户自定义的JS函数、变量、对象发生冲突了。尽管JS没有显示地提供命名空间的定义和使用机制,但这种匿名方式却不失为是一种很好的解决命名空间问题的方法。

  • 2020-05-20 22:30:14

    js中利用prototype给类添加方法

    你可能会想,这不就是个简单的函数声明?没错,这个函数就是一个类的定义的实现。如何使用这个类呢?看下面的代码:var cls1 = new MyClass(); 这样,利用new就可以生成MyClass的一个实例了。所以在js中可以说函数就是类,类就是函数。

  • 2020-05-21 10:56:53

    fixed z-index失效

    作为一个假的前端,在调试一个页面时出现了如下bug。 左侧的菜单固定为fixed时,二级菜单无法设置有效的z-index,导致菜单隐藏在页面元素之下,明明页面元素的z-index是1,但是无论把菜单的z-index设置为多大,都不管用。