I do not want links to open inside my Ionic app, so I'm trying to get the links to open in the mobile browser.
The first example here is working fine. When the URL is inside of the "window.open" command, then the external browser is launched as expected.
<p class="descriptive-class">
<a ng-href="" onclick="window.open('https://stackoverflow.com', '_system', 'location=yes')">
<img src="assets/img/awesome_picture.png" alt="blablabla">
</a>
</p>
The problem lays with this part, where I want to feed a parameter for the URL to the code. I cannot set it directly inside "window.open()", so I have to move it to 'ng-href' and then refer to it via 'this.href'.
Android does not seem to understand this correctly. It shows me the "Complete action using" dialog on Android, and then presents HTML document handler applications. It does not understand the browser link.
How can this be corrected best?
<p class="descriptive-class">
<a href="#" ng-href="item.webURL" onclick="window.open(this.href, '_system', 'location=yes')">
{{ item.webURL }}
</a>
</p>
In this case, the easiest way is to install the In App Browser plugin.
It opens an URL with the installed browser of the device. First add and install the plugin:
*$ ionic cordova plugin add cordova-plugin-inappbrowser*
*$ npm install --save #ionic-native/in-app-browser*
Add it to your app.module.ts
import { InAppBrowser } from '#ionic-native/in-app-browser';
And add it to your providers:
#NgModule({
...
providers: [
...
InAppBrowser
...
]
...
})
Then add on the relevant page:
constructor(private iab: InAppBrowser) { }
openBrowser(){
this.iab.create('https://ionicframework.com/');
}
Call openBrowser() in your (click) method and you're set!
See also: https://ionicframework.com/docs/native/in-app-browser/
As of Feb 2020, this is what works in Ionic 4 & Ionic 5:
1) Install In App Browser plugin. Don't worry, it will open the links externally as you want it. Run the following commands in your project root:
ionic cordova plugin add cordova-plugin-inappbrowser
npm install #ionic-native/in-app-browser
2) In app.module.ts file, add the following code:
Add the import as shown below:
import { InAppBrowser } from '#ionic-native/in-app-browser/ngx';
Add support for InAppBrowser by adding it to the providers array as shown below:
providers: [
StatusBar,
SplashScreen,
InAppBrowser, // ---> Add it here
{provide: RouteReuseStrategy, useClass: IonicRouteStrategy}
],
3) In your desired component TS file or page TS file (example: support.page.ts), add the following code:
Add the import as shown below:
import { InAppBrowser } from '#ionic-native/in-app-browser/ngx';
Add the code in constructor as shown below:
constructor(private iab: InAppBrowser) {}
Add a method that opens the link to your desired webpage as shown below:
openPage(){
this.iab.create('https://stackoverflow.com/'); // --> Change URL here
}
Add click event to your hyperlink as shown below:
{{ item.webURL }}
Result:
Now when you click on the Hyperlink, that should open your desired URL.
NOTE:
If you do not want to hardcode the URL and would rather want to open URLs dynamically, then you can use the following in your HTML page:
{{ item.webURL }}
Add the following in your TS file:
openAnyPage(url){
this.iab.create(url);
}
Result:
Now when you click on any Hyperlink, that should open your desired URL, without the need to hardcode them anywhere.
An update to #Gerben den Boer's answer:
You will run into errors like the following with the import as it is listed.
[ng] ERROR in src/app/components/app-component/app.module.ts(44,5): error TS2322: Type 'InAppBrowserOriginal' is not assignable to type 'Provider'.
[ng] Type 'InAppBrowserOriginal' is not assignable to type 'ClassProvider'.
[ng] Property 'provide' is missing in type 'InAppBrowserOriginal'.
To resolve this use the following import:
import { InAppBrowser } from '#ionic-native/in-app-browser/ngx';
See: https://github.com/ionic-team/ionic-native/issues/2899
Further to #Devner's excellent answer, for a 2021+ (Ionic5) release,
You should do all of the above, but 2 things needed to change for me.
I had multiple variables to pass to it, that suggestion didn't work, but I did overcome the problem with the following:
Open original article.
Also, please note the following that was left off, according to the Cordova Documentation...
A target should be included:
var ref = cordova.InAppBrowser.open(url, target, options);
ref: Reference to the InAppBrowser window when the target is set to '_blank'. (InAppBrowser)
url: The URL to load (String). Call encodeURI() on this if the URL contains Unicode characters.
target: The target in which to load the URL, an optional parameter that defaults to _self. (String)
_system: Opens in the system's web browser.
Therefore, the following code brings it altogether:
openAnyPage(url, wp_id)
{
this.iab.create(url+"index.php?page_id="+wp_id, '_system');
}
Related
I load a webpage via the inappbrowser plugin for my Phonegap app.
The app shows a website and a webshop which are both accessible from the web as well.
I cannot add a button 'go back to app' (this wouldn't make sense when visiting the site from PC). So I want a custom navigation (I prefer bootstrap) in the phonegap app so I can navigate between multiple different websites.
Unfortunately the navigation gets hidden by the inappbrowser. Is there a way to show the app html navigation on top of the inappbrowser?
Thanks a lot!
adding absolute position, z-index 999999 and display block with css didn't help
One way you do could this is inject the button into your webpage by generating it in your Cordova app Webview:
var inAppBrowserRef = cordova.InAppBrowser.open("http://www.mypage.com", "_blank");
inAppBrowserRef.addEventListener('loadstop', function(e) {
inAppBrowserRef.executeScript({
code: '\
var body = document.querySelector("body");\
var button = document.createElement("div");\
button.innerHTML = "Return to app";\
button.classList.add("close_button");\
button.onclick = function() {\
webkit.messageHandlers.cordova_iab.postMessage(JSON.stringify({action: "closeIAB"}));\
};\
body.appendChild(button);\
'
});
});
You'd then add a listener for the message that's posted when the button is click which closes the inappbrowser:
inAppBrowserRef.addEventListener("message", function (params){
if(params.data.action === "closeIAB"){
inAppBrowserRef.close();
}
});
You could also inject the styling of the button from within your Cordova app:
inAppBrowserRef.insertCSS({
"code": "\
.close_button {\
position: fixed;\
bottom: 0;\
z-index: 500;\
width: 100%;\
background: white;\
color: black;\
padding: 10px;\
font-size: 20px;\
}"
});
Or if you prefer, add the button styling to the CSS in your webpage (if it's under your control).
Similarly, if you don't like the idea of creating the button HTML dynamically, you could include it as part of your webpage but hide it by default unless a particular class is injected by the app:
inAppBrowserRef.addEventListener('loadstop', function(e) {
inAppBrowserRef.executeScript({
code: '\
var body = document.querySelector("body");\
body.classList.add("is_app");\
'
});
});
And in your website CSS:
body:not(.is_app) .close_button{
display: none;
}
Note that the emulation of the postMessage API that has been added to cordova-plugin-inappbrowser for Android & iOS by this PR is not yet in the latest release version on npm (v3.0.0) so you'll need to install the plugin directly off the Github master branch (v3.1.0-dev):
cordova plugin add https://github.com/apache/cordova-plugin-inappbrowser
I did this long time ago another way. The in app browser opened a website with a additional GET parameter, so the website knows it's opened inside the app. Then in the website I generated a special button, with href containing a custom scheme and some command. (E.g. myapp://close-browser)
Then I configured the app to capture the custom url by using regular app scheme configuration. Once I captured the command in javascript, I closed the in app browser using it's API.
I'm developing a hybrid app using Ionic 4. Ionic just like other html5 based apps runs as a webview in MainActivity. using capacitor I've imported my app to android studio and I've created a SecondActivity. How can I go to SecondActivity by clicking a button inside first activity(MainActivity) (which is an Ioninc page and for sure an html webview).
So far i've tried different method to achieve this but no luck.
I've created a cordova plugin following this tutorial:
Start android activity from cordova plugin
it works prefect in cordova application but I was not successful to import it into Ionic.
also I've tried Capacitor and apparently accessing native code using capacitor should be very easy but unfortunately I've had no luck so far.
https://capacitor.ionicframework.com/docs/plugins/android
after struggling a lot! here is the answer:
the plugin that I mentioned actually works cool in cordova and to bring it to ionic4 (as the clobbers of plugin is "PluginName", you have to declare and use it in your typescript)my code is as follows (home.page.ts):
import { Component } from '#angular/core';
declare var PluginName: any;
#Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
})
export class HomePage {
goToCustomActivity(){
PluginName.new_activity();
}
}
and in your home.page.html:
<ion-content>
<ion-button (click)="goToCustomActivity()">go to custom activity</ion-
button>
</ion-content>
I hope this help someOne.
and special thanks to original coder of plugin "Ijas Ahamed N"
you can find instructions to write plugin here:
https://www.ijasnahamed.in/2016/11/start-android-activity-from-cordova.html
and here is the stackoverflow (be aware! step to create package.json is omitted in stackoverflow!)
Start android activity from cordova plugin
You can do it by taking use of WebView.addJavaInterface. Just write a Android class in Java (to launch a the Activity you want), and inject the object into WebView context by calling WebView.addJavaInterface(). When the HTML button is clicked, you call the injected JS method to launch the Activity.
The Activity Launcher:
class MyJsInterface {
#JavascriptInterface
public String launchActivity() {
// ...;
}
}
Inject it:
webview.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new MyJsInterface(), "AndroidInterface");
webView.loadUrl(...);
In your web page:
<button onclick="AndroidInterface.launchActivity()">Launche Activity</button>
Hello I have built my website, was looking forward to have an app for my responsive website... I went with android webviews but it posed problems with opening filechooser... So I went with Cordova after doing a lot of research. I succeeded in creating a Cordova application an imported it to Android studio. My problem is, when my landing page opens clicking any other link opens the default browser... I don't want this behavior I want all links to open within the app(Using Cordova's webviews)...thanks in advance.
NOTE:Am using Cardova to open a completely remote website no local stuff.
My MainActivity.java look like this
package com.noel.myapp;
import android.os.Bundle;
import org.apache.cordova.*;
public class MainActivity extends CordovaActivity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Set by <content src="index.html" /> in config.xml
loadUrl("http://www.mywebsite.com");
}
}
The inAppBrowser adds an additional address bar at the top. Instead if you just want in app navigation you can use this solution (borrowed from comment section of this answer)
Add this line in your config.xml file
<allow-navigation href="*://*.example.com/*" />
and inside your index.js add something like this
receivedEvent: function(id) {
// other code
window.location = "https://www.example.com
}
(Although this being an old thread sharing anyways if someone else comes across this)
use cordova-plugin-inappbrowser for that
cordova docs for inappbrowser is here.
after device is ready (deviceready event)
use
var ref = cordova.InAppBrowser.open('http://apache.org', '_blank', 'location=yes');
after adding the plugin.
basic example is here
I was working through the Ionic tutorial for using the Cordova Camera API.
http://learn.ionicframework.com/formulas/cordova-camera/
Far as I can tell everything is working correctly with the Camera API functions, but I cannot get my image to display back into the view.
I am able to return a file URI, but when I attempt to put it to the ng-src I get nothing in the view. I am assuming that the application/code cannot access the file location?
My config:
.config(function($stateProvider, $urlRouterProvider, $compileProvider) {
$compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|ftp|file|blob|content):|data:image\//);
...
The function in my controller:
$scope.getPhoto = function() {
Camera.getPicture().then(function(imageURI) {
console.log(imageURI);
$scope.cameraPic = imageURI;
}, function(err) {
$scope.cameraPic = "error";
console.err(err);
});
};
My view:
<ion-view>
<ion-content>
<div class="form-group padding-top">
<button class='button button-positive' data-ng-click="getPhoto()">
Take Photo
</button>
</div>
<div class="item item-image">
<img ng-src="{{cameraPic}}"/>
</div>
{{cameraPic}}
</ion-content>
</ion-view>
This appears to be the recommended method by the tutorial, and is also repeated on this thread. It sounds like it should work without using a Cordova file service implementation. I have found one such implementation which I guess I could use, but am I missing something here?
EDIT
Using chrome://inspect/#devices, I was able to look into the Webview/Console. I also rebuilt the project, just to see if that would help.
Definitely looking like a local file access issue.
As it turns out, this is an issue unique to using the emulator. I finally found the following on the ngCordova project:
NOTE: The camera API only works on a real device, and not in the
emulator.
Source: http://ngcordova.com/docs/plugins/camera/
This led me to test the code on an actual device using the USB debugger, where the file is accessed by the application and shared with the view as expected. This should be noted as a quirk of the library.
I am using AngularJS with Trigger.io to develop a mobile application for both iOS and Android.
When I try to open a link that looks like this:
<a ng-href="#/offers/{{featured_offer.Id}}"></a>
It works perfectly fine on iOS, but on Android I get this message in the trigger console, and the link is not navigated to:
[WARNING] Attempted to open a URL which could not be handled: unsafe:content://io.trigger.forge722b6464a0e211e2ba9d12313d00dc45/src/index.html#/offers/8
How can I get this to work in Android the same as it works in iOS?
Looks like Angular adds unsafe: to url schemes it doesn't recognise, I think you want to include something like:
app.config(function($compileProvider){
$compileProvider.urlSanitizationWhitelist(/^\s*(https?|ftp|mailto|file|tel|content):/);
});
Which adds content: to the accepted url schemes.
I had this same problem, specifically with trying to display an img with a src of a file returned by forge.file.getImage. Angular adds unsafe: to the content: prefix of the local img URL, and as connorhd said, you need to add content: to the url whitelist.
Note that compileProvider's API has changed with recent versions of Angular, so I'm commenting here in case anyone else finds an updated version of this workaround useful.
app.config(['$compileProvider',
function($compileProvider) {
$compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|ftp|mailto|file|tel|content|blob):|data:image|/);
// note: you'll also have to do imgSrcSanitizationWhitelist if you want to use general links as well as ng-src on images.
}]);
I too had this problem just add sanitizer in you config.xml
var app = angular.module( 'myApp', [] )
.config( [
'$compileProvider',
function( $compileProvider )
{
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|chrome-extension):/);
// Angular before v1.2 uses $compileProvider.urlSanitizationWhitelist(...)
}
]);