Detect rotation of Android phone in the browser with JavaScript

JavascriptAndroidWebkit

Javascript Problem Overview


I know that in Safari on an iPhone you can detect the screen's orientation and change of orientation by listening for the onorientationchange event and querying window.orientation for the angle.

Is this possible in the browser on Android phones?

To be clear, I am asking whether the rotation of an Android device can be detected by JavaScript running on a standard web page. It is possible on an iPhone, and I wondered whether it could be done for Android phones.

Javascript Solutions


Solution 1 - Javascript

The actual behavior across different devices is inconsistent. The resize and orientationChange events can fire in a different sequence with varying frequency. Also, some values (e.g. screen.width and window.orientation) don't always change when you expect. Avoid screen.width -- it doesn't change when rotating in iOS.

The reliable approach is to listen to both resize and orientationChange events (with some polling as a safety catch), and you'll eventually get a valid value for the orientation. In my testing, Android devices occasionally fail to fire events when rotating a full 180 degrees, so I've also included a setInterval to poll the orientation.

var previousOrientation = window.orientation;
var checkOrientation = function(){
    if(window.orientation !== previousOrientation){
        previousOrientation = window.orientation;
        // orientation changed, do your magic here
    }
};

window.addEventListener("resize", checkOrientation, false);
window.addEventListener("orientationchange", checkOrientation, false);

// (optional) Android doesn't always fire orientationChange on 180 degree turns
setInterval(checkOrientation, 2000);

Here are the results from the four devices that I've tested (sorry for the ASCII table, but it seemed like the easiest way to present the results). Aside from the consistency between the iOS devices, there is a lot of variety across devices. NOTE: The events are listed in the order that they fired.

|==============================================================================|
|     Device     | Events Fired      | orientation | innerWidth | screen.width |
|==============================================================================|
| iPad 2         | resize            | 0           | 1024       | 768          |
| (to landscape) | orientationchange | 90          | 1024       | 768          |
|----------------+-------------------+-------------+------------+--------------|
| iPad 2         | resize            | 90          | 768        | 768          |
| (to portrait)  | orientationchange | 0           | 768        | 768          |
|----------------+-------------------+-------------+------------+--------------|
| iPhone 4       | resize            | 0           | 480        | 320          |
| (to landscape) | orientationchange | 90          | 480        | 320          |
|----------------+-------------------+-------------+------------+--------------|
| iPhone 4       | resize            | 90          | 320        | 320          |
| (to portrait)  | orientationchange | 0           | 320        | 320          |
|----------------+-------------------+-------------+------------+--------------|
| Droid phone    | orientationchange | 90          | 320        | 320          |
| (to landscape) | resize            | 90          | 569        | 569          |
|----------------+-------------------+-------------+------------+--------------|
| Droid phone    | orientationchange | 0           | 569        | 569          |
| (to portrait)  | resize            | 0           | 320        | 320          |
|----------------+-------------------+-------------+------------+--------------|
| Samsung Galaxy | orientationchange | 0           | 400        | 400          |
| Tablet         | orientationchange | 90          | 400        | 400          |
| (to landscape) | orientationchange | 90          | 400        | 400          |
|                | resize            | 90          | 683        | 683          |
|                | orientationchange | 90          | 683        | 683          |
|----------------+-------------------+-------------+------------+--------------|
| Samsung Galaxy | orientationchange | 90          | 683        | 683          |
| Tablet         | orientationchange | 0           | 683        | 683          |
| (to portrait)  | orientationchange | 0           | 683        | 683          |
|                | resize            | 0           | 400        | 400          |
|                | orientationchange | 0           | 400        | 400          |
|----------------+-------------------+-------------+------------+--------------|

Solution 2 - 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).

Solution 3 - Javascript

two-bit-fool's excellent answer provides all the background, but let me attempt a concise, pragmatic summary of how to handle orientation changes across iOS and Android:

  • If you only care about window dimensions (the typical scenario) - and not about the specific orientation:
    • Handle the resize event only.
    • In your handler, act on window.innerWidth and window.InnerHeight only.
    • Do NOT use window.orientation - it won't be current on iOS.

  • If you DO care about the specific orientation:
    • Handle only the resize event on Android, and only the orientationchange event on iOS.
    • In your handler, act on window.orientation (and window.innerWidth and window.InnerHeight)

These approaches offer slight benefits over remembering the previous orientation and comparing:

  • the dimensions-only approach also works while developing on desktop browsers that can otherwise simulate mobile devices, e.g., Chrome 23. (window.orientation is not available on desktop browsers).
  • no need for a global/anonymous-file-level-function-wrapper-level variable.

Solution 4 - Javascript

You could always listen to the window resize event. If, on that event, the window went from being taller than it is wide to wider than it is tall (or vice versa), you can be pretty sure the phone orientation was just changed.

Solution 5 - Javascript

It is possible in HTML5.
You can read more (and try a live demo) here: http://slides.html5rocks.com/#slide-orientation.

window.addEventListener('deviceorientation', function(event) {
    var a = event.alpha;
    var b = event.beta;
    var g = event.gamma;
}, false);

It also supports deskop browsers but it will always return the same value.

Solution 6 - Javascript

I had the same problem. I am using Phonegap and Jquery mobile, for Adroid devices. To resize properly I had to set a timeout:

$(window).bind('orientationchange',function(e) {
  fixOrientation();
});

$(window).bind('resize',function(e) {
  fixOrientation();
});

function fixOrientation() {
	
	setTimeout(function() {

		var windowWidth = window.innerWidth;
	    
		$('div[data-role="page"]').width(windowWidth);
		$('div[data-role="header"]').width(windowWidth);
		$('div[data-role="content"]').width(windowWidth-30);
		$('div[data-role="footer"]').width(windowWidth);
		
	},500);
}

Solution 7 - Javascript

Here is the solution:

var isMobile = {
    Android: function() {
        return /Android/i.test(navigator.userAgent);
    },
    iOS: function() {
        return /iPhone|iPad|iPod/i.test(navigator.userAgent);
    }
};
if(isMobile.Android())
	{
		var previousWidth=$(window).width();
		$(window).on({
        resize: function(e) {
		var YourFunction=(function(){
		
			var screenWidth=$(window).width();
			if(previousWidth!=screenWidth)
			{
				previousWidth=screenWidth;
				alert("oreientation changed");
			}
			
        })();
		
		}
    });
		 
	}
	else//mainly for ios
	{
		$(window).on({
			orientationchange: function(e) {
			   alert("orientation changed");
			}	
    	});
	}

Solution 8 - Javascript

Another gotcha - some Android tablets (the Motorola Xoom I believe and a low-end Elonex one I'm doing some testing on, probably others too) have their accelerometers set up so that window.orientation == 0 in LANDSCAPE mode, not portrait!

Solution 9 - Javascript

you can try the solution, compatible with all browser.

Following is orientationchange compatibility pic: compatibility therefore, I author a orientaionchange polyfill, it is a based on @media attribute to fix orientationchange utility library——orientationchange-fix

window.addEventListener('orientationchange', function(){
 if(window.neworientation.current === 'portrait|landscape'){
    // do something……
 } else {
    // do something……
 }
}, false);

Solution 10 - Javascript

Worth noting that on my Epic 4G Touch I had to set up the webview to use WebChromeClient before any of the javascript android calls worked.

webView.setWebChromeClient(new WebChromeClient());

Solution 11 - Javascript

Cross browser way

$(window).on('resize orientationchange webkitfullscreenchange mozfullscreenchange fullscreenchange',  function(){
//code here
});

Solution 12 - Javascript

A little contribution to the two-bit-fool's answer:

As described on the table on droid phones "orientationchange" event gets fired earlier than "resize" event thus blocking the next resize call (because of the if statement). Width property is still not set.

A workaround though maybe not a perfect one could be to not fire the "orientationchange" event. That can be archived by wrapping "orientationchange" event binding in "if" statement:

if (!navigator.userAgent.match(/android/i))
{
    window.addEventListener("orientationchange", checkOrientation, false);
}

Hope it helps

(tests were done on Nexus S)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionphilnashView Question on Stackoverflow
Solution 1 - Javascripttwo-bit-foolView Answer on Stackoverflow
Solution 2 - Javascriptjb.View Answer on Stackoverflow
Solution 3 - Javascriptmklement0View Answer on Stackoverflow
Solution 4 - JavascriptJoel MuellerView Answer on Stackoverflow
Solution 5 - JavascriptDerek 朕會功夫View Answer on Stackoverflow
Solution 6 - JavascripttauanzView Answer on Stackoverflow
Solution 7 - JavascriptShishir AroraView Answer on Stackoverflow
Solution 8 - Javascriptjames-geldartView Answer on Stackoverflow
Solution 9 - JavascriptZhansingsongView Answer on Stackoverflow
Solution 10 - JavascriptcalebisstupidView Answer on Stackoverflow
Solution 11 - JavascriptTim KozakView Answer on Stackoverflow
Solution 12 - JavascriptAlexView Answer on Stackoverflow