How can I address the Samsung Android browser? - javascript

I'm working on a responsive website and I have a weird CSS/JS issue with the default touchwiz browser of Android Samsung devices. I've searched on StackOverflow, finding some unhelpful answers like this.
I have the physical devices to test on, but since it's not possible to do remote debugging on these browsers it's really time consuming to make changes, deploy them a QA server, test, and retry.
Any idea on how can I speed up my testing or targeting that specific browsers?
Useragent is not helping in my case...
Just to make an example: one of the many problems I'm facing is on this free component, it's not positioning in the middle of the screen, while it's ok on all other android and iOS browsers.

For mobile testing, here are some resources might help.
Personally I prefer the Samsung emulator and Adobe Edge Inspect(will charge).
Adobe Edge Inspect
Samsung Emulators
Chrome - Device Mode & Mobile Emulation (recommended only for testing responsiveness)
Keynote (might charge fee)
Because the limit of the content length, Please click the links and see the detailed documentation.
Hope it will help to speed up the testing and debug on mobile devices.

If you have a device I would suggest you to try this tool weinre
It's allow you to remote debug. I always use it for stuff like that

JSBin can take care of the JS debug. Combined with the CSSRule API and the following to grab the browser's default style values for an element and its current rendered values, you might be able to get somewhere.
function defaultStyle(tag) {
var defaultStyles = {},
testElem = document.createElement(tag),
getStyle = 'getComputedStyle' in window,
styles;
document.body.appendChild(testElem);
styles = (getStyle) ? window.getComputedStyle(testElem) : testElem.currentStyle;
for (var prop in styles) {
if (!(/^\d+$/.test(prop))) {
defaultStyles[prop] = styles[prop];
}
}
document.body.removeChild(testElem);
return defaultStyles;
}
function currentStyle(elem) {
var currentStyles = {},
getStyle = 'getComputedStyle' in window,
styles;
styles = (getStyle) ? window.getComputedStyle(elem) : elem.currentStyle;
for (var prop in styles) {
if (!(/^\d+$/.test(prop))) {
currentStyles[prop] = styles[prop];
}
}
document.body.removeChild(testElem);
return currentStyles;
}

Use media queries for making css based on screen lengths. It does not matter whether it is samsung or iphone browser. You can also use bootstrap libraries for it.

Related

A-Frame look-controls very unstable on older devices

I'm building a 360 panorama viewer with A-Frame 1.0.4 and I'm having some trouble with older devices that I don't know how to solve. I'm testing in a WebView inside an Android application.
On most recent devices, the gyroscope and accelerometer work great, but on older devices (for example ASUS X008D), it's all shaky, the view can't stay still when I put the phone on the table or when I hold it. I thought it could be due to polyfills but I can't figure how. I added some logs to check for DeviceMotionEvent and DeviceOrientationEvent and both are recognized but it seems like it's not enough.
How could I be sure that the events are handled correctly and eventually disable the hmd in look-controls manually when it's not stable enough? There would still be the dragging and I would be fine with that.
Thanks for your help :)
After further investigations I found out where the issue came from. It was because the Sensor API was not available on some devices and the Gyroscope wasn't read correctly. If I understood correctly there was a fallback on DeviceMotion but it was probably not good on older devices, I don't know...
What I did to "fix" this was writing this little snippet to check that the Gyroscope class was available. If it was not I disabled all movements from look-controls component to allow only manual movements. I hope it can help anyone who meets this issue. It's kinda quick'n'dirty but it did the job so I'm okay with this.
var gyroscope = null;
try {
gyroscope = new Gyroscope();
gyroscope.addEventListener('error', event => {
document.getElementById("camera").setAttribute("look-controls", "magicWindowTrackingEnabled: false");
});
gyroscope.start();
// Stop the gyroscope after trying so it does not run in background.
setTimeout(function() { gyroscope.stop(); }, 500);
} catch (error) {
document.getElementById("camera").setAttribute("look-controls", "magicWindowTrackingEnabled: false");
}
There's also an open issue about it on A-Frame github page.

Calling function if mobile

I'm completely lost when it comes to jQuery/Javascript so apologies in advance. I'm using the MixItUp jQuery filter on a Wordpress site which has the option to show either grid or list view (default), what I'd like to do is set grid as default when visiting the site using a mobile device.
This is what I have at the moment (I've been copying and pasting from around the web so probably not even close):
if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) {
$(document).ready(function(){
$('#Grid').mixitup('toGrid');
});
Any help on this issue would be highly appreciated!
I have messed with detecting if a device is mobile or not a lot in the past and I have found it to be much easier to detect if it is not a mobile device versus detecting if it is a mobile device.
I like the searches you are doing, but you are missing a few like the Nook and Kindle a lot of mobile devices also use the word "mobile" in their user agent. With that said even if you include these in your search you will surely have more that pop up over the next few years. I have found it to be better to detect if it is a desktop or not because there are not new desktop operating systems being added on almost a yearly basis like we are seeing with mobile devices these days. Not only that but I have also found that older Android devices can return mixed results in their user agents.
Here is the bit of code we use to figure out if the device is Windows, Linux, Mac, Facebook, a bot, or a mobile device. We have used and tested this code a lot with all the different devices we have vising our site and it appears to be working correctly for all devices. I hope this helps!
$(document).ready(function(){
if (deviceType() == "Mobile")
$('#Grid').mixitup('toGrid');
});
function deviceType ()
{
var OSName="Mobile";
if (navigator.appVersion.indexOf("Win")!=-1 && navigator.appVersion.indexOf("Phone")===-1) OSName="Windows";
if (navigator.appVersion.indexOf("Macintosh")!=-1) OSName="MacOS";
if (navigator.appVersion.indexOf("X11")!=-1) OSName="UNIX";
if (navigator.appVersion.indexOf("Linux")!=-1 && navigator.appVersion.indexOf("Android")===-1) OSName="Linux";
if (navigator.appVersion.indexOf("facebook.com")!=-1) OSName="facebook";
if (navigator.appVersion.indexOf("bot")!=-1) OSName="bot";
if (navigator.appVersion.indexOf("Slerp")!=-1) OSName="bot";
return OSName;
}
You want to wrap the "if" statement and function call inside the document ready call. Not the other way around:
$(document).ready(function () {
if(/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|OperaMini/i.test(navigator.userAgent)) {
$('#Grid').mixitup({layoutMode : 'grid'});
}
});

Can I use Javascript to get the compass heading for iOS and Android?

Can I use Javascript in a cross-platform way to get the compass heading in iOS and Android (with Chrome), without using something like PhoneGap? I know iOS has DeviceOrientationEvent, but I can't find any equivalent on Chrome for Android.
As a primer you should review this previous related StackOverflow answer and be familiar with the general practical considerations for using DeviceOrientation Events in web applications.
The simple solution I provided in my previous related StackOverflow answer only applies to browsers that implement absolute deviceorientation events (i.e. browsers where the deviceorientation alpha property is compass-oriented). That means the solution provided there currently only works in Android browsers and not iOS-based browsers or any other browser that does not provide absolute-based deviceorientation event data.
To reliably obtain the current compass heading across both Android and iOS browsers today you need to handle both absolute and non-absolute implementations that provide the additional webkitCompassHeading property and make sure to account for any current screen orientation changes as part of that. AFAIK the only library that currently does this is Full Tilt JS (disclaimer: I am the author of this library).
The following code will give you the same correct compass heading across both iOS and Android browsers, taking account of the differences in device orientation implementations and applying any necessary runtime screen orientation transforms too:
<!-- Include the Full Tilt JS library from https://github.com/richtr/Full-Tilt-JS -->
<script src="fulltilt-min.js"></script>
<script>
// Obtain a new *world-oriented* Full Tilt JS DeviceOrientation Promise
var promise = FULLTILT.getDeviceOrientation({ 'type': 'world' });
// Wait for Promise result
promise.then(function(deviceOrientation) { // Device Orientation Events are supported
// Register a callback to run every time a new
// deviceorientation event is fired by the browser.
deviceOrientation.listen(function() {
// Get the current *screen-adjusted* device orientation angles
var currentOrientation = deviceOrientation.getScreenAdjustedEuler();
// Calculate the current compass heading that the user is 'looking at' (in degrees)
var compassHeading = 360 - currentOrientation.alpha;
// Do something with `compassHeading` here...
});
}).catch(function(errorMessage) { // Device Orientation Events are not supported
console.log(errorMessage);
// Implement some fallback controls here...
});
</script>
Here is a demo that demonstrates this technique to obtain the compass heading the user is facing. It should work well on both iOS and Android browsers.
The implementation of the code in that demo is as shown above and can be viewed on Github at ./scripts/compass.js:L268-L272.
Yes you can! Unfortunately the alpha doesn't work on iPhones/iPads. With Mobile Safari, alpha is based on the direction the device was pointing when device orientation was first requested. The included webkit offers you the compass heading. To make it work for all other browsers (which all supports alpha as compassheading) you can use the following Javascript code:
if (window.DeviceOrientationEvent) {
// Listen for the deviceorientation event and handle the raw data
window.addEventListener('deviceorientation', function(eventData) {
var compassdir;
if(event.webkitCompassHeading) {
// Apple works only with this, alpha doesn't work
compassdir = event.webkitCompassHeading;
}
else compassdir = event.alpha;
});
}
Android also supports Webkit, so would also use event.webkitCompassHeading, but that's OK.
BTW: "oncompassneedscalibration" is also not supported for iPhones and iPads.
I believe you can use the "heading" field of the location object, from navigator.geolocation, please see here:
https://developer.mozilla.org/en-US/docs/WebAPI/Using_geolocation
I know no other way.
Hope it helps,
A.

AppCache excruciatingly slow on iOS

I am developing a web-app utilizing Application Cache, and everything is working great on desktop browsers and on Android (even very old & slow android handsets). However downloading the appcache is taking much much much longer on iOS 6 in both Safari and Chrome.
My application cache total size is a mere 2.1Mb, and I have a pretty solid 70Mbps (download) internet connection. I would expect caching to be pretty rapid.
Here are my times so far:
Desktop Chrome: <1s (similar times for Safari & Firefox)
Android 2.3.3 Stock Browser: ~4s (similar times for Chrome & Dolphin)
Android 4.2.2 (Emulated): ~7s (running inside a PhoneGap app)
iPhone 4S 6.0 Safari: 8 minutes!!! (around the same in iOS Chrome too!!)
iPad 2 6.0 Safari: as above!!!
All of these devices are using the same wifi and internet connection, and my iPhone/iPad are otherwise functioning fine (no native apps exhibiting internet speed issues, and regular websites load just fine). There just seems to be something absolutely decimating AppCache download speed under iOS.
The window.applicationCache.status throughout this time is appCache.DOWNLOADING, and I have a progress event running counting the files as they are downloaded, so I'm certain that it is not stuck elsewhere. This just appears to be the time it takes to download. What gives?
Addendum : The iPhone also runs ridiculously hot, and the battery ticks down very quickly during this operation. It seems that something is causing the CPU to run flat-out during this download.
(Note: I can't publish a link to the web-app here as we're still in private beta, but if you would need to see it before you think you'd be able to help diagnose it, email me at the address in my profile and I'll send a link to the app).
Okay, I figured it out with the help of the iOS Emulator, and Xcode Instruments to profile it. (I'm not sure if I should add my solution into the main question, or as an answer, but I thought I'd do it this way as my question is already a little cluttered).
As it turns out, it was actually some erroneous javascript causing the issue, but apparently only on iOS.
The web-app is intended to only be a single page high (no vertical scrolling, except within specific DIVs), so in addition to the usual standard JS code for hiding the address bar...
window.addEventListener("load",function() {
// Set a timeout...
setTimeout(function(){
// Hide the address bar!
window.scrollTo(0, 1);
}, 0);
});
...I had also added in the following:
$(document).scroll(
function(e){
window.scrollTo(0, 1);
});
From looking at the profile results, I was able to see that a lot of time was being spent in scrollTo, so it immediately pointed to this as the cause. Why the scroll event was being triggered so much, I have no idea (this was occurring with no touching of the screen whatsoever).
My initial fix is to throttle that code, but I am now evaluating whether or not I even need it at all. Here is the code I have that fixes it for now (using jquery-debounce, which I was already using for something else):
$(document).scroll(
$.throttle(function(e){
window.scrollTo(0, 1);
})
, 10);
The download time of the application cache is now in line with the Android times. Phew!
The code is getting itself into an infinite loop, as the initial scrollTo function call triggers the scroll event handler, which then repeatedly re-triggers itself! My best guess is that the iOS JavaScript engine handles this infinite loop differently to the other browsers' JavaScript engines.

Flash always on top in Android browser workaround?

I have a website with a simple Flash animation behind some text and semi-transparent images as a background. I have used swfobject to embed it and set wmode opaque to make it display correctly in most browsers.
For browsers without Flash, the user gets a static background image instead and would not know they were missing anything. However, Android users get the flash background on top of everything as per the known issue with how Flash content is rendered in the Android browser making the site unusable.
I have added a crude browser sniff javascript function to the swfobject code to prevent it from loading for any user agent whith 'Mobile' in it:
<script type="text/javascript">
if (navigator.userAgent.indexOf('Mobile') == -1)
{
var flashvars = {};
var params = { wmode: "opaque" };
var attributes = {};
swfobject.embedSWF("Images/Layout/center_flash.swf", "flashBg",
"1004", "502", "9", "false", flashvars, params, attributes);
}
</script>
The only problem I have left is for Android users browsing with 'Mobile View' turned off as the user agent pretends to be a desktop version of Safari (I think). I do not wish to disable the Flash animation for all Safari users. Is there a way of blocking it for just Andriod users - even if they have 'Mobile View' disabled?
Possible ideas include:
detecting the Flash version with JavaScript or Flash. Does Android use specific versions (version numbers) of Flash which are different from the desktop equivalent?
blocking the specific user agents used by Android devices with 'Mobile View' disabled.
Has anyone come up with an effective workaround for this issue?
Your help/input is appreciated!
You can detect android only by checking the userAgent of the browser in your JavaScript
Something like this:
if (navigator.userAgent.toLowerCase().indexOf("android") != -1)
{
// It's android
}
As far as the flash issue itself, I don't know as I never use flash :P
edit
You can also use that technique for other useragents (I.E. iPhone, iPad, safari)
edit2
Sorry, I just went on my android phone and realized the actual setting changes the userAgent to whatever the user picks (desktop/ipad/iphone/safari). That's no good then, I apologize.
Unfortunately, what you are asking is very difficult then. There are no unique identifiers in the android flash version to give you any help. And the fact that android spoofs the userAgent makes it impossibly to detect if they are on mobile or not.
There exist services that can tell you whether a user is on mobile based on their IP.
I'm sorry to say I don't know how fast, reliable, or expensive they are, but if you must determine whether a user is on Android, that's an avenue to consider

Categories

Resources