Es mostren els missatges amb l'etiqueta de comentaris android. Mostrar tots els missatges
Es mostren els missatges amb l'etiqueta de comentaris android. Mostrar tots els missatges

dilluns, 19 de juny del 2017

Ionic 2, using LoadingController

Sometimes our app it has that some realize tasks what need much time or we don't know the amount of time needed for receive data of the server, or for upload/download an image, file, etc... Normally these task works in background for not keep busy the main thread as this would block the app. The app is running normally but the user can have the sensation that somethings don't works correctly, the screen now is blank, it is waiting for data but the user does not know. For solve it and say to the user that the app is working and waiting data or waiting for the current task finished we can use the LoadingController for show a dialog box with a message to let the user know who the app is working normally.

Here you can read more about these controller. We can customize according our needs, we might dismiss it after a period of time but in my case I don't know when will finish the task.

For that I divide the process in three parts. First declare a variable of type Loading, second I create a function where creates the dialog  and assign them to the Loading variable and show the dialog. And finally when the promise finishes your task, I dismiss the dialog.


First import the components

import { NavController, NavParams, LoadingController, Loading } from 'ionic-angular';

We declare the variable that contains the dialog

loading: Loading;

The function to create and present the dialog

presentLoading () { this.loading = this.loadingCtrl.create({ content: "Waiting data ..." }); this.loading.present(); }


And use it

constructor(public navCtrl: NavController, public navParams: NavParams, public httpService: HttpService, public loadingCtrl: LoadingController) { this.source = navParams.get("src"); this.options = navParams.get("ops"); this.presentLoading(); this.httpService.getData(this.source, this.ops) .then((result:any) => { this.data = result; this.loading.dismiss(); }); }

Obviously is necessary to consider the possible exceptions, the catch clauses where  dismiss the loading dialog and show a message with the problem.

And that's all

dilluns, 12 de juny del 2017

Ionic 2. Checking permissions

Following with what was discussed in the last entry in Android since Marshmallow is necessary to check at run time the permissions cataloged how to dangerous and read or write in the external storage is one of them. In the case at hand, for restore the backup, as the app writes in the sandbox it isn't necessary to check the permissions. 

For check the permissions, we use the diagnostic plugin and we will use the same plugin for check permissions for access to location, sensors, phone, contacts, etc... but in this entry I only will write over the access to the external storage.

Well, first we install the plugin

   ionic plugin add cordova.plugins.diagnostic


And

   npm install --save @ionic-native/diagnostic


And we create a service to manage all the permissions

   ionic g provider PermissionsService

And we edit ../providers/permissions-service.ts and write

import { Injectable } from '@angular/core'; import { Platform } from 'ionic-angular'; import 'rxjs/add/operator/map'; import { Diagnostic } from '@ionic-native/diagnostic'; /* Generated class for the PermissionsService provider. See https://angular.io/docs/ts/latest/guide/dependency-injection.html for more info on providers and Angular 2 DI. */ @Injectable() export class PermissionsService { constructor(public platform: Platform, public diagnostic: Diagnostic) { }
isAndroid() { return this.platform.is('android'); }
checkWritePermission(): Promise<boolean> return new Promise (resolve => if (this.isAndroid) { this.diagnostic.isExternalStorageAuthorized() .then(authorized => { if(authorized) { resolve(true); } else { this.diagnostic.requestExternalStorageAuthorization() .then(authorization => { resolve (authorization == this.diagnostic.permissionStatus.GRANTED); }); } }); } }); } }

And we use it

createBackup () { if (this.permissions.isAndroid()) {< this.permissions.checkWritePermission().then(permission => { this.backup(); }, error => { console.log(error); }); } }

And the result looks like this



dilluns, 29 de maig del 2017

Ionic 2. Backup stories part I

When I started this blog, the idea was to practice my English with the hope to improve it, I'm self taught and I think that it is a good way to do it. Normally I write about what I'm doing, and this time is how to do a backup in my app developed with Ionic 2. The point is all of my apps don't use any server to store data, they not ask for special permissions, only the internet access for serve ads and in this case in Android, permission for write in the external storage for save the backup. But this is the second question of this story, so let's start at the beginning.

My app stores the data in a database SQLite and it to do in two tables. The amount of data is not very large and I don't need any more. My first idea was to create a method  that makes a query of all the data and store it in a file in JSON format. Create the backup is really easy and restore it not too complicated. I looked in the Ionic documentation and it provides a File API in Ionic Native for read and write files. Here you can find more info about this.  Well, it seems that I already have all of I need so let's install it.

From a terminal inside the project directory

   ionic plugin add cordova-plugin-file


And
   npm install --save @ionic-native/file




And add the plugin in the app.module.ts. First import it and then we put it on the providers section

import { File } from '@ionic-native/file';

providers: [{provide: ErrorHandler, useClass: IonicErrorHandler}, DbService, File, AdMob]

Well, it is ready to use.

But reading the documentation of the plugin I see which it have methods to check, delete and copy files. And I have thought SQLite stores the data in a file so for make a backup I only need copy this file and store it in another directory that finally is the same that should I do with the result of the query. Ok, it's already decided. I will copy the file in a directory accessible to the user.

Now the first step is find the file.  In my database service, I have wrote

openDatabase() { return this.db.openDatabase({ name: 'eDomestic.db', location: 'default', createFromLocation: 1 }) .catch(error => console.error('Error opening database', error)); }


But where is location: default. Well, in Android it is in /data/data/your-app/databases/ or using the plugin File.applicationStorageDirectory + 'databases/'. In iOS it is in /var/mobile/Applications/<UUID>/Library/LocalDatabase/  or using the plugin File.applicationStorageDirectory + 'Library/LocalDatabase/.

First we need to know what system we are using Android or iOS, for that

if (/(android)/i.test(navigator.userAgent)) { this.AndroidDir = this.file.externalRootDirectory; } else if (/(ipod|iphone|ipad)/i.test(navigator.userAgent)) { this.iOSDir = this.file.documentsDirectory; }

AndroidDir and iOSDir contains the destination for the backup. For the origin path

if (this.iOSDir.length > 1) { destPath = this.iOSDir; path = this.file.applicationStorageDirectory + 'Library/LocalDatabase/'; this.translate.get('IOSDOCUMENTSDIRECTORY') .subscribe(value => { dirMessage = value; }); } else { destPath = this.AndroidDir; path = this.file.applicationStorageDirectory + 'databases/'; this.translate.get('ANDROIDDOCUMENTSDIRECTORY') .subscribe(value => { dirMessage = value; }); }

Here, depending of what OS we are using we select a destination and origin or another. And now we can use the plugin for copy the file. But where save the file and why?

In the next entry I will continue explain the as and the why I do it like that.