I am very new to Ionic and Cordova, for the last couple of days I am trying to download an image that I have upload in firebase storage. I want to transfer the image and store it in my mobile device through my mobile application. I have installed all the plugins needed to do that. I have created two buttons. The first button is to display the image in my application and the second button is to download the image in my device. The source code for that is in my storage.html
<ion-header>
<ion-navbar>
<ion-title>storage</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<button ion-button (click)="display()">Display</button>
<button ion-button (click)="download()">Download</button>
<img src="{{imgsource}}">
</ion-content>
The functionality is in my storage.ts
import { Component, NgZone } from '#angular/core';
import { NavController, Platform, AlertController } from 'ionic-angular';
//import {File,Transfer} from 'ionic-native';
import {FileTransferObject } from '#ionic-native/file-transfer';
import {TransferObject} from '#ionic-native/transfer';
import {Transfer} from '#ionic-native/transfer';
import {File} from '#ionic-native/file';
import firebase from 'firebase';
declare var cordova: any;
#Component({
selector: 'storage-home',
templateUrl: 'storage.html',
providers: [Transfer, TransferObject, File]
})
export class StoragePage {
storageDirectory: string = '';
fileTransfer: FileTransferObject;
nativepath: any;
firestore = firebase.storage();
imgsource: any;
constructor(public navCtrl: NavController, public platform: Platform, public alertCtrl: AlertController, public zone: NgZone) {
this.platform.ready().then(() => {
// make sure this is on a device, not an emulation (e.g. chrome tools device mode)
if(!this.platform.is('cordova')) {
return false;
}
if (this.platform.is('ios')) {
this.storageDirectory = cordova.file.documentsDirectory;
}
else if(this.platform.is('android')) {
this.storageDirectory = cordova.file.dataDirectory;
}
else {
// exit otherwise, but you could add further types here e.g. Windows
return false;
}
});
}
display() {
this.firestore.ref().child('image.jpg').getDownloadURL().then((url) => {
this.zone.run(() => {
this.imgsource = url;
this.fileTransfer.download(url,'image.jpg').then((entry) => {
console.log('download complete: ' + entry.toURL());
}, (error) => {
// handle error
});
})
})
}
downlad() {
this.firestore.ref().child('image.jpg').getDownloadURL().then((url) => {
this.zone.run(() => {
this.imgsource = url;
this.fileTransfer.download(url,cordova.file.dataDirectory +'image.jpg').then((entry) => {
console.log('download complete: ' + entry.toURL());
}, (error) => {
// handle error
});
})
})
}
}
The display button works perfectly as I can see my image when I install the application on my device. The problem though is with the download button as nothing is happening and I don’t know if it’s working as I can’t find my image anywhere in my device. Can anyone please guide me?
Thanks in regards
It looks like you may have a typo on your download function name. In the HTML module you refer to download() and in your code your function is labeled as downlad.
Related
I'm working on ionic 4 application. when the user signs In, I added a checkbox to asks for Remember me, so the next time the user open the app it doesn't show the login page and directly forward the user to Home page. I have google and found this. However, while using the accepted solution, I encountered an issue, which it shows the login page for 2 or 3 seconds, then open the Home page. How I can safely achieve it without delay?
app.component.ts
import { SmsVerificationService } from 'src/app/services/SMS/sms-verification.service';
import { Component } from '#angular/core';
import { Platform } from '#ionic/angular';
import { SplashScreen } from '#ionic-native/splash-screen/ngx';
import { StatusBar } from '#ionic-native/status-bar/ngx';
import { FCM } from '#ionic-native/fcm/ngx';
import { Plugins, Capacitor } from '#capacitor/core';
import { Router } from '#angular/router';
import { Storage } from '#ionic/storage';
#Component({
selector: 'app-root',
templateUrl: 'app.component.html'
})
export class AppComponent {
constructor(
private platform: Platform,
private splashScreen: SplashScreen,
private statusBar: StatusBar,
private fcm: FCM,
private route: Router,
private storage: Storage
) {
this.initializeApp();
}
initializeApp() {
this.platform.ready().then(() => {
this.fcm.getToken().then(token => {
console.log(' token is ', token);
});
this.fcm.onTokenRefresh().subscribe(token => {
console.log('on token refresh ', token);
});
this.fcm.onNotification().subscribe(data => {
console.log(data);
if (data.wasTapped) {
console.log('Received in background');
// this.router.navigate([data.landing_page, data.price]);
} else {
console.log('Received in foreground');
// this.router.navigate([data.landing_page, data.price]);
}
});
this.storage.get('isLogined').then(data => {
if (data)
this.route.navigateByUrl('/main-tab');
})
this.statusBar.styleDefault();
this.splashScreen.hide();
if (Capacitor.isPluginAvailable('SplashScreen')) {
Plugins.SplashScreen.hide();
}
});
}
}
The codes that are supposed to change the page
this.storage.get('isLogined').then(data => {
if (data)
this.route.navigateByUrl('/main-tab');
})
Do you have a separate login component? If so, you can create and add a guard to your login component to navigate to your main page when Remember me was checked.
I have been trying to insert a share button for a post in my app that is able to use the default apps installed in the android phone and can not seem to find a way through.
This is how my post.ts file looks like
import { Component } from '#angular/core';
import { NavParams, NavController, AlertController } from 'ionic-angular';
.
.
import { SocialSharing } from '#ionic-native/social-sharing';
/**
* Generated class for the PostPage page.
*/
#Component({
selector: 'page-post',
templateUrl: 'post.html'
})
export class PostPage {
post: any;
user: string;
comments: Array<any> = new Array<any>();
categories: Array<any> = new Array<any>();
morePagesAvailable: boolean = true;
constructor(
public navParams: NavParams,
public navCtrl: NavController,
public alertCtrl: AlertController,
private socialSharing: SocialSharing
) {
}
ionViewWillEnter(){
this.morePagesAvailable = true;
this.post = this.navParams.get('item');
Observable.forkJoin(
this.getAuthorData(),
this.getCategories(),
this.getComments())
.subscribe(data => {
this.user = data[0].name;
this.categories = data[1];
this.comments = data[2];
});
}
getAuthorData(){
return this.wordpressService.getAuthor(this.post.author);
}
getCategories(){
return this.wordpressService.getPostCategories(this.post);
}
getComments(){
return this.wordpressService.getComments(this.post.id);
}
loadMoreComments(infiniteScroll) {
let page = (this.comments.length/10) + 1;
this.wordpressService.getComments(this.post.id, page)
.subscribe(data => {
for(let item of data){
this.comments.push(item);
}
infiniteScroll.complete();
}, err => {
console.log(err);
this.morePagesAvailable = false;
})
}
goToCategoryPosts(categoryId, categoryTitle){
this.navCtrl.push(HomePage, {
id: categoryId,
title: categoryTitle
})
}
// Social sharing function is here
sharePost() {
this.socialSharing.share("Post Excerpt", "Post Title", "Post Image URL", "Post URL")
.then(() => {
console.log("sharePost: Success");
}).catch(() => {
console.error("sharePost: failed");
});
}
}
Problem
How do insert the post title, post url post image (REST API - JSON) into this.socialSharing.share("Post Excerpt", "Post Title", "Post Image URL", "Post URL")
so that the share button can look more like this
<button ion-fab class="btn share" mini (click)="sharePost()"></button>
EDIT
I have managed to make it work using
sharePost() {
this.socialSharing.share(this.post.excerpt.rendered, this.post.title.rendered, this.post.images.large, this.post.link)
.then(() => {
console.log("sharePost: Success");
}).catch(() => {
console.error("sharePost: failed");
});
}
However when i share like using gmail, the html special characters display
e.g title shows: catering & Cleaning Services
Excerpt shows: <p>Some text[…]</p>
How do i get rid of those html characters and just show some clean text.?
Thank you
One way i removed html tag from my wordpress post was to create a pipe and i pass the excerpt through the pipe before it gets rendered to the view
Pipe.ts was like so
import { Pipe, PipeTransform } from '#angular/core';
/**
* Generated class for the RemovehtmltagsPipe pipe.
*
* See https://angular.io/api/core/Pipe for more info on Angular Pipes.
*/
#Pipe({
name: 'RemovehtmltagsPipe',
})
export class RemovehtmltagsPipe implements PipeTransform {
/**
* Takes a value and makes it lowercase.
*/
transform(value: string) {
if (value) {
let result = value.replace(/<\/?[^>]+>/gi, "");
return result;
}
else {
}
}
}
Then i added the pipe as export in my component's module.ts
details.module.ts was like so
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '#angular/core';
import { IonicPageModule } from 'ionic-angular';
import { DetailsPage } from './details';
import { RemovehtmltagsPipe } from
'../../pipes/removehtmltags/removehtmltags';
#NgModule({
declarations: [
DetailsPage,
],
imports: [
IonicPageModule.forChild(DetailsPage),
],
exports: [RemovehtmltagsPipe],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class DetailsPageModule {}
Finally used the pipe inside my html code
details.html
<ion-row class="white-bg" padding>
<ion-col>
<h1 class="title">{{article.title.rendered | RemovehtmltagsPipe}}</h1>
<p class="date">Published: {{article.modified.split('T')[0]}} {{article.modified.split('T')[1]}}</p>
</ion-col>
</ion-row>
This should get rid of any html tags in your post.Hope this helps
I have used #ionic-native/printer plugin to implement printing option for bill report.
I have installed plugin using this command line:
npm install --save #ionic-native/printer
Then in the viewbill.html I put a line to active the printer :
<button ion-button (click)="print()">
<ion-icon name="print">
</ion-icon>
Print
</button>
Then my viewbill.ts code:
import { Component } from '#angular/core';
import { IonicPage, NavController, NavParams, Platform, AlertController } from 'ionic-angular';
import { Printer, PrintOptions } from '#ionic-native/printer';
#IonicPage()
#Component({
selector: 'page-viewbill',
templateUrl: 'viewbill.html',
})
export class ViewbillPage {
public srNo = [];
public particulars = [];
public particularAmt = [];
constructor(public navCtrl: NavController,
public navParams: NavParams,
public printer: Printer,
public platform: Platform,
public alertCtrl: AlertController) {
}
ionViewDidLoad() {
console.log('ionViewDidLoad ViewbillPage');
this.srNo = [
{no: '1'},
{no: '2'},
{no: '3'}
];
this.particulars = [
{particular: 'Particular 1'},
{particular: 'Particular 2'},
{particular: 'Particular 3'}
];
this.particularAmt = [
{amount: '100'},
{amount: '500'},
{amount: '1000'}
];
}
print(){
if(this.platform.is('cordova')){
if(this.printer.isAvailable())
{
let options: PrintOptions = {
name: 'Bill Report',
duplex: true,
landscape: true,
grayscale: true
};
var page = document.getElementById('billReport');
this.printer.print(page, options);
}
else{
this.alert('Please connect your device to a printer!');
}
}
else{
this.alert('You are on a web browser!');
}
}
alert(message: string) {
this.alertCtrl.create({
title: 'Info!',
subTitle: message,
buttons: ['OK']
}).present();
}
}
Whenever I click on a print button, nothing happens!
Did anyone have this kind of troubles with the plugin ? Did I do something wrong ? Should I install other things to fix the problem ? And did anyone have a exemple project working well ?
Thank you very much !
You seem to have missed the step of installing the codrova plugin:
ionic cordova plugin add de.appplant.cordova.plugin.printer
The ionic native package is a wrapper for the above plugin. Check docs here
I am building an ionic app for wallpapers.
In the app,there is an image stored in www/assets/img displayed.I have build 2 buttons below,for downloading and retrieving the displayed image to the mobile device memory.
When i click download button,a dialog is shown,saying "Download Succeeded!Pug.jpg was successfully downloaded to: filepath".But when i check the phone memory no such file is there.Also when i click "Retrieve"Button it's showing dialog saying"File retrieval succeed!Pug.jpg was successfully retrieved from: filepath""even though file is not present in the phone memory.
This is home.ts code
import {Component} from '#angular/core';
import {NavController, Platform, AlertController} from 'ionic-angular';
import {Transfer, TransferObject} from '#ionic-native/transfer';
import {File} from '#ionic-native/file';
declare var cordova: any;
#Component({
selector: 'page-home',
templateUrl: 'home.html',
providers: [Transfer, TransferObject, File]
})
export class HomePage {
storageDirectory: string = '';
constructor(public navCtrl: NavController, public platform: Platform, private transfer: Transfer, private file: File, public alertCtrl: AlertController) {
this.platform.ready().then(() => {
// make sure this is on a device, not an emulation (e.g. chrome tools device mode)
if(!this.platform.is('cordova')) {
return false;
}
if (this.platform.is('ios')) {
this.storageDirectory = cordova.file.documentsDirectory;
}
else if(this.platform.is('android')) {
this.storageDirectory = cordova.file.dataDirectory;
}
else {
// exit otherwise, but you could add further types here e.g. Windows
return false;
}
});
}
downloadImage(image) {
this.platform.ready().then(() => {
const fileTransfer: TransferObject = this.transfer.create();
const imageLocation = `${cordova.file.applicationDirectory}www/assets/img/${image}`;
fileTransfer.download(imageLocation, this.storageDirectory + image).then((entry) => {
const alertSuccess = this.alertCtrl.create({
title: `Download Succeeded!`,
subTitle: `${image} was successfully downloaded to: ${entry.toURL()}`,
buttons: ['Ok']
});
alertSuccess.present();
}, (error) => {
const alertFailure = this.alertCtrl.create({
title: `Download Failed!`,
subTitle: `${image} was not successfully downloaded. Error code: ${error.code}`,
buttons: ['Ok']
});
alertFailure.present();
});
});
}
retrieveImage(image) {
this.file.checkFile(this.storageDirectory, image)
.then(() => {
const alertSuccess = this.alertCtrl.create({
title: `File retrieval Succeeded!`,
subTitle: `${image} was successfully retrieved from: ${this.storageDirectory}`,
buttons: ['Ok']
});
return alertSuccess.present();
})
.catch((err) => {
const alertFailure = this.alertCtrl.create({
title: `File retrieval Failed!`,
subTitle: `${image} was not successfully retrieved. Error Code: ${err.code}`,
buttons: ['Ok']
});
return alertFailure.present();
});
}
}
This is home.html code
<ion-header>
<ion-navbar>
<ion-title>
File Transfer Example
</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<ion-card>
<ion-card-header>
Ionic 3 File Transfer Example
</ion-card-header>
<ion-card-content>
<img src="assets/img/pug.jpg" alt="Cute Pug">
<button ion-button (click)="downloadImage('pug.jpg')" color="secondary">Download image</button>
<button ion-button (click)="retrieveImage('pug.jpg')" color="secondary">Retrieve downloaded image</button>
</ion-card-content>
</ion-card>
</ion-content>
I build this ionic app based on this Github code example
I actually want the ionic app to first create a folder(app named folder) in internal memory and put all images there.So users can access files in that folder.For example,if app name is "Appsample" then all images should be in Appsample folder in internal memory.
How can i develop for above purpose?
Thanks.
I just posted an answer to nearly the same question, see:
Download not working using filetransfer plugin.
The main problem here is that you are using the following directory to save your file:
else if(this.platform.is('android')) {
this.storageDirectory = cordova.file.dataDirectory;
}
As stated in the cordova docs (https://cordova.apache.org/docs/en/latest/reference/cordova-plugin-file/#where-to-store-files), "cordova.file.dataDirectory" is the persistent and private data storage within the application's sandbox using internal memory.
Use cordova.file.externalDataDirectory to fit your purpose. Then the file should be placed somewhere here: "file:///storage/emulated/0/Android/data/subdomain.domainname.toplevdomain/files/...".
On Android, external storage directories always exist. If the device doesn't have a physical card, Android will emulate it.
You can use this way, it's working file
Capacitor
npm install cordova-plugin-whitelist
npx cap sync
Cordova
npm install cordova-plugin-whitelist
npx cap update
download() {
const url = 'http://www.example.com/file.pdf';
fileTransfer.download(url, this.file.dataDirectory + 'file.pdf').then((entry) => {
console.log('download complete: ' + entry.toURL());
}, (error) => {
// handle error
});
}
I Have the same issue when i wrote my download code it worked but i couldn't see the file on my phone
1. Write download method
2. Write Permission method, Call Permission method
3. Call download method inside Permission, the phone will pop up and ask for permission for file read if it has not been set.
4. After download you might not be able to see where the file is on phone, you will now use photoViewer to view it on phone if it is
image or use document viewer if it is pdf or other document related.
The plugins needed
private transfer: FileTransfer,
private fileTransfer: FileTransferObject,
private file: File,
private androidPermissions: AndroidPermissions,
private photoViewer: PhotoViewer,
getPermission() {
// get permission from device to save
this.androidPermissions.checkPermission(this.androidPermissions.PERMISSION.READ_EXTERNAL_STORAGE).then(
result =>//,
err => this.androidPermissions.requestPermission(this.androidPermissions.PERMISSION.READ_EXTERNAL_STORAGE)
);
// get permission from device to save
this.androidPermissions.hasPermission(this.androidPermissions.PERMISSION.WRITE_EXTERNAL_STORAGE)
.then(status => {
if (status.hasPermission) {
this.download('k');
}
else {
this.androidPermissions.requestPermission(this.androidPermissions.PERMISSION.WRITE_EXTERNAL_STORAGE)
.then(status => {
if (status.hasPermission) {
this.download('');
}
});
}
});
}
public download() {
let url = encodeURI(this.imgUrl);
var imagePath = this.file.dataDirectory + "myDP.png";
const fileTransfer = this.transfer.create();
fileTransfer.download(url, imagePath).then((entry) => {
this.generalProvider.showToast('download completed: ' + imagePath);
this.photoViewer.show(entry.toURL());
}, (error) => {
});
}
this is my code :
import { Component } from '#angular/core';
import { NavController } from 'ionic-angular';
import { FileOpener } from 'ionic-native';
#Component({
selector: 'page-installHelper',
templateUrl: 'installHelper.html'
})
export class InstallHelper {
constructor(public navCtrl: NavController) {
FileOpener.open('assets/app.apk', 'application/vnd.android.package-archive').then(
function(){
console.log("success");
}, function(err){
console.log("status : "+err.status);
console.log("error : "+err.message);
});
}
}
but I can't access the file app.apk which is in assets/app.apk
and I get the error :
Status : 9
Error : File Not Found
is it even possible to access a file within the app folders ?
Well I did it by making the app get downloaded from a server to a local folder I created in the phone and install it immediately/automatically,
Here is the code in case someone else needed it one day :
import { Component } from '#angular/core';
import { Platform, LoadingController } from 'ionic-angular';
import { StatusBar, Splashscreen } from 'ionic-native';
import { FileOpener } from 'ionic-native';
import { File } from 'ionic-native';
import { Transfer } from 'ionic-native';
import { HomePage } from '../pages/home/home';
declare var cordova: any;
#Component({
template: `<ion-nav [root]="rootPage"></ion-nav>`
})
export class MyApp {
rootPage = HomePage;
constructor(platform: Platform, public loadingCtrl: LoadingController) {
let me = this;
platform.ready().then(() => {
let loading = me.loadingCtrl.create({
content: 'Preparing The App ...'
});
loading.present();
File.createDir(cordova.file.externalDataDirectory, "appFolder", true).then(function(link){
const fileTransfer = new Transfer();
let url = 'http://yourserverhere.com/app.apk';
fileTransfer.download(url, cordova.file.externalDataDirectory +"appFolder/app.apk").then((entry) => {
loading.dismiss();
FileOpener.open(entry.toURL(), "application/vnd.android.package-archive").then(
function(){
console.log("success");
},function(err){
console.log("status : "+err.status);
console.log("error : "+err.message);
});
}, (error) => {
console.log(error);
});
},function(error){
console.log(error);
});
StatusBar.styleDefault();
Splashscreen.hide();
});
}
}
Any explanation just ask me.
Well since you want the user to download the .apk file, you could use (in your html)
<a href="assets/app.apk" download>Download apk</a>
But the user will have to manually open his downloads (or tap the popup) to install your app.
I do not know if there is a plugin which is capable of installing these apk files. (Googling for ionic 2 install external apk didn't return any results).