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>
Related
My current setup is:
#capacitor/core: 3.0.0,
#ionic-native/core: 5.0.7
I'm trying to change the behavior of my app to not close the app, but go back in the navigation stack. To my knowledge, the hardware back button on Android devices did not automatically close the app until I upgraded Capacitor to 3.0.0
What is confusing me though, is how I have absolutely 0 code for handling the back button functionality, and from everything I'm searching online shows the back button doing nothing by default, not automatically closing the app as the default (as mine seems to be doing). I've searched all the project files for anything to do with "platform", "backButton", and "App.Exit" and was unable to find any code that may be causing the app to close.
I've tried subscribing to the back button press event using the below code and it is never ran. The app closes instead of showing the alert dialog. I've changed the priority from 0, 10, and 99 (all priorities listed in the Ionic documentation)
this.platform.backButton.subscribeWithPriority(10, () => {
alert('Back button pressed!');
});
Install capacitor app.
npm install #capacitor/app
Import it.
import { App as CapacitorApp } from '#capacitor/app';
Add back listener if can go back then we can push to back or exit the app.
CapacitorApp.addListener('backButton', ({canGoBack}) => {
if(!canGoBack){
CapacitorApp.exitApp();
} else {
window.history.back();
}
});
So, I feel a bit dumb after realizing this, but it is because I had to run the below commands, because I apparently didn't update them when upgrading Capacitor a while back. Make sure all of your plugins are fully updated, yours may be different than mine.
npm install #capacitor/app
npx cap sync
I had the same issue and I tried installing all the plugins like it says here
npm install #capacitor/app #capacitor/haptics #capacitor/keyboard #capacitor/status-bar
After I finished installing, I still got the error. Also my PushNotifications plugin was not working either.
My problem was I forgot to delete the OnCreate method from MainActivity.java. So if you still have the problem after installing the plugins, try to delete OnCreate method so your MainActivity.java looks like this:
public class MainActivity extends BridgeActivity {}
See more here.
It also fixed my PushNotifications plugin.
If I understand it correctly, if you have any plugin that is not registered correctly, it will cause this kind of error. This answer also helped me.
https://stackoverflow.com/a/69084017/19086322
This post work really good for me !!
Before this post i made these commands and after it worked:
npm install #capacitor/app
npx cap sync
I have the same issue and adding #capacitor/app to my App worked for debugging puposes. The Problem is, when I build a release app, it still closes the app.
--- EDIT ---
I fixed the issue by building a completely new Ionic App (with the latest versions of everything) and then copying my code.
I assume it really had something to do with the installed versions of the Ionic and Capacitor packages
You need to use below code to handle the Hardware back button in Ionic app:
//back button handle
//Registration of push in Android and Windows Phone
let lastTimeBackPress: number = 0;
let timePeriodToExit: number = 2000;
platform.registerBackButtonAction(() => {
//Double check to exit app
if (new Date().getTime() - lastTimeBackPress < timePeriodToExit) {
//this.platform.exitApp(); //Exit from app
this.appMinimize.minimize().then(() => {
console.log('minimized successfully');
});
} else {
this.toastCtrl.create({
message: this.translate.instant('EXIT_APP_MESSAGE'),
duration: 3000,
position: 'bottom'
}).present();
lastTimeBackPress = new Date().getTime();
}
});
for android:
import android.webkit.WebView;
import com.getcapacitor.BridgeActivity;
public class MainActivity extends BridgeActivity {
//in my case I call it the JS function when I press the back button
#Override
public void onBackPressed() {
WebView webView = getBridge().getWebView();
webView.loadUrl("javascript:pressBack()");
// in Index.html create tag
//<script type="text/javascript">
// function pressBack(){
// alert('yes!!')
// }
//</script>
return;
}
}
Im creating an app and I need to keep working in background but this doesnt work.
Im using:
https://github.com/katzer/cordova-plugin-background-mode
I am on Visual studio with ionic , so I execute:
ionic cordova run android
The app is launched and working. The first view is a Login, I fill the login and this take me to the second view (thit is a tab page).
On this page I add:
import { BackgroundMode } from '#ionic-native/background-mode/ngx';
constructor(private background: BackgroundMode){
this.background.enable();
console.log(this.background.isEnable());
console.log(this.background.isActive());
this.background.moveToBackground();
}
Also, console.log shows that is enable, but not active (that is normal).
The problem is that when I move the app to the background, is “restarted” . I mean that when I open the app from the background it takes me again to the first view where I should do the Login. So this is not working.
This image appears all the times that I open the app for background, and after this, the app is restarted
Am I doing something wrong? Is visual studio?** How can I solve it?**
Thanks!
Use plugin Background Mode
ionic cordova plugin add cordova-plugin-background-mode
npm install #ionic-native/background-mode
Then use it like this:
import { BackgroundMode } from '#ionic-native/background-mode/ngx';
export class AppComponent {
constructor(private backgroundMode: BackgroundMode) {
this.initializeApp();
}
initializeApp() {
this.platform.ready().then(() => {
this.backgroundMode.enable();
});
}
}
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');
}
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 have a weird problem. I recently developed an App for ios using Phonegap and Xcode. It went well, they are in the App store, everything worked. One of the elements is a simple email form, written in HTML. It looks like this:
<form name="emailformbtn" id="emailformbtn" onsubmit="submitHandler(e);" action="#emailfromBtn">
To: <input type="email" name="emailvarto"/>
Message:<textarea cols="40" rows="8" id="emailmessagebtn" name="emailmessage">Email Message</textarea>
<input type="button" value="send" onsubmit="submitHandler(e);" onclick="emailProcessfromBtn();"/>
</form>
Works in ios using Phonegap and Jquery mobile. So i decided to convert the app into Android. Converting all the ObjectiveC into Java, and the rest should work because they are both Phonegap/Cordova.
I am Using Cordova 2.0 and Android 4.1
A lot of it does, but when I try to touch the input of the emails field, it does nothing, and Eclipse displays the message:
The View is not attached to a window.
Its a Phonegap/Cordova element. I'm not even sure what its trying to say. Is there an issue with Android and Jquery mobile, or does touching input fields in Android using phonegap not invoke native Keyboards?
Any direction or advice on this problem would be greatly appreciated.
Just to make things clearer, even though I followed Phonegap's configuration guide tot he letter, Here is the contents of the Activity.java file:
package uk.co.testdevelopment.testapp.droidapp;
import android.os.Bundle;
import android.view.Menu;
import org.apache.cordova.*;
public class MainActivity extends DroidGap {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.loadUrl("file:///android_asset/www/index.html");
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
Are you sure your activity is extending 'DroidGap' and not 'Activity'? This definitely sounds wierd and looks more like a problem of the cordova configuration than anything to do with your html
The issue appears to be with the menu that you specified that you're calling inflate on. With ICS and higher, the menu is created when the app is first run and not when the menu is accessed. I would recommend removing your menu code to get rid of the View error.
BTW: Views have to be attached to a root element of an Android View, which is normally handled by DroidGap. DroidGap also has menu handlers as well, and you may want to look at using a Menu Plugin or using the CordovaWebView approach to developing a Hybrid App for Android 4.x.