Start External Browser from Cordova - javascript

We currently have an Cordova application that needs to start an external browser with a POST.
We have it coded to use the inAppBrowser plugin to start a browser that is embedded within the app.
I don't like using the internal browser because I will be blamed for any bugs in the webpage that render in the default browser and don't work in the inAppBrowser.
How can we start the default browser with a POST request?
Once the browser starts we do NOT need to have a back button in the browser that will take the user back to our app.
We are only worried about iOS and Android. We can use different solutions on each of those platforms.
I have googled but there is so much conflicting information; there will be a response that it works, then another person replies that it does not. There also caveats to getting it to work; for instance, it seems that one can get the URL to open in the default browser, but it also leaves the page open in the in-app-browser as well. This would be confusing for the end user.
[EDIT] I have created an upwork.com project to pay someone to create a cordova plugin specific for starting the external browser with a POST request. Feel free to comment on any anticipated problems with doing that.
[EDIT] Here are the steps I used to test on iOS:
clear all background tasks on iPhone
Start the app that has link intended to start external browser
click the link that is intended to start external browser
Observe that browser starts
double tap the home key to expose all running apps
if successfully running in default browser I should observe the original app and the browser running.
if successful we should also observe that the original app is not displaying the target webpage. This point is important because some people are able to start the default browser, but the original app is left in the state of having the webpage also displayed.

Looks like the "_blank" can not open url in external browser on iOS.
I tried by this:
1) Install inappbrowser plugin.
2) call window.open(encodeURI('https://openclipart.org/'), "_blank");
when button pressed.
The url open in app, not external browser.
Update:
Use "_system" will open url in Safari on iOS, to open url :
1) Install inappbrowser plugin.
2) call cordova.InAppBrowser.open(encodeURI('https://openclipart.org/'), "_system");
Unfortunately this way only work to send get request.
Some people suggest submit post form on loadstop event like this:
Cordova InAppBrowser post form to url
The method worked when target is "_blank", when target is "_system", because open url in browser not app windows, the loadstop event will not be fired.

You can open a browser outside of the app with inAppBrowser by specifying the target eg.;
var linkTarget = "_blank" ; ( was using for desktop ; had coded target as _system for Android. Apologies.)
[EDITED]
openclipart.org;
This doesn't open web page in the app - opens in system browser.
If the browser defaults have been cleared in the device settings app manager page this link will prompt the user for their choice of browser ( I'm assuming it otherwise uses the previously set default though you might want to double check particularly if you're using crosswalk )
There are other target options but seem to recall _system not working as expected - give it a try if _blank doesn't work
I don't think there's any straight forward way to launch a browser doing a post even if you had a special plugin ;
Looks like using a dataUrl might allow you to open browser doing a post - if so prob the cleanest approach. ( see link in Wu's answer below ) [EDIT] looks like won't work on Windows mobile platforms though; see caniuse dataURIs.
Alternatively, you might try a separate html file as part of your app files - load it into a new browser as above (except "file://.." )and have it run some startup javascript (maybe using a querystring for control) to do the post eg. via a jquery ajax call. There will be security issues with this approach - the file will have to be somewhere the browser has access to ( can have app copy it there from internal www folder - need read/write permissions ) . Not sure if there will be CORS issues etc. I'd definitely look into the dataUrl first if windows not a consideration.

Related

Cordova ios app - Not able to open links due to pop up blocker

I have a cordova application which downloads an angularjs application (Say 'MyAngularApp') from the server based on some version matching logic. This 'MyAngular' app comes in a zipped folder which my cordova application unzips and stores at a persistent location on mobile device.
After 'MyAngularApp' is successfully downloaded and unzipped, I launch 'MyAngularApp/index.html' from persistent location on device using file://path_to_angularjs_application_in_device/MyAngularApp/index.html
Now, the issue I am facing is that when user clicks on a link in 'MyAngularApp' on iOS, the popupblocker is blocking the pages to open. The code that is written inside 'MyAngularApp' to open a page is
function openUrlInNewTab(url, params, isExternal) {
if (params) {
url += '#' + params;
}
var windowName = url.startsWith('mailto') ? '_self' : '_blank';
$window.open(url, windowName);
}
I know if we can make a change above to modify the code and replace _blank to _system, it should work theoretically, but the problem is that I can not make a change inside 'MyAngularApp' code.
I tried switching off popupblocker setting from safari settings but that did not help. The point to consider here is that I can not make a change inside 'MyAngularApp' code. I can only modify my own cordova app which downloads this 'MyAngularApp'.
This issue happens only in iOS. This works perfectly on Android.
Tested on iOS versions 12+. Cordova version 7.0.0
What I tried ?
Go to Settings → Safari → Block Pop-ups → Disable (Did not work. New window still did not open)
Install cordova InAppBrowser plugin and assign window.open = cordova.InAppBrowser.open (Did not work because the problem here is that this piece if code would be applicable till my cordova app is loaded. Once 'MyAngularApp' loads then context changes and this chunk of code is no more in context).
Any ideas ?
I was able to resolve this myself. Here's what resolved my issue, in case someone is still looking for an answer.
Since, In the scenario explained above, the embedded AngularJs application did not have access to cordova libraries. It was downloaded on the go and then browsed in the cordova webview and that was blocking the required cordova assistance to open a new window.
I included 'cordova.js' file manually in the folder where my index.html resided and it resolved the issue.

Check if app is installed from webpage

I have an iOS and Android app and I'm building a corresponding website. I would like that the webpage, if opened using a mobile device, opens the app or its corresponding app store page (without using Facebook app links).
On the app side everything is working, including the url schema.
Does someone know how to implement this procedure, without external services, using HTML and JS?
Thanks in advance for your help.
To be honest, this is kind of a pain to implement on your own. There is no easy way to handle everything without a ton of nasty edge cases, most notably the 'Cannot Open Page" error users will see if they don't have your app installed. Until iOS 9, a reasonable basic implementation was putting a JavaScript redirect like this into a dedicated redirect page on your site:
setTimeout(function() {
window.location = "https://yourdomain.com";
}, 25);
// If "yourapp://" is registered, the user will see a dialog
// asking if they want to open your app. If they agree, your
// app will launch immediately and the timer won't fire.
// If not installed, you'll get an ugly "Cannot Open Page"
// dialogue and your fallback page will open when the timer expires.
window.location = "yourapp://";
Unfortunately this would still show a 'Cannot Open Page' error, but until recently it was possible to get around this in a reasonably user-friendly way by using a more nuanced version of this script. Sadly, Apple intentionally broke that with the iOS 9.2 update, so custom URL schemes are actually pretty much useless for deep linking now, unless you are certain the app is already installed on that device.
Apple is obviously trying to push the newer Universal Links standard as much as possible. Universal Links lets you use a normal http:// URL to a page on your website (the page could be a simple redirection to your desired fallback webpage without the custom URL trigger that causes the 'Cannot Open Page' error), which is intercepted by your phone and sent directly into your app if installed.
This is quite a lot to handle, so the best option might be a free service like Branch.io (full disclosure: I work with the team) to take care of all the technical aspects. You can find examples of apps using the Branch service here.

Safari/webapp launching native application iOS

I have a simple nginx docker container, ip => 192.168.99.100, which serves static html file with a bit of javascript in it. I mapped docker's port 80 to my machines, 172.20.16.34:8080, so I can access it from mobile device on local network.
I have a simple button with an 'click' event listener. On click this code is triggered:
window.location = "xyz_app://hello_world"
I expect this code to launch our native application on the device, with the registered URL scheme. However what always happens is that browser tries to redirect to:
172.20.16.34:8080/xyz_app://hello_world
instead of to:
xyz_app://hello_world
and opening the application. Any idea why?
When I was looking for ways of launching native applications from Safari, this:
window.location = "xyz_app://hello_world"
was the most commonly suggested way.
You need to make sure that your URL scheme does not have an underscore in it, as if it does it will not be correctly recognised as a URL scheme.

Open Android app through deep link if it's installed or fall back to web if not installed

I'm trying to create a web page that automatically opens an Android app but only if app is installed. In case it's not it should redirect to another web page.
The app is already in production and is properly handling deep links like example://content?id=42. The format of the link could not be changed.
What I've already tried
1) Redirects and timeout:
window.location.replace('example://content?id=42');
setTimeout(function() {
window.location.replace = 'http://example.com/content?id=42';
}, 500);
Works fine for iOS but for Android it redirects to example:// immediately and thus gives me ERR_UNKNOWN_URL_SCHEME. Seems to be no go for Android.
2) iframe approach. Impossible in rencent Chrome versions. Also doesn't seem to work in Samsung browser.
3) Intents with S.browser_fallback_url. Works well but in Chrome only. Doesn't work in Opera and Samsung browser... most probably nowhere else but Chrome 25+.
use http://example.com/content?id=42 as the link and add the intent filter to your activity in manifest
<intent-filter>
<data android:scheme="http" android:host="example.com" />
...
</intent-filter>
However, a list of app registered, e.g. browsers, will show up when the link is first accessed on the machine.
You need to be aware of the browser of the client, and its operating system and adapt your site to them. For example, if the browser is Chrome and the OS is Android, use the Intent solution; if the browser is Safari use the example:// schema. You can get the info looking at the User-Agent header of the request, but I'm sure there are many open source libraries that can help you to get infos related to browser and OS.
Seems like you could at least approximate the experience by letting the user give a one-time assist:
Have your web page itself have the fallback url content.
When the page is hit check the user agent to see if the os is Android
If its Android, show the user a choice prompt/dialog to use web or Android
If they choose web (remember the choice with local storage), dismiss the dialog and show the fallback
If they choose android (remember the choice), redirect to the app with the intent:// URL (without fallback_url), will take them to market to install if necessary
After the first interaction, it'll work as you describe - automatically taking them to the web page or the installed app.
You can try using this scheme(to be sent to the user):
intent://details?id=X&url=Y&referrer=Z#Intent;scheme=market;action=android.intent.action.VIEW;package=com.android.vending;end";
X: Package name of the App
Y: Deep link scheme which should be defined in the App's manifest.
(Please refer this)
Here, they have used this URL as an example: "http://www.example.com/gizmos" , therefore Y should be replaced by this URL.
Z: Can be any data which you want to pass to the App via Google Play.
Please take note that any data which you pass should not be '&' separated because the original parameters are itself '&' separated.
PS: The Google Play makes a broadcast to the app. So make sure you receive the broadcast in a receiver.

Can I embed a chrome extension app as part of my main AngularJS app?

I have been doing a lot of reading and studying to figure out.
I basically just want my main AngularJS application to run, but also include an embedded Chrome Extension app - in this case, have regularly scheduled alarms (using the chrome.alarm API).
I want all users of my AngularJS app to have automatic access to the Chrome extension app, embedded in the main clientside one with lots of other Angular features.
It seems like I have to manually enable my Chrome app in Developer mode on my browser and even drag my Chrome app specifically to a location in my Chrome browser. I don't understand how end users can just automatically use my Chrome app then.
I need to add here I have never really used jQuery, only AngularJS but AngularJS extensively. My AngularJS app is the frontend, the backend is provided by Rails.
Some advice would be really helpful. I hope I am not downvoted as it is strange how sometimes questions get downvoted and I am not sure why...I don't really know where else to go with this question.
EDIT:
Ok some code to demonstrate:
myangularapp.controller('myappcontroller', function($scope, $http) {
var delayvar = 5;
chrome.alarms.create("arandomalarm", {delay: delayvar});
};
This doesn't just work as part of my AngularJS, I tried creating a manifest.json file in the app/assets folder too. As well as a background.js file there and my-chrome-app.js file. "chrome.alarms" is undefined, but I haven't enabled Developer mode yet. But still, how are end users supposed to use it if just to make me use it I need to do so much specific browser configuration?
You should have a look at Content Scripts and then at Message Passing which explains you how to communicate between a web page and an Chrome extension.
its not possible to automatically install a chrome extension. the user must install it from the chrome store.
you may make it easier for them to install it by providing an inline installation from your webpage. its in the official documentation and you can see an example on this page with the "add to chrome" button:
http://plusfortrello.com (one of my chrome extensions which has inline installation inside that page).
that example button is further customized to display a message instead if the user is not on chrome desktop.
if your extension also has permission to your webpage then you can also detect from your webpage if the extension is already install it (to hide the button, send messages to it and such).

Categories

Resources