Part 07

ikona aplikácie, kontakty, notifikácie

Oznamy

  • (slide) cvičenia v utorky o 0730 nebudú

  • (slide) darovanie krvy

  • (slide) zadanie

    • spísané požiadavky (o ktorých som tu pravidelne hovoril)
  • (slide) bakalárky

    • o analýze

Overview

  • (slide)

  • content providers

    • kontakty
    • kalendár
  • ako sa k nim dostať?

  • spravíme appku, ktorá nás včas upozorní na to, kto má v najbližšej dobe sviatok

Accessing Contacts

  • plugin cordova-plugin-contacts - executes asynchronously, querying the device contacts database and returning an array of Contact objects

  • instalacia:

    cordova plugin install cordova-plugin-contacts
  • ma niekolko metod:

    • navigator.contacts.create
    • navigator.contacts.find
    • navigator.contacts.pickContact
  • nás však bude zaujímať len vyhľadávanie

Searching in Contacts

  • (slide)

  • funkcia find() má niekoľko parametrov:

    • contactFields - Contact fields to use as a search qualifier. (DOMString[]) [Required]

    • contactSuccess - Success callback function invoked with the array of Contact objects returned from the database. [Required]

    • contactError - Error callback function, invoked when an error occurs. [Optional]

    • contactFindOptions - Search options to filter navigator.contacts. [Optional]

    • Keys include:

      • filter - The search string used to find navigator.contacts. (DOMString) (Default: ““)
      • multiple - Determines if the find operation returns multiple navigator.contacts. (Boolean) (Default: false)
      • desiredFields - Contact fields to be returned back. If specified, the resulting Contact object only features values for these fields. (DOMString[]) [Optional]
      • hasPhoneNumber(Android only) - Filters the search to only return contacts with a phone number informed. (Boolean) (Default: false)
  • Poďme hľadať. Začneme len s povinnými vecami - callbackom onSuccess() a filtrom na všetko:

    function onSuccess(contacts) {
        console.log(`Contacts found: ${contacts.length}`);
        console.log(contacts);
    };
    
    navigator.contacts.find(["*"], onSuccess);
  • V tomto prípade sme vlastne ani nič nehľadali - proste vrátil všetky kontakty.

  • Tentokrát nastavme ešte aj options. Aby sme ich však mohli použiť, potrebujeme aj callback funkciu pre chybu onError():

    function onError(error) {
        alert(error);
    };
    
    var options = new ContactFindOptions();
    options.multiple = true;
    options.desiredFields = [navigator.contacts.fieldType.id];
  • Tentokrá vo výsledku neuvidíme všetky hodnoty, ale len id. To je kvôli filtru na desiredFields, teda vo výsledku sa budú nachádzať len tieto položky. Ukázať si to teda môžeme aj na viacerých položkách - pridáme displayName a birthday:

    var options = new ContactFindOptions();
    options.multiple = true;
    options.desiredFields = [
        navigator.contacts.fieldType.id,
        navigator.contacts.fieldType.displayName,
        navigator.contacts.fieldType.birthday
    ];
  • Vyhľadávanie však funguje len ako full-text-search. Nevieme sa teda veľmi opýtať, či sa tam nachádza nejaká hodnota alebo hodnota v rozsahu. Na toto si musíme urobiť vlastné ošetrenie:

    var options = new ContactFindOptions();
    options.filter = "Luis";
    options.multiple = true;
    options.desiredFields = [
        navigator.contacts.fieldType.id,
        navigator.contacts.fieldType.displayName,
        navigator.contacts.fieldType.birthday
    ];
  • Potrebujeme vyhľadávať nad hodnotou atribútu birthday - teda či je nastavený a potom aj to, či je v uvedenom rozsahu. Použijeme teda metódu .filter() nad poľom, ktorá nám vráti nový zoznam obsahujúci len tie prvky, ktoré vyhovujú vyhľadávacím kritériám:

    const filtered = contacts.filter(contact => contact.birthday);

Birthday in 10 Days

  • Vytvoríme funkciu getDaysToBirtday(), ktorá dostane ako parameter objekt typu Date a vráti počet dní do najbližších narodenín od dnešného dňa. Jej implementácia môže vyzerať napr. takto:

    function getDaysToBirthday(date) {
       let today = new Date();
       let next = new Date();
       next.setUTCDate(date.getUTCDate());
       next.setUTCMonth(date.getUTCMonth());
       if (next.getUTCMonth() < today.getUTCMonth()) {
           next.setUTCFullYear(next.getUTCFullYear() + 1);
       } else if (next.getUTCMonth() == today.getUTCMonth()) {
           if (next.getUTCDate() < today.getUTCDate()) {
            next.setUTCFullYear(next.getUTCFullYear() + 1);
           }
       }
       let diff = next.getTime() - today.getTime();
       return diff / 1000 / 60 / 60 / 24;
    }
  • Od toho už máme pomerne blízko k úprave nášho kódu tak, aby nám vrátil zoznam tých kontaktov, ktoré majú uvedený dátum narodenia a počet dní do najbližších narodenín je menší ako 10:

    onDeviceReady: function() {
        navigator.contacts.find(
            ["*"],
            function(contacts) {
                const filtered = contacts.filter(function(contact) {
                    return (
                        contact.birthday &&
                        getDaysToBirthday(contact.birthday) < 10
                    );
                });
    
                console.log(filtered);
            },
            function(err) {
                console.error(err.message);
            }
        );
    }

Notifications

  • (slide) Nastal čas, aby sme upozornili na to, že niekto má narodeniny do 10 dní od dnes. Vhodným spôsobom môže byť použitie notifikácií. Za týmto účelom nainštalujeme plugin cordova-plugin-local-notifications: cordova plugin add

  • (slide) Notification components:

    • Header area
    • Content area
    • Action area
  • (slide) How notifications may be noticed:

    • Showing a status bar icon
    • Appearing on the lock screen
    • Playing a sound or vibrating
    • Peeking onto the current screen
    • Blinking the device’s LED
  • takze zacnime s jednoduchou ukazkou priamo zo stranky:

    cordova.plugins.notification.local.schedule({
        title: 'My first notification',
        text: 'Thats pretty easy...',
        foreground: true
    });
  • a teraz to naviazme na zoznam ludi, ktori maju narodeniny (aj s ich obrazkom, ak ho maju):

    filtered.forEach((contact, idx) => {
        cordova.plugins.notification.local.schedule({
            title: "We have a Birthday!",
            text: `${
                contact.displayName
            } has a birthday in ${getDaysToBirthday(
                contact.birthday
            )} days`,
            foreground: true,
            attachments: [contact.photos[0].value]
        });
    });

Application Icon

  • vytvoriť parádnejšiu ikonu

  • https://romannurik.github.io/AndroidAssetStudio/

Running Once a Day

  • service - beh na pozadí

  • naplánovať spustenie raz za deň