Android-用重力传感器做横竖屏切换

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

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

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-28 06:12:09

Android-用重力传感器做横竖屏切换的相关文章

重力感应 视频横竖屏切换

public class ScreenSwitchUtils { private static final String TAG = ScreenSwitchUtils.class.getSimpleName(); private volatile static ScreenSwitchUtils mInstance; private Activity mActivity; // 是否是竖屏 private boolean isPortrait = true; private SensorMan

android activity生命周期以及横竖屏切换问题

自己重写activity的几个生命周期的方法,运行下就知道是怎么回事,实在懒得人可以看下:点击打开链接. onCreate   :创建activity时执行,只执行一次. onStart      :界面可见的时候执行. onResume:界面获得焦点,按钮可点击时执行. onPause   :界面失去焦点,按钮不可点击时执行. onStop      :界面不可见时执行. onDestroy :销毁,只执行一次. onRestart  :界面之前出现过,未销毁,从不可见状态回到可见状态时,执行

Android横竖屏切换总结

Android横竖屏切换总结(Android资料) Android横竖屏要解决的问题应该就两个: 一.布局问题 二.重新载入问题 1.布局问题:如果不想让软件在横竖屏之间切换,最简单的办法就是在项目的AndroidManifest.xml中找到你所指定的activity中加上android:screenOrientation属性,他有以下几个参数: "unspecified":默认值 由系统来判断显示方向.判定的策略是和设备相关的,所以不同的设备会有不同的显示方向. "lan

Android横竖屏切换及其对应布局加载问题

第一,横竖屏切换连带横竖屏布局问题: 如果要让软件在横竖屏之间切换,由于横竖屏的高宽会发生转换,有可能会要求不同的布局. 可以通过以下两种方法来切换布局: 1)在res目录下建立layout-land和layout-port目录,相应的layout文件名不变,比如:layout-land是横屏的layout,layout-port是竖屏的layout,其他的不用管,横竖屏切换时程序调用Activity的onCreate方法中的setOnContent(xxx),并自动加载相应的布局. 2)假如布

Android Configuration横竖屏切换时Activity生命周期调用

问题:横竖屏切换时Activity的生命周期? 测试环境:华为mate7 package com.virglass.beyond.activity; import android.app.Activity; import android.content.res.Configuration; import android.os.Bundle; import com.virglass.beyond.utils.LogUtil; /** * 系统设置更改 * @author Administrator

横竖屏切换时,禁止activity重新创建,android:configChanges=&quot;keyboardHidden|orientation&quot; 不起作用

这个网上搜索,很多结果都是: AndroidManifest.xml android:configChanges="keyboardHidden|orientation" 但是,实际上很多手机上,这个根本不起作用.这是为什么呢? 因为,但多数人陈陈相因,文章直接转,都没有结果自己实践. 在低版本上,这个是可以起作用.在android 4.0 以上实际上这个是不起作用的. 必须要加上screenSize. android:configChanges="keyboardHidde

iOS开发之判断横竖屏切换

/** *  当屏幕即将旋转的时候调用 * *  @param toInterfaceOrientation 旋转完毕后的最终方向 *  @param duration  旋转动画所花费的时间 */ - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { if (UIInterfaceOrientation

Android横竖屏切换重载问题与小结

(转自:http://www.cnblogs.com/franksunny/p/3714442.html) (老样子,图片啥的详细文档,可以下载后观看 http://files.cnblogs.com/franksunny/635350788930000000.pdf) Android手机或平板都会存在横竖屏切换的功能,通常是由物理重力感应触发的,但是有时候也不尽然,通常在设置里面我们可以对手机的横竖屏切换进行关闭,操作界面如下 只需要点击下“屏幕旋转”按钮就可以关闭横竖屏切换了. 一.禁止AP

Android 横竖屏切换小结

转自:http://www.cnblogs.com/franksunny/p/3714442.html (老样子,图片啥的详细文档,可以下载后观看 http://files.cnblogs.com/franksunny/635350788930000000.pdf) Android手机或平板都会存在横竖屏切换的功能,通常是由物理重力感应触发的,但是有时候也不尽然,通常在设置里面我们可以对手机的横竖屏切换进行关闭,操作界面如下 只需要点击下“屏幕旋转”按钮就可以关闭横竖屏切换了. 一.禁止APP内