Size: 170
Comment:
|
Size: 16073
Comment:
|
Deletions are marked like this. | Additions are marked like this. |
Line 4: | Line 4: |
== Run chrome == {{{ "/C/Program Files (x86)/Google/Chrome/Application/chrome.exe" --disable-web-security --disable-gpu --user-data-dir="c:\TempChrome" --disable-features=SameSiteByDefaultCookies,SameSiteDefaultChecksMethodRigorously google-chrome --disable-web-security --disable-gpu --user-data-dir="/tmp" --disable-features=SameSiteByDefaultCookies,SameSiteDefaultChecksMethodRigorously }}} == Example app == * Requires Android SDK, node 12.16.2 and npm 6.14.5 {{{#!highlight bash cd ~ mkdir IonicTest npm install @ionic/cli node_modules/.bin/ionic start IonicTest #framework angular #starter template tabs #integrate capacitor N #create free ionic account N cd IonicTest npm i npm install @ionic/cli npm install cordova npm install cordova-res node_modules/.bin/ionic cordova plugin add cordova-plugin-advanced-http npm install @ionic-native/http node_modules/.bin/ionic cordova platform add android node_modules/.bin/ionic cordova build android scp ./platforms/android/app/build/outputs/apk/debug/app-debug.apk userx@example.net:/home/userx/www/ionic-test.apk node_modules/.bin/ionic cordova platform add browser node_modules/.bin/ionic cordova build browser node_modules/.bin/ionic serve --cordova --platform=browser # http://localhost:8100 # no CORS google-chrome --disable-web-security --disable-gpu --user-data-dir="/tmp" }}} === app.module.ts === {{{ import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { RouteReuseStrategy } from '@angular/router'; import { IonicModule, IonicRouteStrategy } from '@ionic/angular'; import { SplashScreen } from '@ionic-native/splash-screen/ngx'; import { StatusBar } from '@ionic-native/status-bar/ngx'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { HTTP } from '@ionic-native/http/ngx'; @NgModule({ declarations: [AppComponent], entryComponents: [], imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule], providers: [ HTTP, StatusBar, SplashScreen, { provide: RouteReuseStrategy, useClass: IonicRouteStrategy } ], bootstrap: [AppComponent] }) export class AppModule {} }}} === tab1.page.ts === {{{ import { Component } from '@angular/core'; import { HTTP } from '@ionic-native/http/ngx'; @Component({ selector: 'app-tab1', templateUrl: 'tab1.page.html', styleUrls: ['tab1.page.scss'] }) export class Tab1Page { public res; constructor(private http: HTTP) {} public ionViewDidEnter(){ console.log("Stuff"); this.http.get("https://labs.bitarus.allowed.org/xapps/rest/version/", {}, {}) .then(data => { console.log(data.status); console.log(data.data); // data received by server this.res=data.data; console.log(data.headers); }) .catch(error => { console.log(error.status); console.log(error.error); // error message as string console.log(error.headers); }); } } }}} === tab1.page.html === {{{ <ion-header [translucent]="true"> <ion-toolbar> <ion-title> Tab 111 {{res}} </ion-title> </ion-toolbar> </ion-header> <ion-content [fullscreen]="true"> <ion-header collapse="condense"> <ion-toolbar> <ion-title size="large">Tab 111</ion-title> </ion-toolbar> </ion-header> <app-explore-container name="Tab 111 page {{res}}"></app-explore-container> </ion-content> }}} === tab2.page.html === {{{ <ion-header [translucent]="true"> <ion-toolbar> <ion-title> Sum </ion-title> </ion-toolbar> </ion-header> <ion-content [fullscreen]="true"> <ion-header collapse="condense"> <ion-toolbar> <ion-title size="large">Sum</ion-title> </ion-toolbar> </ion-header> <ion-item> <ion-label>Value 1</ion-label> <ion-input [(ngModel)]="in1"></ion-input> </ion-item> <ion-item> <ion-label>Value 2</ion-label> <ion-input [(ngModel)]="in2"></ion-input> </ion-item> <ion-button color="primary" (click)="sumValuesButtonClicked()">Sum values</ion-button> </ion-content> }}} === tab2.page.ts === {{{ import { Component } from '@angular/core'; import { AlertController } from '@ionic/angular'; @Component({ selector: 'app-tab2', templateUrl: 'tab2.page.html', styleUrls: ['tab2.page.scss'] }) export class Tab2Page { in1:string; in2:string; constructor(public alertController: AlertController) {} sumValuesButtonClicked(){ let res:Number; res = parseInt(this.in1) + parseInt(this.in2); this.presentResult(res).then(()=>{ console.log("Done"); }); } async presentResult(res:Number) { const alert = await this.alertController.create({ header: 'Sum', subHeader: 'Result', message: res.toString(), buttons: ['OK'], }); await alert.present(); let result = await alert.onDidDismiss(); console.log(result); } } }}} === notifier.service.ts === {{{ import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class NotifierService { static readonly GOT_PUSH: 'GotPush'; private actions: string[]; private callbacks: Function[]; constructor() { this.actions = []; this.callbacks = []; } /** * Subscribe a callback to an action * @param action * @param callback */ public subscribe(action: string, callback: Function) { this.actions.push(action); this.callbacks.push(callback); } public notify(action: string) { let idx: number; idx = -1; for (idx = 0; idx < this.actions.length; idx++) { if (this.actions[idx] == action) { break; } } if (idx != -1) { this.callbacks[idx](); } } } }}} === tab3.page.ts === {{{ import { ChangeDetectorRef, Component } from '@angular/core'; import { DbService } from '../db.service'; import { NotifierService } from '../notifier.service'; @Component({ selector: 'app-tab3', templateUrl: 'tab3.page.html', styleUrls: ['tab3.page.scss'] }) export class Tab3Page { public items: string[]; constructor(private dbService: DbService, private notifier: NotifierService, private changeDetectionRef: ChangeDetectorRef ) { this.updateData(); this.notifier.subscribe(NotifierService.GOT_PUSH, this.gotPush.bind(this)); //setInterval(this.refresh.bind(this), 5000); } // private refresh() { // // triggers change detection when called by setInterval // } public gotPush() { try { this.updateData(); } catch (e) { alert("Caught error in gotPush"); } } public updateData() { this.dbService.getNotifications().then((data: string[]) => { this.items = data; this.changeDetectionRef.detectChanges(); }); } public ionViewDidEnter() { this.updateData(); } } }}} === db.service.ts === * ionic generate service db {{{ import { Injectable } from '@angular/core'; import { SQLite, SQLiteObject } from '@ionic-native/sqlite/ngx'; @Injectable({ providedIn: 'root' }) export class DbService { constructor(private sqlite: SQLite) { } private getDb(): Promise<SQLiteObject> { let async: Promise<SQLiteObject> = new Promise<SQLiteObject>((resolve, reject) => { let promise = this.sqlite.create({ name: 'data.db', location: 'default' }); promise.then((db: SQLiteObject) => { db.executeSql('CREATE TABLE IF NOT EXISTS PushNotificationsTable (push text)', []) .then(() => { resolve(db); }) .catch((e) => { reject('Table not created ' + JSON.stringify(e)); }); }); promise.catch(e => reject("Create db error " + JSON.stringify(e))); }); return async; } public insertPush(body: string) { this.getDb().then((db: SQLiteObject) => { if (db != null) { db.executeSql('INSERT INTO PushNotificationsTable VALUES (?)', [body]) .then(() => { }) .catch(e => alert("Insert error " + JSON.stringify(e))); } else { alert('insertPush: this.db is null'); } }); } public getNotifications(): Promise<string[]> { let asyncTask: Promise<string[]> = new Promise<string[]>((resolve, reject) => { this.getDb().then((db: SQLiteObject) => { if (db != null) { db.executeSql('SELECT * FROM PushNotificationsTable', []).then((data) => { let items: string[]; items = []; for (let i = 0; i < data.rows.length; i++) { let item = data.rows.item(i); items.push(item.push); } resolve(items); }).catch((e) => { reject(e); }); } else { alert('getNotifications: this.db is null'); reject('getNotifications: this.db is null'); } }); }); return asyncTask; } } }}} == EchoPlugin == * www/EchoPlugin.js {{{#!highlight javascript window.echo = function(str, callback) { cordova.exec(callback, function(err) { callback('Nothing to echo.'); }, "Echo", "echo", [str]); }; }}} * echo-plugin/plugin.xml {{{#!highlight xml <?xml version="1.0" encoding="UTF-8"?> <plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" id="org.allowed.bitarus.EchoPlugin" version="1.0.0"> <name>echo-plugin</name> <description>echo plugin</description> <license>null</license> <js-module src="www/EchoPlugin.js" name="EchoPlugin"> <clobbers target="EchoPlugin" /> </js-module> <platform name="android"> <config-file target="res/xml/config.xml" parent="/*"> <feature name="EchoPlugin" > <param name="android-package" value="org.allowed.bitarus.EchoPlugin"/> </feature> </config-file> <config-file target="AndroidManifest.xml" parent="/*"> <uses-permission android:name="android.permission.INTERNET" /> </config-file> <source-file src="src/main/java/org/allowed/bitarus/EchoPlugin.java" target-dir="src/org/allowed/bitarus" /> </platform> </plugin> }}} * echo-plugin/package.json {{{#!highlight javascript { "name": "org.allowed.bitarus.echoplugin", "version": "1.0.0", "description": "Echo plugin", "cordova": { "id": "org.allowed.bitarus.echoplugin", "platforms": [ "android" ] }, "keywords": [ "ecosystem:cordova", "cordova-android" ], "author": "Vitor", "license": "null" } }}} * echo-plugin/src/main/java/org/allowed/bitarus/EchoPlugin.java {{{#!highlight java package org.allowed.bitarus; import org.apache.cordova.CordovaPlugin; import org.apache.cordova.CallbackContext; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.apache.cordova.CordovaWebView; import org.apache.cordova.CordovaInterface; public class EchoPlugin extends CordovaPlugin { @Override public void initialize(CordovaInterface cordova, CordovaWebView webView) { super.initialize(cordova, webView); } @Override public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException { if (action.equals("echo")) { String message = "Echo " + args.getString(0) + " !!!"; this.echo(message, callbackContext); return true; } if (action.equals("getintentdata")) { this.getintentdata(callbackContext); return true; } return false; } private void echo(String message, CallbackContext callbackContext) { if (message != null && message.length() > 0) { callbackContext.success(message); } else { callbackContext.error("Expected one non-empty string argument."); } } private void getintentdata(CallbackContext callbackContext) { String data = this.cordova.getActivity().getIntent().getDataString() ; String action = this.cordova.getActivity().getIntent().getAction(); String result = String.format( "{\"data\":\"%s\" , \"action\":\"%s\"}",data,action ); callbackContext.success(result); } } }}} * tab1.page.ts {{{#!highlight javascript import { Component } from '@angular/core'; import { HTTP } from '@ionic-native/http/ngx'; import { Platform } from '@ionic/angular'; declare let cordova: any; @Component({ selector: 'app-tab1', templateUrl: 'tab1.page.html', styleUrls: ['tab1.page.scss'] }) export class Tab1Page { public res; public echo: string; constructor(private http: HTTP, private platform: Platform) { this.platform.ready().then(() => { this.init(); } ); } public init() { this.getEcho(); } getEcho() { if (this.platform.is('cordova')) { try { cordova.exec( (success) => { this.echo = success; }, (error) => { }, //feature name in /home/vitor/MyIonicProject/echo-plugin/plugin.xml //feature name in /home/vitor/MyIonicProject/platforms/android/app/src/main/res/xml/config.xml "EchoPlugin", // class Service name "echo", // action ["argxyz"] // arguments ); } catch (e) { this.echo = "Got error in get echo " + JSON.stringify(e) + e.message; } } } public ionViewDidEnter() { console.log("Stuff"); this.http.get("https://labs.bitarus.allowed.org/cebapps/r/core/version/", {}, {}) .then(data => { console.log(data.status); console.log(data.data); // data received by server this.res = data.data; console.log(data.headers); }) .catch(error => { console.log(error.status); console.log(error.error); // error message as string console.log(error.headers); }); } } }}} * tab1.page.html {{{#!highlight xml <ion-header [translucent]="true"> <ion-toolbar> <ion-title> Tab 111 {{res}} </ion-title> </ion-toolbar> </ion-header> <ion-content [fullscreen]="true"> <ion-header collapse="condense"> <ion-toolbar> <ion-title size="large">Tab 111</ion-title> </ion-toolbar> </ion-header> <app-explore-container name="Tab 111 page {{res}} {{echo}}"></app-explore-container> </ion-content> }}} == SQLite == * npm install @ionic-native/sqlite * node_modules/.bin/ionic cordova plugin add cordova-sqlite-storage * https://github.com/storesafe/cordova-sqlite-storage {{{ // app.module.ts import { SQLite } from '@ionic-native/sqlite/ngx'; providers SQLite // app.component.ts import { SQLite } from '@ionic-native/sqlite/ngx'; constructor private sqlite:SQLite }}} == Create service == * node_modules/.bin/ionic generate service notifier * Add in providers in app.module.ts * Inject in constructor of classes that might use the dependency/bean/service == Angular change detection == * https://www.mokkapps.de/blog/the-last-guide-for-angular-change-detection-you-will-ever-need/ {{{ In short, the framework will trigger a change detection if one of the following events occurs: any browser event (click, keyup, etc.) setInterval() and setTimeout() HTTP requests via XMLHttpRequest }}} * https://angular.io/api/core/ChangeDetectorRef {{{ constructor(private ref: ChangeDetectorRef) { //... this.ref.detectChanges(); }}} |
Ionic
Ionic Framework is an open source mobile UI toolkit for building high quality, cross-platform native and web app experiences.
Run chrome
"/C/Program Files (x86)/Google/Chrome/Application/chrome.exe" --disable-web-security --disable-gpu --user-data-dir="c:\TempChrome" --disable-features=SameSiteByDefaultCookies,SameSiteDefaultChecksMethodRigorously google-chrome --disable-web-security --disable-gpu --user-data-dir="/tmp" --disable-features=SameSiteByDefaultCookies,SameSiteDefaultChecksMethodRigorously
Example app
- Requires Android SDK, node 12.16.2 and npm 6.14.5
1 cd ~
2 mkdir IonicTest
3 npm install @ionic/cli
4 node_modules/.bin/ionic start IonicTest
5 #framework angular
6 #starter template tabs
7 #integrate capacitor N
8 #create free ionic account N
9 cd IonicTest
10 npm i
11 npm install @ionic/cli
12 npm install cordova
13 npm install cordova-res
14 node_modules/.bin/ionic cordova plugin add cordova-plugin-advanced-http
15 npm install @ionic-native/http
16 node_modules/.bin/ionic cordova platform add android
17 node_modules/.bin/ionic cordova build android
18 scp ./platforms/android/app/build/outputs/apk/debug/app-debug.apk userx@example.net:/home/userx/www/ionic-test.apk
19 node_modules/.bin/ionic cordova platform add browser
20 node_modules/.bin/ionic cordova build browser
21 node_modules/.bin/ionic serve --cordova --platform=browser
22 # http://localhost:8100
23 # no CORS
24 google-chrome --disable-web-security --disable-gpu --user-data-dir="/tmp"
app.module.ts
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { RouteReuseStrategy } from '@angular/router'; import { IonicModule, IonicRouteStrategy } from '@ionic/angular'; import { SplashScreen } from '@ionic-native/splash-screen/ngx'; import { StatusBar } from '@ionic-native/status-bar/ngx'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { HTTP } from '@ionic-native/http/ngx'; @NgModule({ declarations: [AppComponent], entryComponents: [], imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule], providers: [ HTTP, StatusBar, SplashScreen, { provide: RouteReuseStrategy, useClass: IonicRouteStrategy } ], bootstrap: [AppComponent] }) export class AppModule {}
tab1.page.ts
import { Component } from '@angular/core'; import { HTTP } from '@ionic-native/http/ngx'; @Component({ selector: 'app-tab1', templateUrl: 'tab1.page.html', styleUrls: ['tab1.page.scss'] }) export class Tab1Page { public res; constructor(private http: HTTP) {} public ionViewDidEnter(){ console.log("Stuff"); this.http.get("https://labs.bitarus.allowed.org/xapps/rest/version/", {}, {}) .then(data => { console.log(data.status); console.log(data.data); // data received by server this.res=data.data; console.log(data.headers); }) .catch(error => { console.log(error.status); console.log(error.error); // error message as string console.log(error.headers); }); } }
tab1.page.html
<ion-header [translucent]="true"> <ion-toolbar> <ion-title> Tab 111 {{res}} </ion-title> </ion-toolbar> </ion-header> <ion-content [fullscreen]="true"> <ion-header collapse="condense"> <ion-toolbar> <ion-title size="large">Tab 111</ion-title> </ion-toolbar> </ion-header> <app-explore-container name="Tab 111 page {{res}}"></app-explore-container> </ion-content>
tab2.page.html
<ion-header [translucent]="true"> <ion-toolbar> <ion-title> Sum </ion-title> </ion-toolbar> </ion-header> <ion-content [fullscreen]="true"> <ion-header collapse="condense"> <ion-toolbar> <ion-title size="large">Sum</ion-title> </ion-toolbar> </ion-header> <ion-item> <ion-label>Value 1</ion-label> <ion-input [(ngModel)]="in1"></ion-input> </ion-item> <ion-item> <ion-label>Value 2</ion-label> <ion-input [(ngModel)]="in2"></ion-input> </ion-item> <ion-button color="primary" (click)="sumValuesButtonClicked()">Sum values</ion-button> </ion-content>
tab2.page.ts
import { Component } from '@angular/core'; import { AlertController } from '@ionic/angular'; @Component({ selector: 'app-tab2', templateUrl: 'tab2.page.html', styleUrls: ['tab2.page.scss'] }) export class Tab2Page { in1:string; in2:string; constructor(public alertController: AlertController) {} sumValuesButtonClicked(){ let res:Number; res = parseInt(this.in1) + parseInt(this.in2); this.presentResult(res).then(()=>{ console.log("Done"); }); } async presentResult(res:Number) { const alert = await this.alertController.create({ header: 'Sum', subHeader: 'Result', message: res.toString(), buttons: ['OK'], }); await alert.present(); let result = await alert.onDidDismiss(); console.log(result); } }
notifier.service.ts
import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class NotifierService { static readonly GOT_PUSH: 'GotPush'; private actions: string[]; private callbacks: Function[]; constructor() { this.actions = []; this.callbacks = []; } /** * Subscribe a callback to an action * @param action * @param callback */ public subscribe(action: string, callback: Function) { this.actions.push(action); this.callbacks.push(callback); } public notify(action: string) { let idx: number; idx = -1; for (idx = 0; idx < this.actions.length; idx++) { if (this.actions[idx] == action) { break; } } if (idx != -1) { this.callbacks[idx](); } } }
tab3.page.ts
import { ChangeDetectorRef, Component } from '@angular/core'; import { DbService } from '../db.service'; import { NotifierService } from '../notifier.service'; @Component({ selector: 'app-tab3', templateUrl: 'tab3.page.html', styleUrls: ['tab3.page.scss'] }) export class Tab3Page { public items: string[]; constructor(private dbService: DbService, private notifier: NotifierService, private changeDetectionRef: ChangeDetectorRef ) { this.updateData(); this.notifier.subscribe(NotifierService.GOT_PUSH, this.gotPush.bind(this)); //setInterval(this.refresh.bind(this), 5000); } // private refresh() { // // triggers change detection when called by setInterval // } public gotPush() { try { this.updateData(); } catch (e) { alert("Caught error in gotPush"); } } public updateData() { this.dbService.getNotifications().then((data: string[]) => { this.items = data; this.changeDetectionRef.detectChanges(); }); } public ionViewDidEnter() { this.updateData(); } }
db.service.ts
- ionic generate service db
import { Injectable } from '@angular/core'; import { SQLite, SQLiteObject } from '@ionic-native/sqlite/ngx'; @Injectable({ providedIn: 'root' }) export class DbService { constructor(private sqlite: SQLite) { } private getDb(): Promise<SQLiteObject> { let async: Promise<SQLiteObject> = new Promise<SQLiteObject>((resolve, reject) => { let promise = this.sqlite.create({ name: 'data.db', location: 'default' }); promise.then((db: SQLiteObject) => { db.executeSql('CREATE TABLE IF NOT EXISTS PushNotificationsTable (push text)', []) .then(() => { resolve(db); }) .catch((e) => { reject('Table not created ' + JSON.stringify(e)); }); }); promise.catch(e => reject("Create db error " + JSON.stringify(e))); }); return async; } public insertPush(body: string) { this.getDb().then((db: SQLiteObject) => { if (db != null) { db.executeSql('INSERT INTO PushNotificationsTable VALUES (?)', [body]) .then(() => { }) .catch(e => alert("Insert error " + JSON.stringify(e))); } else { alert('insertPush: this.db is null'); } }); } public getNotifications(): Promise<string[]> { let asyncTask: Promise<string[]> = new Promise<string[]>((resolve, reject) => { this.getDb().then((db: SQLiteObject) => { if (db != null) { db.executeSql('SELECT * FROM PushNotificationsTable', []).then((data) => { let items: string[]; items = []; for (let i = 0; i < data.rows.length; i++) { let item = data.rows.item(i); items.push(item.push); } resolve(items); }).catch((e) => { reject(e); }); } else { alert('getNotifications: this.db is null'); reject('getNotifications: this.db is null'); } }); }); return asyncTask; } }
EchoPlugin
- www/EchoPlugin.js
- echo-plugin/plugin.xml
1 <?xml version="1.0" encoding="UTF-8"?>
2 <plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
3 id="org.allowed.bitarus.EchoPlugin"
4 version="1.0.0">
5 <name>echo-plugin</name>
6 <description>echo plugin</description>
7 <license>null</license>
8
9 <js-module src="www/EchoPlugin.js" name="EchoPlugin">
10 <clobbers target="EchoPlugin" />
11 </js-module>
12
13 <platform name="android">
14 <config-file target="res/xml/config.xml" parent="/*">
15 <feature name="EchoPlugin" >
16 <param name="android-package" value="org.allowed.bitarus.EchoPlugin"/>
17 </feature>
18 </config-file>
19 <config-file target="AndroidManifest.xml" parent="/*">
20 <uses-permission android:name="android.permission.INTERNET" />
21 </config-file>
22 <source-file src="src/main/java/org/allowed/bitarus/EchoPlugin.java" target-dir="src/org/allowed/bitarus" />
23 </platform>
24 </plugin>
- echo-plugin/package.json
1 {
2 "name": "org.allowed.bitarus.echoplugin",
3 "version": "1.0.0",
4 "description": "Echo plugin",
5 "cordova": {
6 "id": "org.allowed.bitarus.echoplugin",
7 "platforms": [
8 "android"
9 ]
10 },
11 "keywords": [
12 "ecosystem:cordova",
13 "cordova-android"
14 ],
15 "author": "Vitor",
16 "license": "null"
17 }
- echo-plugin/src/main/java/org/allowed/bitarus/EchoPlugin.java
1 package org.allowed.bitarus;
2
3 import org.apache.cordova.CordovaPlugin;
4 import org.apache.cordova.CallbackContext;
5 import org.json.JSONArray;
6 import org.json.JSONException;
7 import org.json.JSONObject;
8 import org.apache.cordova.CordovaWebView;
9 import org.apache.cordova.CordovaInterface;
10
11 public class EchoPlugin extends CordovaPlugin {
12 @Override
13 public void initialize(CordovaInterface cordova, CordovaWebView webView) {
14 super.initialize(cordova, webView);
15 }
16
17 @Override
18 public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
19 if (action.equals("echo")) {
20 String message = "Echo " + args.getString(0) + " !!!";
21 this.echo(message, callbackContext);
22 return true;
23 }
24
25 if (action.equals("getintentdata")) {
26 this.getintentdata(callbackContext);
27 return true;
28 }
29
30
31 return false;
32 }
33
34 private void echo(String message, CallbackContext callbackContext) {
35 if (message != null && message.length() > 0) {
36 callbackContext.success(message);
37 } else {
38 callbackContext.error("Expected one non-empty string argument.");
39 }
40 }
41
42 private void getintentdata(CallbackContext callbackContext) {
43 String data = this.cordova.getActivity().getIntent().getDataString() ;
44 String action = this.cordova.getActivity().getIntent().getAction();
45 String result = String.format( "{\"data\":\"%s\" , \"action\":\"%s\"}",data,action );
46 callbackContext.success(result);
47 }
48 }
- tab1.page.ts
1 import { Component } from '@angular/core';
2 import { HTTP } from '@ionic-native/http/ngx';
3 import { Platform } from '@ionic/angular';
4
5 declare let cordova: any;
6
7 @Component({
8 selector: 'app-tab1',
9 templateUrl: 'tab1.page.html',
10 styleUrls: ['tab1.page.scss']
11 })
12 export class Tab1Page {
13 public res;
14 public echo: string;
15
16 constructor(private http: HTTP, private platform: Platform) {
17
18 this.platform.ready().then(() => {
19 this.init();
20 }
21 );
22
23 }
24
25 public init() {
26 this.getEcho();
27 }
28
29 getEcho() {
30 if (this.platform.is('cordova')) {
31 try {
32 cordova.exec(
33 (success) => {
34 this.echo = success;
35 },
36 (error) => { },
37 //feature name in /home/vitor/MyIonicProject/echo-plugin/plugin.xml
38 //feature name in /home/vitor/MyIonicProject/platforms/android/app/src/main/res/xml/config.xml
39 "EchoPlugin", // class Service name
40 "echo", // action
41 ["argxyz"] // arguments
42 );
43 } catch (e) {
44 this.echo = "Got error in get echo " + JSON.stringify(e) + e.message;
45 }
46 }
47 }
48
49 public ionViewDidEnter() {
50 console.log("Stuff");
51 this.http.get("https://labs.bitarus.allowed.org/cebapps/r/core/version/", {}, {})
52 .then(data => {
53 console.log(data.status);
54 console.log(data.data); // data received by server
55 this.res = data.data;
56 console.log(data.headers);
57 })
58 .catch(error => {
59 console.log(error.status);
60 console.log(error.error); // error message as string
61 console.log(error.headers);
62 });
63 }
64 }
- tab1.page.html
1 <ion-header [translucent]="true">
2 <ion-toolbar>
3 <ion-title>
4 Tab 111 {{res}}
5 </ion-title>
6 </ion-toolbar>
7 </ion-header>
8 <ion-content [fullscreen]="true">
9 <ion-header collapse="condense">
10 <ion-toolbar>
11 <ion-title size="large">Tab 111</ion-title>
12 </ion-toolbar>
13 </ion-header>
14 <app-explore-container name="Tab 111 page {{res}} {{echo}}"></app-explore-container>
15 </ion-content>
SQLite
- npm install @ionic-native/sqlite
- node_modules/.bin/ionic cordova plugin add cordova-sqlite-storage
// app.module.ts import { SQLite } from '@ionic-native/sqlite/ngx'; providers SQLite // app.component.ts import { SQLite } from '@ionic-native/sqlite/ngx'; constructor private sqlite:SQLite
Create service
- node_modules/.bin/ionic generate service notifier
- Add in providers in app.module.ts
- Inject in constructor of classes that might use the dependency/bean/service
Angular change detection
In short, the framework will trigger a change detection if one of the following events occurs: any browser event (click, keyup, etc.) setInterval() and setTimeout() HTTP requests via XMLHttpRequest
constructor(private ref: ChangeDetectorRef) { //... this.ref.detectChanges();