Android:检测方向已更改

我需要检测我的应用程序中的方向更改,但是我不希望将我的布局从纵向更改为横向。 目前我正在使用OrientationEventListener但是检测方向angular度是不够的。 我想检测用户是否从纵向变为横向,反之亦然,这不仅仅是检测方位angular是90°还是270°。

我想要做和Android一样的检测来改变活动的方向。 我试着覆盖onConfigurationChanged并检查orientantion是风景/人像,但是这仍然改变我的活动布局到风景。

有没有办法使用onConfigurationChanged,但强制布局保持肖像?
有没有使用OrientationEventListener检测方向更改的另一种方法。 最终我可以实现我自己的方向改变algorithm,对此有什么想法? 它必须比if(90-THRESHOLD <= orientation <= 90+THRESHOLD)更复杂的东西,我想检测用户是否完成了移动肖像 – >风景或风景 – >肖像。

谢谢您的帮助,
菲利佩

Solutions Collecting From Web of "Android:检测方向已更改"

好吧,在尝试使用Android API并且无法完成我所需要的操作之后,我实现了自己的algorithm,实际上并没有那么复杂:我使用了OrientationEventListener,并计算方向是否在4个方向点(在我的代码中,我只检测LANDSCAPE_RIGHTPORTRAIT_UP

 orientationListener = new OrientationEventListener(context, SensorManager.SENSOR_DELAY_UI) { public void onOrientationChanged(int orientation) { if(canShow(orientation)){ show(); } else if(canDismiss(orientation)){ dismiss(); } } }; @Override public void onResume(){ super.onResume(); orientationListener.enable(); } @Override public void onPause(){ super.onPause(); orientationListener.disable(); } private boolean isLandscape(int orientation){ return orientation >= (90 - THRESHOLD) && orientation <= (90 + THRESHOLD); } private boolean isPortrait(int orientation){ return (orientation >= (360 - THRESHOLD) && orientation <= 360) || (orientation >= 0 && orientation <= THRESHOLD); } public boolean canShow(int orientation){ return !visible && isLandscape(orientation); } public boolean canDismiss(int orientation){ return visible && !dismissing && isPortrait(orientation); } 

你好,尖叫声这是你在找什么?

 // Set background image, rotatable View view = getWindow().getDecorView(); int orientation = getResources().getConfiguration().orientation; if (Configuration.ORIENTATION_LANDSCAPE == orientation) { //Do SomeThing; // Landscape } else { //Do SomeThing; // Portrait } 

我创build了以下类来检测方向变化,保持我的活动原始方向:

 public class SensorOrientationChangeNotifier { public final String TAG = getClass().getSimpleName(); private ArrayList<WeakReference<SensorOrientationChangeNotifier.Listener>> mListeners = new ArrayList<WeakReference<SensorOrientationChangeNotifier.Listener>>(3); private int mOrientation = 0; private SensorEventListener mSensorEventListener; private SensorManager mSensorManager; private static SensorOrientationChangeNotifier mInstance; public static SensorOrientationChangeNotifier getInstance() { if (mInstance == null) mInstance = new SensorOrientationChangeNotifier(); return mInstance; } private SensorOrientationChangeNotifier() { mSensorEventListener = new NotifierSensorEventListener(); Context applicationContext = GlobalData.getInstance().getContext(); mSensorManager = (SensorManager) applicationContext.getSystemService(Context.SENSOR_SERVICE); } /** * Call on activity reset() */ private void onResume() { mSensorManager.registerListener(mSensorEventListener, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL); } /** * Call on activity onPause() */ private void onPause() { mSensorManager.unregisterListener(mSensorEventListener); } private class NotifierSensorEventListener implements SensorEventListener { @Override public void onSensorChanged(SensorEvent event) { float x = event.values[0]; float y = event.values[1]; int newOrientation = mOrientation; if (x < 5 && x > -5 && y > 5) newOrientation = 0; else if (x < -5 && y < 5 && y > -5) newOrientation = 90; else if (x < 5 && x > -5 && y < -5) newOrientation = 180; else if (x > 5 && y < 5 && y > -5) newOrientation = 270; //Log.e(TAG,"mOrientation="+mOrientation+" ["+event.values[0]+","+event.values[1]+","+event.values[2]+"]"); if (mOrientation != newOrientation){ mOrientation = newOrientation; notifyListeners(); } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } } public int getOrientation() { return mOrientation; } public interface Listener { void onOrientationChange(int orientation); } public void addListener(SensorOrientationChangeNotifier.Listener listener) { if (get(listener) == null) // prevent duplications mListeners.add(new WeakReference<SensorOrientationChangeNotifier.Listener>(listener)); if (mListeners.size() == 1) { onResume(); // this is the first client } } public void remove(SensorOrientationChangeNotifier.Listener listener) { WeakReference<SensorOrientationChangeNotifier.Listener> listenerWR = get(listener); remove(listenerWR); } private void remove(WeakReference<SensorOrientationChangeNotifier.Listener> listenerWR) { if (listenerWR != null) mListeners.remove(listenerWR); if (mListeners.size() == 0) { onPause(); } } private WeakReference<SensorOrientationChangeNotifier.Listener> get(SensorOrientationChangeNotifier.Listener listener) { for (WeakReference<SensorOrientationChangeNotifier.Listener> existingListener : mListeners) if (existingListener.get() == listener) return existingListener; return null; } private void notifyListeners() { ArrayList<WeakReference<SensorOrientationChangeNotifier.Listener>> deadLiksArr = new ArrayList<WeakReference<SensorOrientationChangeNotifier.Listener>>(); for (WeakReference<SensorOrientationChangeNotifier.Listener> wr : mListeners) { if (wr.get() == null) deadLiksArr.add(wr); else wr.get().onOrientationChange(mOrientation); } // remove dead references for (WeakReference<SensorOrientationChangeNotifier.Listener> wr : deadLiksArr) { mListeners.remove(wr); } } public boolean isPortrait(){ return mOrientation == 0 || mOrientation == 180; } public boolean isLandscape(){ return !isPortrait(); } } 

使用它如下:

在AndroidManifest.xml中 –

  <activity ... android:screenOrientation="portrait" > 

在你的活动中:

 public class MainActivity extends Activity implements SensorOrientationChangeNotifier.Listener { @Override protected void onResume() { super.onResume(); SensorOrientationChangeNotifier.getInstance().addListener(this); } @Override protected void onPause() { super.onPause(); SensorOrientationChangeNotifier.getInstance().remove(this); } @Override public void onOrientationChange(int orientation) { if (orientation == 90 || orientation == 270){ // Do some landscape stuff } else { // Do some portrait stuff } } } } 

为了检测方向,我们会要求活动给我们提供活动的宽度和高度,所以我们可以find宽度>高度将是“风景”或相反的高度>宽度是“肖像” – 以下代码是testing和工作。

 @SuppressWarnings("deprecation") public void detectScreenOrientation(){ WindowManager wm = getWindowManager(); Display d = wm.getDefaultDisplay(); if (d.getWidth() > d.getHeight()){ Log.d("Orientation","Landscape mode"); } else { Log.d("Orientation", "Portrait mode"); } }