Android:检测方向已更改

我需要检测应用程序中的方向更改,但我不希望我的布局从纵向更改为横向。 目前我正在使用OrientationEventListener但是检测方向角度是不够的。 我想检测用户是从纵向更改为横向还是横向,这不仅仅是检测方向角是90还是270。

我想做与Android相同的检测来改变活动的方向。 我尝试重写onConfigurationChanged并检查orientantion是否为横向/纵向,但是这仍然会将我的活动布局更改为横向。

有没有办法使用onConfigurationChanged但强制布局保持纵向?
是否有另一种方法可以在不使用OrientationEventListener情况下检测方向变化。 最终我可以实现我自己的方向改变算法,对此有何想法? 它必须比if(90-THRESHOLD <= orientation <= 90+THRESHOLD)更复杂if(90-THRESHOLD <= orientation <= 90+THRESHOLD) ,我想检测用户是否完成了纵向 – >横向或横向 – >纵向移动。

谢谢您的帮助,
菲利佩

好吧,在尝试使用Android API并且无法完成我需要的操作后,我实现了自己的算法,实际上并没有那么复杂:我使用了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); } 

嗨screamingnoises这是你要找的?

 // 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 } 

我创建了以下类来检测方向更改,保持我的活动原始方向:

 public class SensorOrientationChangeNotifier { public final String TAG = getClass().getSimpleName(); private ArrayList> mListeners = new ArrayList>(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(listener)); if (mListeners.size() == 1) { onResume(); // this is the first client } } public void remove(SensorOrientationChangeNotifier.Listener listener) { WeakReference listenerWR = get(listener); remove(listenerWR); } private void remove(WeakReference listenerWR) { if (listenerWR != null) mListeners.remove(listenerWR); if (mListeners.size() == 0) { onPause(); } } private WeakReference get(SensorOrientationChangeNotifier.Listener listener) { for (WeakReference existingListener : mListeners) if (existingListener.get() == listener) return existingListener; return null; } private void notifyListeners() { ArrayList> deadLiksArr = new ArrayList>(); for (WeakReference wr : mListeners) { if (wr.get() == null) deadLiksArr.add(wr); else wr.get().onOrientationChange(mOrientation); } // remove dead references for (WeakReference wr : deadLiksArr) { mListeners.remove(wr); } } public boolean isPortrait(){ return mOrientation == 0 || mOrientation == 180; } public boolean isLandscape(){ return !isPortrait(); } } 

使用方法如下:

在AndroidManifest.xml中 –

   

在您的活动中:

 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宽度>高度是“横向”还是相反的高度>宽度是“肖像” – 以下代码是测试和工作。

 @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"); } }