dijous, 27 d’abril del 2017

eDomestic

eDomestic, the app to help you in your domestic expenses control task.

With this app you can create shopping list and so avoid the compulsive shopping. Create your list and follow it in your purchase, ticking in the list what we already have in the basket. 

Choose the expense by category
   - Shopping basket
   - Clothes
   - Phone
   - Electricity
   - Fuel
   - Maintenance
   - Transport
   - Hairdressing, ...
   - Healt
   - Entertainment
   - Taxes
   - Rentals

and annotate the expense with a description if you want.

Query the movements by month and category or check the history.



dilluns, 24 d’abril del 2017

Ionic 2, publishing your app. Android

Finally the app development has finished and it is time to publish it. Here you can find more documentation about the process.

If we have run the command ionic platform add android inside the project directory we can find a platforms directory. In platforms/android/build/outputs/apk we will find the result of this process.

First, we edit the config.xml file and modify  the id and version attribute in the widget tag, and the tags name, description and author. Then we run the command in a terminal inside our project directory.

   ionic build --release --prod android

If appears an error with this message

   Error: No Java files found that extend CordovaActivity

Then for solve it we run

   ionic platform rm android
   ionic platform add android

And now we run the first command again. If all the process it will well a BUILD SUCCESSFULL message appears and the route to the apk file.

   platforms/android/build/outputs/apk/android-release-unsigned.apk

Now we can sign the apk file. For that we need a private key, I assume you already have one if it is not so, you will have to create one using keytool.

   keytool -genkey -v -keystore your-release-key.keystore -alias 
          your_alias_name -keyalg RSA -keysize 2048 -validity 10000

The next step is run jarsigner to sign the apk

   jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 
             -keystore your-release-key.keystore 
             android-release-unsigned.apk your_alias_name

And finally the last step is optimize the apk using the zipalign tool.  The tool can be find in /path/to/Android/sdk/build-tools/VERSION/zipalign. In my case using OS X, I run 

   ~/Library/Android/sdk/build-tools/25.0.2/zipalign
             -v 4 android-release-unsigned.apk myApp.apk

And now, our app is ready to be published in Google Play. And remember, every time that the app is updated, you have to modify the config.xml file and update the version attribute before creating the apk.

dijous, 13 d’abril del 2017

Ionic 2, ads with AdMob

Well, our app development is nearing to completion and maybe we want monetize it. An option is to use Google AdMob to serve ads, and it's very easy in Ionic 2. Here you can find the official documentation.

The first step is install the plugin, from a terminal, inside your project run

   ionic plugin add cordova-plugin-admobpro

And to add the ionic native AdMob module run

   npm install --save @ionic-native/admob

And we already have everything we need, as it is assumed to we have an AdMob app ID.
First edit the src/app/app.module.ts, import the plugin and add it in the providers section


   import { NgModule, ErrorHandler } from '@angular/core';
   import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
   import { Http } from '@angular/http';
   import { TranslateModule, TranslateLoader, TranslateStaticLoader } 
                                    from 'ng2-translate/ng2-translate'
   import { MyApp } from './app.component';

   import { AdMob} from '@ionic-native/admob';

   export function createTranslateLoader(http: Http) {
      return new TranslateStaticLoader(http, 'assets/i18n', '.json');
   }

   @NgModule({
      declarations: [
         MyApp
      ],
   imports: [
      IonicModule.forRoot(MyApp)
      TranslateModule.forRoot({
         provide: TranslateLoader,
         useFactory: (createTranslateLoader),
         deps: [Http]
      })
     ],
   bootstrap: [IonicApp],
   entryComponents: [
      MyApp
   ],
   providers: [{provide: ErrorHandler, useClass: IonicErrorHandler},
              AdMob]
   })
   export class AppModule {}
 

The next step is edit the src/app/app.component.ts and first import the plugin, configure the AdMob, create the banner and show it.

   import { Component } from '@angular/core';
   import { Platform } from 'ionic-angular';
   import { StatusBar, Splashscreen } from 'ionic-native';
  
   import { TabsPage } from '../pages/tabs/tabs';


   import { AdMob } from '@ionic-native/admob';

   interface AdMobType {
      banner: string
   };

   @Component({
      templateUrl: 'app.html'
   })
   export class MyApp {
      rootPage = TabsPage;

      constructor(platform: Platform, private admob: AdMob) {
         platform.ready().then(() => {

            StatusBar.styleDefault();
            Splashscreen.hide();

            // AdMob settings
           var adMobID: AdMobType;
           if (/(android)/i.test(navigator.userAgent)) {
              adMobID = {
                 banner: 'ca-app-pub-android/id'
              };
           } else if (/(ipod|iphone|ipad)/i.test(navigator.userAgent)) {
              adMobID = {
                 banner: 'ca-app-pub-iOS/id'
              };        
           } else {
              adMobID = {
                 banner: 'ca-app-pub-Windows/id'
              };        
           }

           if (this.admob) {
              this.admob.createBanner({
                 adId: adMobID.banner,
                 isTesting: true,
                 position: this.admob.AD_POSITION.BOTTOM_CENTER,
                 autoShow: true
              });
           }
         });
      }
   }

When the app are ready to release, in createBanner comment isTesting property or set it to false. For the banner position, if you want set it to top, change the position property to AD_POSITION.TOP_CENTER.

Finally the app looks like


dilluns, 10 d’abril del 2017

Ionic 2, Splash Screen and Icon

In my opinion this is the more tedious task at time of develop an app, the icon and the splash screen. But this is the first thing who user see when uses the app and this is important. For make it more tedious, numerous icons and different sizes are needed for iOS and Android. Here you can find more info, in this entry I will only explain the more easy form to solve this.

For help us  in this task the Ionic CLI provides a command

   ionic resources

This command makes all we need, but it needs some  things for make your work. In the /resources directory inside your project you encounter two files, the icon.png for the Icon and splash.png for the Splash Screen. Also contains a directory for each platform iOS and Android in my case. We will works whit this two files, the directories will be contain the diferent files who we need.

We will can edit the files with our prefered app. I use Gimp and Inkscape but you can uses which you want, whenever you respect the formats and the sizes, 2208x2208 in the splash.png and 1024x1024 for the icon.png and should have no rounded corners. The formats can be .png, .psd and .ai

Well, that's all. When we are finished the Icon and the Splash Screen  we just need run the command from a terminal inside the project directory and it will make all the files we need.


dilluns, 3 d’abril del 2017

Ionic 2, localizing with NG2-translate

It's time to localize your app, for this in Ionic 2 you can use the NG2-translate library. Here you can find more info.
The first step is to install the library, for this in a terminal into your project directory run

   npm install ng2-translate --save

Next it must be imported in the NgModule of the app and added to the imports array. The code in the app.module.ts file  would be like this


   import { NgModule, ErrorHandler } from '@angular/core';
   import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular';
   import { Http } from '@angular/http'; 
   import { TranslateModule, 
            TranslateLoader, 
            TranslateStaticLoader } from 'ng2-translate/ng2-translate'

   export function createTranslateLoader(http: Http) {
      return new TranslateStaticLoader(http, 'assets/i18n', '.json');
   }

   @NgModule({
      declarations: [
         MyApp
      ],
      imports: [
         IonicModule.forRoot(MyApp),
         TranslateModule.forRoot({
            provide: TranslateLoader,
            useFactory: (createTranslateLoader),
            deps: [Http]
         })
      ],
      bootstrap: [IonicApp],
      entryComponents: [
         MyApp
      ],
      providers: [{provide: ErrorHandler, useClass: IonicErrorHandler}]
   })
   export class AppModule {}

The function createTranslateLoader(http: Http) change the default location of the json translation files. By default it is in i18n/ and for Ionic 2 must be change to src/assets and we added it in the imports array. How createTranslateLoader(http: Http) uses Http we import it from @angular/http.

Now in the src/assets/i18n directory we create a file for each language what we want translate en.json, ca.json, fr.json, es.json, etc...

The json file for catalan looks like

   {
    "TAXES": "Impostos",
    "JANUARY": "Gener",
    "FEBRUARY": "Febrer",
    "MARCH": "Març",
    "APRIL": "Abril",
    "MAY": "Maig",
    "JUNE": "Juny",
    "JULY": "Juliol",
    "AUGUST": "Agost",
    "SEPTEMBER": "Setembre",
    "OCTOBER": "Octubre",
    "NOVEMBER": "Novembre",
    "DECEMBER": "Desembre"
   }

For use in the template we use the TranslaterPipe as follows

   <ion-label>{{ 'TAXES' | translate }}</ion-label>

For change the current language and translate values in the application we use TranslateService. First import it and set the default language, next change the language to the user language.


   
   import { Component } from '@angular/core';

   import { NavController} from 'ionic-angular';
   import { TranslateService } from 'ng2-translate';

   @Component({
      selector: 'page-home',
      templateUrl: 'home.html'
   })

   export class HomePage {
      items: string[];

      userLang: string = navigator.language.split('-')[0];

      constructor(public navCtrl: NavController, 
                  public translate: TranslateService) {

         this.translate.setDefaultLang('en');
         this.translate.use(this.userLang);

         this.translate.get(["JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY",
                            "JUNE", "JULY", "AUGUST", "SEPTEMBER", "OCTOBER",
                            "NOVEMBER", "DECEMBER"])
                       .subscribe(months => {
                    
                          this.items = [months.JANUARY, months.FEBRUARY, 
                                        months.MARCH, months.APRIL, 
                                        months.MAY, months.JUNE, 
                                        months.JULY, months.AUGUST,
                                        months.SEPTEMBER, months.OCTOBER,
                                        months.NOVEMBER, months.DECEMBER];
                       });     

      }
   }

The TranslateService provides a get, it take the string that need translate form the assets, subscribe to the observable and return the translate string.

And now we can use in the template, in this case loading the months in a button using a ngFor loop
  

   <ion-list inset>
      <button ion-item *ngFor="let item of items" 
                          (click)="itemSelected(item)">
         {{ item }}
      <button>
   </ion-list>

And the result looks like this