This is weird. I tried to pick up an image to preview it in a div using the HTML5 FileReader.readAsDataURL() function and a inline-image. This works fine on most browsers incl. iPhone's Safari.
But if I'm using the standard Android browser on a Samsung Nexus AND pick a photo which is stored on the phone I alwas get a width of 10810px and a height of 4286px regardless of which size the source image has, when I use a picture directly by taking a new photo it works. I get the correct sizes. :# I tried naturalWitdh, width, using jQUery and native javascript. All with same results
$('#file-input').change(function () {
if (window.File && window.FileReader && window.FileList && window.Blob) {
var files = this.files ? this.files : this.currentTarget.files;
if (files && files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#picture')
.attr('src', e.target.result).attr('style', '')
.load(function () {
console.log('w:' + $(this).width());
});
};
reader.readAsDataURL(files[0]);
}
} else {
alert('an error message');
}
});
Have you tried hooking chrome up to your computer's chrome to see if the image and or divs are doing anything funky?
I had the same problem and found a solution for android (browser) 4.0 and up.
I found that it works correctly if you use the createObjectURL function to do something like the following:
function getImgSize(input) {
if (input.files && input.files[0]) {
var apiURL = (window.createObjectURL && window)
|| (window.URL && URL.revokeObjectURL && URL)
|| (window.webkitURL && webkitURL);
var url = apiURL.createObjectURL(input.files[0]);
$('#testImg').attr('src', url);
}
}
$('#testImg').on('load',function(){
alert($(this).width()+'*'+$(this).height());
});
$("input").change(function(){
getImgSize(this);
});
See http://jsfiddle.net/bravoman/qm2C5/5/ for a full example and use http://jsfiddle.net/bravoman/qm2C5/5/embedded/result/ to test it on your device/emulator.
Related
If a user visits my websites example, from Safari Mobile how could I place there a blank page that says "Add To Homescreen."? Once added it would show different content.
You'll want to check two things. First, is it running on an iOS device? Second, is window.navigator.standalone == true?
window.navigator.standalone is primarily used by Webkit browsers to indicate the app is in fullscreen (or standalone) mode. Plenty of devices (like phones running Android), support this property, but don't have the option to 'Add to Homescreen' like iOS devices do, so you need to check both.
Demo:
Javascript:
function isIOS() {
var userAgent = window.navigator.userAgent.toLowerCase();
return /iphone|ipad|ipod/.test( userAgent );
};
function isStandalone() {
return ( isIOS() && window.navigator.standalone );
};
window.onload = function () {
if( isStandalone() || !isIOS() ) { //either ios+standalone or not ios
//start app
} else {
//display add to homescreen page
};
};
Check window.navigator.standalone.
Slight slight different code, based on #ThinkingStiff solution, and this other question on this Post, to support IOS7 detection to provide CSS interface to add more padding-top in case of transparent app title.
isIOS7 = function() {
return navigator.userAgent.match(/(iPad|iPhone|iPod touch);.*CPU.*OS 7_\d/i);
};
isStandaloneAndIOS7 = function() {
return isIOS7() && window.navigator.standalone;
};
if (isStandaloneAndIOS7()) {
body = document.getElementsByTagName("body")[0];
body.className = body.className + " standalone";
}
Does anyone have further details on how this would be done to handle multiple devices. I would like to target iPhone, Android, and Windows devices. According to this article, you can use different links. Any thoughts on how 3 different links should be used around on single element?
http://habaneroconsulting.com/insights/opening-native-map-apps-from-the-mobile-browser#.VYg3-flVikp
I usually do this:
var isiOS = (navigator.userAgent.match('iPad') || navigator.userAgent.match('iPhone') || navigator.userAgent.match('iPod'));
var isAndroid = navigator.userAgent.match('Android');
var isWP = navigator.userAgent.match('Windows Phone') || navigator.userAgent.match('IEMobile');
if (isiOS){
setTimeout(function () { window.location = siteURL; }, 25); //fall back url
$('body').append('<iframe style="visibility: hidden;" src="'+ appURI +'" />');
} else if ((isAndroid) || (isWP)){
setTimeout(function () { window.location = siteURL; }, 25); //fall back url
window.location = appURI;
} else { // if (isOtherPlatform)
window.location = siteURL;
}
Note that on iOS, you can not determine if user has the map app installed or not. If you navigate to an app which the user has not installed would result in an ugly message complaining the absent of the target app. The workaround is to open that deep link in the iframe.
Also note that you should always redirect users to the web version of maps after some seconds to provide a smooth flow.
I have serious issues loading binary image data into a simple image-element. I coded a cordova app (using Sencha touch) which loads images the following way:
xhr.open('GET', imageUrl, true);
xhr.responseType = 'blob';
xhr.addEventListener('load', function () {
if (xhr.status === 200) {
// onload needed since Google Chrome doesn't support addEventListener for FileReader
fileReader.onload = function (evt) {
image.setSrc(evt.target.result);
};
// Load blob as Data URL
fileReader.readAsDataURL(xhr.response);
}
}, false);
On Android 5 and 4.4 (these are the ones I tested) it works like a charm. Now I ran it Android 4.1 on an ASUS Tablet and the onload callback doesn't get fired. When I throw a blob in the readAsDataURL-function, at least the onload callback is fired, but the image doesn't show any image as well :(
Has anyone a suggestion, what the failure could be or what I'm doing wrong?
Ah, finally I got it to work on Android 4.1.1 (ASUS Tablet) with the following code. Another issue was, that saving an arraybuffer response from the xhr could not simply serialized, so I converted the stuff to string. Also I receive the blob taking into account, that on some systems the Blob object simply isn't there:
function arrayBufferToString(buf) {
return String.fromCharCode.apply(null, new Uint8Array(buf));
};
function stringToArrayBuffer(str) {
var buf = new ArrayBuffer(str.length*2); // 2 bytes for each char
var bufView = new Uint8Array(buf);
for (var i=0, strLen=str.length; i<strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
};
function getBlob(content, type) {
var blob = null;
// Android 4 only has the deprecated BlobBuilder :-(
try {
blob = new Blob([content], {type: type});
} catch(e) {
window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder ||
window.MozBlobBuilder || window.MSBlobBuilder;
if (window.BlobBuilder)
{
var bb = new BlobBuilder();
bb.append(content);
blob = bb.getBlob(type);
}
}
return blob;
};
cachedFile = getCachedFile(...); // not of interest here, I think :-)
if (cachedFile)
{
callback.apply(this, [window.webkitURL.createObjectURL(getBlob(stringToArrayBuffer(cachedFile.data), 'image/jpeg'))]);
}
else {
xhr.open('GET', imageUrl, true);
xhr.responseType = 'arraybuffer';
xhr.addEventListener('load', function () {
if (xhr.status === 200) {
cachedFile = {
url: imageUrl,
data: arrayBufferToString(xhr.response)
};
addCachedFile(cachedFile); // not of interest here, I think :-)
callback.apply(this, [window.webkitURL.createObjectURL(getBlob(xhr.response, 'image/jpeg'))]);
}
}, false);
// Send XHR
xhr.send();
}
Edit: Just did a little change and now used the Uint8Array Class instead of the Uint16Array Class because I got errors: "RangeError: byte length of Uint16Array should be a multiple of 2". Now it works well.
Edit2: Just saw, that the above code doesn't work out in all situations because of the usage of Uint8Array resp. Uint16Array.
Now I think I have a solid solution: I convert the binary responded by the image url into a base64 using canvas with the function from here http://appcropolis.com/blog/web-technology/javascript-encode-images-dataurl/ . Takes a little time, but still a working solution :)
Good day folks.
I am stuck with a strange problem and after lots of googling I couldn't find the solution/answer
I am creating and Sencha +cordova app for android.
It simply display 10 images in loop.
my code works fine on Chrome browser in desktop.
It fails On android 4.4.2 device when I install as APK.
Please help to fix the code for android.
init: function () {
this.callParent(arguments);
//console.log('init');
if(Ext.os.name == 'Android')
baseurl = baseAndroidUrl;
else
baseurl = baseDesktopUrl;
//alert('baseurl ' + baseurl);
}
var baseurl;
var baseAndroidUrl = 'file:///android_asset/www/resources/resources/images/';
var baseDesktopUrl = '/resources/resources/images/';
var imageArray =
['page00.jpg',
'page01.jpg',
'page02.jpg',
'page03.jpg',
'page04.jpg',
'page05.jpg',
'page06.jpg',
'page07.jpg',
'page08.jpg',
'page09.jpg',
'page10.jpg'];
var counter = 0;
-----------------------------------------------
onPrePageCommand: function () {
console.log('onPrePageCommand');
if( counter === 0 )
return ;
counter--;
// Folloing dynamic updation doesn't work in android , works perfectly on desktop
Ext.getCmp('pageID').setSrc(baseurl+imageArray[counter]);
//Ext.getCmp('pageID ').doLayout();
},
onNextPageCommand: function () {
console.log('onNextPageCommand');
if( counter === imageArray.length-1 )
return ;
counter++;
Ext.getCmp('pageID').setSrc(baseurl+imageArray[counter]);
},
------------------------------------------
//initial view : work perfect for both Desktop browser and APK
{
xtype: 'image',
src:'resources/images/Page00.jpg',
id:'pageID',
mode:'image'
height:'100%',
width:'100%'
}
--------------------------------------------
Try to use a Framework for that like http://wowslider.com/ this worked great for me the last time. You can also scroll the images with your fingers (swipe them).
How can I detect my document has reached the page bottom on mobile devices?
I have this code works perfectly on desktop devices, but not on mobile devices, such as android phones,
$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() == $(document).height()) {
alert("bottom!");
}
});
any idea what else should I include in the code to make it work on mobile?
I am using it for infinite scroll. I have a "load more" link on nearly bottom of page.
jQuery( window ).scroll( function() {
var loadMoreLink = 'a.infinite-link';
var actualLink = jQuery( loadMoreLink );
if ( actualLink.length ) {
var currentPosition = jQuery( loadMoreLink ).offset();
var pixelsVisible = window.innerHeight - currentPosition.top + jQuery( window ).scrollTop();
if ( pixelsVisible > 100 ) {
// time to do some ajax call.
}
}
});