Android: Detect Orientation Changed
Solution 1:
Ok, after trying to use the Android API and not being able to do what I need, I implemented my own algorithm and actually it wasn't that complicated:
I used a OrientationEventListener, and calculated if the orientation is in the 4 orientation points (in my code I only detect LANDSCAPE_RIGHT
and PORTRAIT_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);
}
Solution 2:
Hi screamingnoises is this what you`re looking for?
// 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
}
Solution 3:
I created the following class to detect orientation changes, keeping my activity original orientation:
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();
}
}
Use it as follows:
In AndroidManifest.xml -
<activity
...
android:screenOrientation="portrait"
>
In your activity:
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
}
}
}
}
Solution 4:
A kotlin version of the Asaf Pinhassi answer.
import android.content.Context
import android.hardware.Sensor
import android.hardware.SensorEvent
import android.hardware.SensorEventListener
import android.hardware.SensorManager
import java.lang.ref.WeakReference
import java.util.*
class SensorOrientationChangeNotifier private constructor(context: Context) {
val TAG = javaClass.simpleName
private val mListeners = ArrayList<WeakReference<Listener?>>(3)
var orientation = 0
private set
private val mSensorEventListener: SensorEventListener
private val mSensorManager: SensorManager
/**
* Call on activity reset()
*/
private fun onResume() {
mSensorManager.registerListener(mSensorEventListener, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL)
}
/**
* Call on activity onPause()
*/
private fun onPause() {
mSensorManager.unregisterListener(mSensorEventListener)
}
private inner class NotifierSensorEventListener : SensorEventListener {
override fun onSensorChanged(event: SensorEvent) {
val x = event.values[0]
val y = event.values[1]
var newOrientation: Int = orientation
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 (orientation != newOrientation) {
orientation = newOrientation
notifyListeners()
}
}
override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {}
}
interface Listener {
fun onOrientationChange(orientation: Int)
}
fun addListener(listener: Listener) {
if (get(listener) == null) // prevent duplications
mListeners.add(WeakReference(listener))
if (mListeners.size == 1) {
onResume() // this is the first client
}
}
fun remove(listener: Listener) {
val listenerWR = get(listener)
remove(listenerWR)
}
private fun remove(listenerWR: WeakReference<Listener?>?) {
if (listenerWR != null) mListeners.remove(listenerWR)
if (mListeners.size == 0) {
onPause()
}
}
private operator fun get(listener: Listener): WeakReference<Listener?>? {
for (existingListener in mListeners) if (existingListener.get() === listener) return existingListener
return null
}
private fun notifyListeners() {
val deadLiksArr = ArrayList<WeakReference<Listener?>>()
for (wr in mListeners) {
if (wr.get() == null) deadLiksArr.add(wr) else wr.get()!!.onOrientationChange(orientation)
}
// remove dead references
for (wr in deadLiksArr) {
mListeners.remove(wr)
}
}
val isPortrait: Boolean
get() = orientation == 0 || orientation == 180
val isLandscape: Boolean
get() = !isPortrait
companion object {
private var mInstance: SensorOrientationChangeNotifier? = null
fun getInstance(context: Context): SensorOrientationChangeNotifier? {
if (mInstance == null) mInstance = SensorOrientationChangeNotifier(context)
return mInstance
}
}
init {
mSensorEventListener = NotifierSensorEventListener()
mSensorManager = context.getSystemService(Context.SENSOR_SERVICE) as SensorManager
}
}