How can I detect screen rotation?
Manifest:
<activity android:name=".MyActivity" android:configChanges="screenSize|orientation|screenLayout|navigation"/>
Activity:
@Override
public void onConfigurationChanged(Configuration newConfig)
{
Log.d("tag", "config changed");
super.onConfigurationChanged(newConfig);
int orientation = newConfig.orientation;
if (orientation == Configuration.ORIENTATION_PORTRAIT)
Log.d("tag", "Portrait");
else if (orientation == Configuration.ORIENTATION_LANDSCAPE)
Log.d("tag", "Landscape");
else
Log.w("tag", "other: " + orientation);
....
}
try this link also
How do I detect screen rotation
How can I globally detect when the screen rotation changes?
Use the hidden API
You can do this using a hidden API called IWindowManager.watchRotation(IRotationWatcher)
. From my testing, it seems to take a callback that is called every time the screen rotation changes. The callback also seems to be given the current screen rotation.
Being a hidden API, you can't just call it directly. How to use hidden APIs is a topic of its own. And, of course, this might not be as reliable from a maintainability perspective as normal APIs.
Also, onRotationChanged
isn't called in the same thread you used to call watchRotation
. You'll probably want to delegate some work to a different thread such as the UI thread once you're in onRotationChanged
.
Compatibility
Tested and working in API 14 - 28.
Example
Here's one way to get it to work:
- Copy
android.view.IRotationWatcher
into your app. Make sure to keep it in its original package. This seems to cause the development tools to think your code has access to it while also causing the operating system to still use the real one rather than your own copy. Use reflection to call
watchRotation
:try {
Class<?> serviceManager = Class.forName("android.os.ServiceManager");
IBinder serviceBinder = (IBinder)serviceManager.getMethod("getService", String.class).invoke(serviceManager, "window");
Class<?> stub = Class.forName("android.view.IWindowManager$Stub");
Object windowManagerService = stub.getMethod("asInterface", IBinder.class).invoke(stub, serviceBinder);
Method watchRotation;
if (Build.VERSION.SDK_INT >= 26)
watchRotation = windowManagerService.getClass().getMethod("watchRotation", IRotationWatcher.class, int.class);
else
watchRotation = windowManagerService.getClass().getMethod("watchRotation", IRotationWatcher.class);
//This method seems to have been introduced in Android 4.3, so don't expect to always find it
Method removeRotationWatcher = null;
try {
removeRotationWatcher = windowManagerService.getClass().getMethod("removeRotationWatcher", IRotationWatcher.class);
}
catch (NoSuchMethodException ignored) {}
IRotationWatcher.Stub screenRotationChanged = new IRotationWatcher.Stub() {
@Override
public void onRotationChanged(int rotation) throws RemoteException {
//Do what you want here
//WARNING: This isn't called in the same thread you were in when you called watchRotation
}
};
//Start monitoring for changes
if (Build.VERSION.SDK_INT >= 26)
watchRotation.invoke(windowManagerService, screenRotationChanged, Display.DEFAULT_DISPLAY);
else
watchRotation.invoke(windowManagerService, screenRotationChanged);
//Stop monitoring for changes when you're done
if (removeRotationWatcher != null) {
removeRotationWatcher.invoke(windowManagerService, screenRotationChanged);
} catch (ClassNotFoundException | ClassCastException | InvocationTargetException | NoSuchMethodException | IllegalAccessException e) {
throw new RuntimeException(e);
}
Detect viewport orientation, if orientation is Portrait display alert message advising user of instructions
if(window.innerHeight > window.innerWidth){
alert("Please use Landscape!");
}
jQuery Mobile has an event that handles the change of this property... if you want to warn if someone rotates later - orientationchange
Also, after some googling, check out window.orientation
(which is I believe measured in degrees...)
EDIT: On mobile devices, if you open a keyboard then the above may fail, so can use screen.availHeight
and screen.availWidth
, which gives proper height and width even after the keyboard is opened.
if(screen.availHeight > screen.availWidth){
alert("Please use Landscape!");
}
Detect rotation of Android phone in the browser with JavaScript
To detect an orientation change on an Android browser, attach a listener to the orientationchange
or resize
event on window
:
// Detect whether device supports orientationchange event, otherwise fall back to
// the resize event.
var supportsOrientationChange = "onorientationchange" in window,
orientationEvent = supportsOrientationChange ? "orientationchange" : "resize";
window.addEventListener(orientationEvent, function() {
alert('HOLY ROTATING SCREENS BATMAN:' + window.orientation + " " + screen.width);
}, false);
Check the window.orientation
property to figure out which way the device is oriented. With Android phones, screen.width
or screen.height
also updates as the device is rotated. (this is not the case with the iPhone).
Swift - How to detect orientation changes
let const = "Background" //image name
let const2 = "GreyBackground" // image name
@IBOutlet weak var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
imageView.image = UIImage(named: const)
// Do any additional setup after loading the view.
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
if UIDevice.current.orientation.isLandscape {
print("Landscape")
imageView.image = UIImage(named: const2)
} else {
print("Portrait")
imageView.image = UIImage(named: const)
}
}
How to detect screen rotation through 180 degrees from landscape to landscape orientation?
OrientationEventlistener won't work when the device isn't rotating/moving.
I find display listener is a better way to detect the change.
DisplayManager.DisplayListener mDisplayListener = new DisplayManager.DisplayListener() {
@Override
public void onDisplayAdded(int displayId) {
android.util.Log.i(TAG, "Display #" + displayId + " added.");
}
@Override
public void onDisplayChanged(int displayId) {
android.util.Log.i(TAG, "Display #" + displayId + " changed.");
}
@Override
public void onDisplayRemoved(int displayId) {
android.util.Log.i(TAG, "Display #" + displayId + " removed.");
}
};
DisplayManager displayManager = (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE);
displayManager.registerDisplayListener(mDisplayListener, UIThreadHandler);
How do I detect screen rotation
You are correct that at a 180 degree rotation you will not get restarted or get a configuration change, because the configuration has not actually changed. (It is still in landscape or portrait, and everything else is the same.)
However if you are showing a compass, that must mean you are updating it from sensor events. Thus you can just call Display.getRotation() each time you get a sensor update to get the current rotation of the screen. In fact that you need is rotation of interpreting sensor events (or actually how your drawing of them will be modified when it gets to the screen), not just the orientation.
I found a relevant blog post that is well worth reading.
Be sure to read the SDK documentation.
Also check out the discussion about using Display.getRotation() to correctly remap sensor coordinates.
Related Topics
Eclipse Hangs at The Android Sdk Content Loader
What Features Do Progressive Web Apps Have VS. Native Apps and Vice-Versa, on Android
Right Align Text in Android Textview
Android Device Configuration for Aosp
How to Set The Title Color for The New Toolbar
Android Studio Run/Debug Configuration Error: Module Not Specified
Android, How to Read Qr Code in My Application
How to Close Activity and Go Back to Previous Activity in Android
How to Set a Ripple Effect on Textview or Imageview on Android
Need Some Clarification About Beta/Alpha Testing on The Developer Console
Best Way to Show a Loading/Progress Indicator
Google Maps V2 - Set Both My Location and Zoom In
Why Should We Use Sp for Font Sizes in Android