Android监测屏幕旋转

文章介绍了三种在Android中检测屏幕旋转的方法:通过AndroidManifest配置screenOrientation,使用OrientationEventListener,以及SensorEventListener。每种方案的优缺点都进行了详细说明,包括系统自动处理、手动判断角度和设备方向等。方案二和三能提供更精确的旋转方向信息,但可能需要额外处理平放状态下的角度获取问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

监测屏幕旋转的方案,这里简要说一下screenOrientation,OrientationEventListener,SensorEventListener。

方案一

screenOrientation。

在AndroidManifest中,activity配置screenOrientation,比如值为sensor,系统可以自动改变activity的界面方向。在回调onConfigurationChanged()中可以判断当前方向。

       <activity android:name=".ui.sensor.ScreenOrientationActivity"
            android:configChanges="orientation|keyboardHidden"
            android:screenOrientation="sensor"/>

优点:简单,系统自动。

缺点:只能监听屏幕方向;系统自动设置方向,当有条件切换时,无法实现需求;无法知道旋转方向。

方案二

OrientationEventListener。

实现OrientationEventListener方法。在适当的位置调用enable()和disable()来开启和关闭监听。

public class OrientationEventActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sensor);

        initOrientationEvent();
    }


    OrientationEventListener mOrientationEventListener;
    public void initOrientationEvent(){
        mOrientationEventListener = new OrientationEventListener(this,
                SensorManager.SENSOR_DELAY_NORMAL) {
            @Override
            public void onOrientationChanged(int orientation) {
                if (orientation == OrientationEventListener.ORIENTATION_UNKNOWN) {
                    return;  //手机平放时,检测不到有效的角度
                }
                //只检测是否有四个角度的改变
                if (orientation > 350 || orientation < 10) { //0度
                    orientation = 0;
                } else if (orientation > 80 && orientation < 100) { //90度
                    orientation = 90;

                } else if (orientation > 170 && orientation < 190) { //180度
                    orientation = 180;
                } else if (orientation > 260 && orientation < 280) { //270度
                    orientation = 270;
                } else {
                    return;
                }
            }
        };

        if (mOrientationEventListener.canDetectOrientation()) {
            mOrientationEventListener.enable();
        } else {
            mOrientationEventListener.disable();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(mOrientationEventListener !=null){
            mOrientationEventListener.disable();
        }
    }
}

优点:可以判断角度,解决按需设置方向。也能通过判断知道旋转方向。但平放时,无法得到有效的角度。可以通过反射,解决平放时,无法获取角度问题。

    public  class ScreenOrientationListener extends OrientationEventListener {

        private int mOrientation;
        private OnOrientationChangedListener mOnOrientationChangedListener;
        private Context mContext;
        private Field mFieldRotation;
        private Object mOLegacy;

        public ScreenOrientationListener(Context context) {
            super(context);
            mContext = context;
        }

        public void setOnOrientationChangedListener(OnOrientationChangedListener listener) {
            this.mOnOrientationChangedListener = listener;
        }

        public int getOrientation() {
            int rotation = -1;
            try {
                if (null == mFieldRotation) {
                    SensorManager sensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
                    Class clazzLegacy = Class.forName("android.hardware.LegacySensorManager");
                    Constructor constructor = clazzLegacy.getConstructor(SensorManager.class);
                    constructor.setAccessible(true);
                    mOLegacy = constructor.newInstance(sensorManager);
                    mFieldRotation = clazzLegacy.getDeclaredField("sRotation");
                    mFieldRotation.setAccessible(true);
                }
                rotation = mFieldRotation.getInt(mOLegacy);
            } catch (Exception e) {
                LogUtil.e( "getRotation e=" + e.getMessage());
                e.printStackTrace();
            }
//        Log.d(TAG, "getRotation rotation=" + rotation);

            int orientation = -1;
            switch (rotation) {
                case Surface.ROTATION_0:
                    orientation = 0;
                    break;
                case Surface.ROTATION_90:
                    orientation = 90;
                    break;
                case Surface.ROTATION_180:
                    orientation = 180;
                    break;
                case Surface.ROTATION_270:
                    orientation = 270;
                    break;
                default:
                    break;
            }
//        Log.d(TAG, "getRotation orientation=" + orientation);
            return orientation;
        }

        @Override
        public void onOrientationChanged(int orientation) {
            if (orientation == OrientationEventListener.ORIENTATION_UNKNOWN) {
                return; // 手机平放时,检测不到有效的角度
            }
            orientation = getOrientation();
            if (mOrientation != orientation) {
                mOrientation = orientation;
                if (null != mOnOrientationChangedListener) {
                    mOnOrientationChangedListener.onOrientationChanged(mOrientation);
                    LogUtil.d("ScreenOrientationListener onOrientationChanged orientation=" + mOrientation);
                }
            }
        }

        public interface OnOrientationChangedListener {
            void onOrientationChanged(int orientation);
        }
    }

方案三

SensorEventListener

package com.ader.demo_unit.ui.sensor;

import android.annotation.TargetApi;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Build;
import android.os.Bundle;
import android.view.OrientationEventListener;
import android.view.Surface;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import com.ader.baseapp.base.ui.BaseActivity;
import com.ader.baseapp.base.utils.LogUtil;
import com.ader.demo_unit.R;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;

/**
 * Create by Wang Xiaowu on 2023-02-06
 * Describe:
 */
public class SensorActivity extends AppCompatActivity {

    SensorManager sm;

    SensorEventListener mSensorEventListener = new SensorEventListener() {
        @Override
        public void onSensorChanged(SensorEvent event) {
//            float[] values=event.values;
//            String sb="x方向加速度:"+
//                    values[0]+
//                    "\nY轴方向加速度:"+
//                    values[1]+
//                    "\nZ轴方向加速度:"+
//                    values[2];
//            LogUtil.e(String.format("%s accuracy:%d sensor:%s",sb,event.accuracy,event.sensor.toString()));
//
//            /* 判断Sensor的种类 */
            if (event.sensor.getType() == Sensor.TYPE_ORIENTATION) {
                /* 取得X值资料 */
                float x_data = event.values[SensorManager.DATA_X];
                if ((x_data > 0 && x_data <= 22.5) || x_data > 337.5) {
                    LogUtil.e("北方" + String.valueOf(x_data));
                } else if (x_data > 22.5 && x_data <= 67.5) {
                    LogUtil.e("东北方" + String.valueOf(x_data));
                } else if (x_data > 67.5 && x_data <= 112.5) {
                    LogUtil.e("东方" + String.valueOf(x_data));
                } else if (x_data > 112.5 && x_data <= 157.5) {
                    LogUtil.e("东南方" + String.valueOf(x_data));
                } else if (x_data > 157.5 && x_data <= 202.5) {
                    LogUtil.e("南方" + String.valueOf(x_data));
                } else if (x_data > 202.5 && x_data <= 247.5) {
                    LogUtil.e("西南方" + String.valueOf(x_data));
                } else if (x_data > 247.5 && x_data <= 292.5) {
                    LogUtil.e("西方" + String.valueOf(x_data));
                } else if (x_data > 292.5 && x_data <= 337.5) {
                    LogUtil.e("西北方" + String.valueOf(x_data));
                }
            }





        }

        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {
            LogUtil.e(String.format("onAccuracyChanged accuracy:%d sensor:%s",accuracy,sensor.toString()));

        }
    };
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sensor);

        //1.获取系统的传感器管理服务
        sm =  (SensorManager)getSystemService(SENSOR_SERVICE);
    }




    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    @Override
    protected void onResume() {
        super.onResume();
        //2.
        // 为系统的加速度传感器注册监听事件
//        sm.registerListener(mSensorEventListener,
//                sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
//                SensorManager.SENSOR_DELAY_GAME);
//        //方向传感器
        sm.registerListener(mSensorEventListener,
                sm.getDefaultSensor(Sensor.TYPE_ORIENTATION),
                SensorManager.SENSOR_DELAY_FASTEST);
        //* Sensor.TYPE_ORIENTATION:方向传感器。
        //
        //* Sensor.TYPE_GYROSCOPE:陀螺仪传感器。
        //
        //* Sensor.TYPE_MAGNETIC_FIELD:磁场传感器。
        //
        //* Sensor.TYPE_GRAVITY:重力传感器。
        //
        //* Sensor.TYPE_LINEAR_ACCELERATION:线性加速度传感器。
        //
        //* Sensor.TYPE_AMBIENT_TEMPERATURE:温度传感器。
        //
        //* Sensor.TYPE_LIGHT:光传感器。
        //
        //* Sensor.TYPE_PRESSURE:压力传感器。

    }

    @Override
    protected void onPause() {
        super.onPause();
        //取消注册
        sm.unregisterListener(mSensorEventListener);
    }



}

可以获取位置方向,但获取屏幕方向有点困难。已经被废弃。官方推荐使用 SensorManager.getOrientation() 替代。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值