Android redirect does not work - javascript

I need to redirect in a javascript file to a given URI specified by the user.
So a quick example how I do this:
function redirect(uri) {
if(navigator.userAgent.match(/Android/i)) {
document.location.href=uri;
}
window.location.replace(uri);
}
This works fine for everything except Android devices. iOS and all modern Webbrowsers support window.location.replace(...), however Android devices don't do that.
But if I now try to redirect using this function, lets say to "http://www.google.com" the android devices fail to actually redirect to the given url.
Now is it just me being stupid here right now or is there another problem?
Sincerly
p.s. the redirect function is called as an callback from an XML request sent, but that should not be an issue at all.

Android supports document.location without the href property
Try to use:
function redirect(uri) {
if(navigator.userAgent.match(/Android/i))
document.location=uri;
else
window.location.replace(uri);
}

I think it should be window.location.href, not document.location.href.

I would suggest :
location.assign('someUrl');
It's a better solution as it keeps history of the original document, so you can navigate to the previous webpage using back-button or history.back() as explained here.

You can use match and replace in iOS but apparently not in Android. In my experience this is what works for redirects in Android:
<script type="text/javascript"> // <![CDATA[
if ( (navigator.userAgent.indexOf('Android') != -1) ) {
document.location = "http://www.your URL/your HTML file.html";
} // ]]>
</script>

You can just use: window.location = "http://example.com";

Related

Deep linking opening both installed app on the android and playstore url

I am trying to acheive deeplinking through below javascrip piece of code, but the issue is if I have an installed app on android device it is opening both application and playstore url at sametime.Any suggestions to this?
<html>
<body>
<button onclick="launchAndroidApp()">Deep linking test</button>
<script>
function launchAndroidApp() {
var test = window.open('DeeplinkingURL', "_self");
setTimeout("window.location = 'Playstoreurl", 1000);
}
</script>
</body>
</html>
You can use a single URL using Android Intents with Chrome. For example, supposing DeeplinkingUrl="https://example.com/hello" and you expect it to be opened by the com.example.Hello application,
intent://example.com/hello
#Intent;
scheme=https;
package=com.example.Hello;
S.browser_fallback_url=market%3A%2F%2Fdetails%3Fid%3Dcom.example.Hello;
end
without the spaces, will use com.example.Hello to launch https://example.com/hello if available, and open the Play store listing for the app otherwise. (Of course you could use http://play.google.com/store/apps/details?id= instead of market://details?id=.)
The setTimeout method simply gets executed regardless after 1 second. This is not the right approach to doing so, but if you are convinced on this method, I'd try using a try-catch.
try{
window.open('DeeplinkingURL', "_self");
} catch {
window.location = 'Playstoreurl';
}
Instead, I'd recommend using Branch. You can do this with their SDK for free and much cleaner.

Meteor method not working properly in mozilla

I am trying to make a call to a meteor method, to insert a document before redirecting the user to the relevant url (using the generated document _id).
The code currently works on chromium but not on firefox, where on firefox it appears to just get redirected right away without actually inserting anything.
I've attached my code at the bottom. Can anyone tell me what went wrong and what can I do to fix it? Why will chrome and firefox behave differently in this situation?
Any help provided is greatly appreciated!
client.js
newDoc(){
Meteor.call('addDoc',{
// some parameters
})
}
clientandserver.js (Meteor method)
'addDoc'(obj){
console.log(obj); // does not output anything on firefox
DocumentData.insert({
//some parameters
},function(err,documentID){
if (Meteor.isClient){
window.location = '/docs/' + documentID;
// redirection happens before insertion on firefox
}
});
}
Bring window.location to the client side. Like:
newDoc(){
Meteor.call('addDoc', data, function(error, result){
if(result){
window.location = '/docs/' + documentID;
}
})
}
And put only the insertion in server side, like:
'addDoc'(obj){
return DocumentData.insert({
//some parameters
});
}
I've used this structure and it works for me in both Firefox & Chrome.

WKWebView doesn't interact anymore with Javascript in iOS10

I have a native app which has to interact with a website. It has been working normally up to iOS 9, but with iOS 10, the Javascript code inside the web app is no longer valid.
Here is an example of the JS code I use on the onClick event of a button, which as mentioned worked like a charm before iOS10.
function DoSomething()
{
var iframe = document.createElement("IFRAME");
var url='codeToBeUsed://id=1230';
iframe.setAttribute("src", url);
document.documentElement.appendChild(iframe);
iframe.parentNode.removeChild(iframe);
iframe = null;
}
when I debug the app on Xcode, the request variable which normally contained the content of the "url" variable on the example provided, now returns a blank value...
<NSMutableURLRequest: 0x170011070> { URL: about:blank }
I even tested placing a alert('click'); but it didn't work either. Does anybody know how to solve this issue?
Using a code close to yours (I pass a stringified json in the src), I also got an embarassing 'about;blank' in the request.
It seems iOs10 has some new restrictions on what you pass to iframe 'src'. I found it requires a valid url to trigger properly the request.
Try to use :
var url='codeToBeUsed://?id=1230';
Edit : or encode URI...

Detect between a mobile browser or a PhoneGap application

Is it possible to detect if the user is accessing through the browser or application using JavaScript?
I'm developing a hybrid application to several mobile OS through a web page and a PhoneGap application and the goal would be to:
Use the same code independently of the deployment target
Add PhoneGap.js file only when the user agent is an application
You could check if the current URL contains http protocol.
var app = document.URL.indexOf( 'http://' ) === -1 && document.URL.indexOf( 'https://' ) === -1;
if ( app ) {
// PhoneGap application
} else {
// Web page
}
Quick solution comes to mind is,
onDeviceReady
shall help you. As this JS call is invoked only by the Native bridge (objC or Java), the safari mobile browser will fail to detect this. So your on device app(phone gap) source base will initiate from onDeviceReady.
And if any of the Phonegap's JS calls like Device.platform or Device.name is NaN or null then its obviously a mobile web call.
Please check and let me know the results.
I figured out a way to do this and not rely on deviceready events thus, keeping the web codebase intact...
The current problem with using the built in deviceready event, is that when the page is loaded, you have no way of telling the app: "Hey this is NOT running on an mobile device, there's no need to wait for the device to be ready to start".
1.- In the native portion of the code, for example for iOS, in MainViewController.m there's a method viewDidLoad, I am sending a javascript variable that I later check for in the web code, if that variable is around, I will wait to start the code for my page until everything is ready (for example, navigator geolocation)
Under MainViewController.m:
- (void) viewDidLoad
{
[super viewDidLoad];
NSString* jsString = [NSString stringWithFormat:#"isAppNative = true;"];
[self.webView stringByEvaluatingJavaScriptFromString:jsString];
}
2.- index.html the code goes like this:
function onBodyLoad()
{
document.addEventListener("deviceready", onDeviceReady, false);
}
function onDeviceReady(){;
myApp.run();
}
try{
if(isAppNative!=undefined);
}catch(err){
$(document).ready(function(){
myApp.run();
});
}
PhoneGap has window.PhoneGap (or in Cordova, it's window.cordova or window.Cordova) object set. Check whether that object exists and do the magic.
Inside the native call where the url for the phonegap app is loaded you add a parameter target with value phonegap. So the call for android becomes something like this.
super.loadUrl("file:///android_asset/www/index.html?target=phonegap");
Your website using this code won't be called with the extra parameter, so we now have something different between the two deploying platforms.
Inside the javascript we check if the parameter exists and if so we add the script tag for phonegap/cordova.
var urlVars = window.location.href.split('?');
if(urlVars.length > 1 && urlVars[1].search('target=phonegap') != -1){
//phonegap was used for the call
$('head').append('<script src="cordova.js"></script>');
}
A small caveat: this method requires to change the call to index.html in phonegap for each different targeted mobile platform. I am unfamiliar where to do this for most platforms.
what if you try following :
if(window._cordovaNative) {
alert("loading cordova");
requirejs(["...path/to/cordova.js"], function () {
alert("Finished loading cordova");
});
}
I am using the same code for both phonegap app and our web client. Here is the code that I use to detect if phonegap is available:
window.phonegap = false;
$.getScript("cordova-1.7.0.js", function(){
window.phonegap = true;
});
Keep in mind that phonegap js file is loaded asynchronously. You can load it synchronously by setting the correct option of a nifty jquery $.getScript function.
Note that approach does make an extra GET request to grab phonegap js file even in your webclient. In my case, it did not affect the performance of my webclient; so it ended up being a nice/clean way to do this.Well at least until someone else finds a quick one-line solution :)
It sounds like you are loading another webpage once the webview starts in the Phonegap app, is that correct? If that's true then you could add a param to the request url based on configuration.
For example, assuming PHP,
App.Config = {
target: "phonegap"
};
<body onload="onbodyload()">
var onbodyload = function () {
var target = App.Config.target;
document.location = "/home?target=" + target;
};
Then on the server side, include the phonegap js if the target is phonegap.
There is no way to detect the difference using the user agent.
The way I'm doing it with is using a global variable that is overwritten by a browser-only version of cordova.js. In your main html file (usually index.html) I have the following scripts that are order-dependent:
<script>
var __cordovaRunningOnBrowser__ = false
</script>
<script src="cordova.js"></script> <!-- must be included after __cordovaRunningOnBrowser__ is initialized -->
<script src="index.js"></script> <!-- must be included after cordova.js so that __cordovaRunningOnBrowser__ is set correctly -->
And inside cordova.js I have simply:
__cordovaRunningOnBrowser__ = true
When building for a mobile device, the cordova.js will not be used (and instead the platform-specific cordova.js file will be used), so this method has the benefit of being 100% correct regardless of protocols, userAgents, or library variables (which may change). There may be other things I should include in cordova.js, but I don't know what they are yet.
Ive ben struggling with this aswell, and i know this is an old thread, but i havent seen my approach anywhere, so thought id share incase itll help someone.
i set a custom useragent after the actual useragent :
String useragent = settings.getUserAgentString();
settings.setUserAgentString(useragent + ";phonegap");
that just adds the phonegap string so other sites relying on detecting your mobile useragent still works.
Then you can load phonegap like this:
if( /phonegap/i.test(navigator.userAgent) )
{
//you are on a phonegap app, $getScript etc
} else {
alert("not phonegap");
}
To my mind you try to make issue for self. You didn't mentioned your development platform but most of them have different deployment configuration. You can define two configurations. And set variable that indicates in which way code was deployed.
In this case you don't need to care about devices where you deployed your app.
Short and effective:
if (document.location.protocol == 'file:') { //Phonegap is present }
Similar to B T's solution, but simpler:
I have an empty cordova.js in my www folder, which gets overwritten by Cordova when building. Don't forget to include cordova.js before your app script file (it took my one hour to find out that I had them in wrong order...).
You can then check for the Cordova object:
document.addEventListener('DOMContentLoaded', function(){
if (window.Cordova) {
document.addEventListener('DeviceReady', bootstrap);
} else {
bootstrap();
}
});
function bootstrap() {
do_something()
}
New solution:
var isPhoneGapWebView = location.href.match(/^file:/); // returns true for PhoneGap app
Old solution:
Use jQuery, run like this
$(document).ready(function(){
alert(window.innerHeight);
});
Take iPhone as example for your mobile application,
When using PhoneGap or Cordova, you'll get 460px of WebView, but in safari, you'll lose some height because of browser's default header and footer.
If window.innerHeight is equal to 460, you can load phonegap.js, and call onDeviceReady function
Nobody mentioned this yet, but it seems Cordova now supports adding the browser as a platform:
cordova platforms add browser
This will automatically add cordova.js during run-time, which features the onDeviceReady event, so that you do not need to fake it. Also, many plugins have browser support, so no more browser hacks in your code.
To use your app in the browser, you should use cordova run browser. If you want to deploy it, you can do so using the same commands as the other platforms.
EDIT: forgot to mention my source.
Solution: Patch index.html in Cordova and add cordova-platform="android" to <html> tag, so that cordova-platform attribute will be only present in Cordova build and missing from original index.html used for web outside of Cordova.
Pros: Not rely on user agent, url schema or cordova API. Does not need to wait for deviceready event. Can be extended in various ways, for example cordova-platform="browser" may be included or not, in order to distinguish between web app outside of Cordova with Cordova's browser platform build.
Merge with config.xml
<platform name="android">
<hook src="scripts/patch-android-index.js" type="after_prepare" />
</platform>
Add file scripts/patch-android-index.js
module.exports = function(ctx) {
var fs = ctx.requireCordovaModule('fs');
var path = ctx.requireCordovaModule('path');
var platformRoot = path.join(ctx.opts.projectRoot, 'platforms/android');
var indexPath = platformRoot + '/app/src/main/assets/www/index.html';
var indexSource = fs.readFileSync(indexPath, 'utf-8');
indexSource = indexSource.replace('<html', '<html cordova-platform="android"');
fs.writeFileSync(indexPath, indexSource, 'utf-8');
}
Notes: For other than android, the paths platforms/android and /app/src/main/assets/www/index.html should be adjusted.
App can check for cordova-platform with
if (! document.documentElement.getAttribute('cordova-platform')) {
// Not in Cordova
}
or
if (document.documentElement.getAttribute('cordova-platform') === 'android') {
// Cordova, Android
}

Loading a local page into Firefox with Javascript

For loading a local file into Firefox I have noticed that...
location.href = "./relative/path/file.htm"; //this works
location.href = "http://localhost/path/file.htm"; //this works
location.href = "file:///c:/absolute/path/file.htm"; //doesnt work (also doesnt work if remove the "file:///" bit)
I would like to get the last example to work. Is there some about.config setting I can add to allow this or maybe a "netscape.security.PrivilegeManager..." statement?
(This is for a special Firefox profile and not for general use so the insecurity issues are not relevant).
Thanks.
http://kb.mozillazine.org/Links_to_local_pages_don%27t_work#Firefox_1.5.2C_SeaMonkey_1.0_and_newer answers this
when using "file:///" you need to use backslashes ( windows ) in other words you need to type
the physical address of the file as it accessed from file explorer ( windows )
dont forget escape with "\\".
example:
var url = "file:///c:\\myDir\\1.html";

Categories

Resources