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-02-24 18:43:54

    百度地图JS关于规划路线偏离预警的解决方式

    说实在的这个解决方案有点low,我并不会很赞成,效率有点低。如果多的话,很是耗费资源。 我推荐使用矩形来解决这个问题,而不是圆形。 当日用矩形的话,就要确保轨迹是折线的,而不是弧线等。

  • 2020-02-24 18:45:33

    巧妙解决百度地图加偏纠偏问题

    所谓的加偏,就是将真实坐标加上一定的偏移量,而这个偏移量又不是线性的,不同地区偏移不一样,但同一地区偏移量却差不多,因此,有人就使用了个暴力破解的方法,

  • 2020-02-24 18:48:34

    规划驾车路线和途径点及判断车辆路线偏移

    项目需求需要利用百度地图构建路线并支持设置途径点,以及可以实时监控车辆是否偏移路线;两种方案。 写了比较完整的注释了,替换ak可直接看效果,规划驾车路线和途径点及判断车辆路线偏移

  • 2020-02-25 15:15:56

    nuxtjs全栈

    Nuxt.js 依据 pages 目录结构自动生成 vue-router 模块的路由配置。 要在页面之间使用路由,我们建议使用<nuxt-link> 标签。

  • 2020-02-25 19:24:08

    IDEA 简单的正则匹配

    IDEA在进行查看或替换的时候,勾选Regex 选项就可以进行正则匹配查找了 几个简单实用的正则:

  • 2020-02-26 20:16:49

    一条简单的命令就可以将 stylus 语法转换为 scss 语法

    因为早期有个项目用到了 stylus,stylus 开发起来很爽,但 stylus 基于缩进的代码在修改的时候不是很方便,加上所在团队开发使用的都是 SCSS ,为了便于维护和统一,准备将项目中的 stylus 替换成 SCSS。手动转换 stylus 浪费时间,且出错率大,当时在想也许别人也有这样的需求呢,所以就做了这样一个项目。请各位大佬动动你们发财的小手,给我点个 star,不胜感激。^_^