Su uno smartphone Android è possibile avere la rubrica dei contatti e dei calendari con gli eventi senza passare per i servizi Google? Sembra di sì, anche se è tutt'altro che semplice!
In pratica è necessario installare un server che fornisca il servizio tramite i protocolli DAV, nel nostro caso abbiamo utilizzato DAViCal su Debian. Sul terminale Android si deve installare un client opportuno, la nostra scelta è caduta su DAVdroid. Infine è necessario adottare diversi accorgimenti per poter esportare i calendari e i contatti esistenti e verificare che la sincronizzazione col server remoto avvenga correttamente.
In Debian 9 Stretch esiste il pacchetto DAViCal versione 1.1.5, per convenienza esiste anche il backport della versione 1.1.7, che abbiamo preferito. Per soddisfare le dipendenze è necessario prendere dai backports anche il pacchetto libawl-php versione 0.59.
È necessario un database di supporto, nel nostro caso abbiamo utilizzato PostgreSQL. La procedura di installazione è abbastanza sui generis, in quanto richiede che venga predisposto l'accesso al database senza password (per fortuna è possibile revocarlo al termine dell'installazione). Vedere gli appunti nel paragrafo Installazione del server DAViCal.
In Apache 2.4 abbiamo definito un VirtualHost solo su HTTPS. Chi fa accesso usando HTTP viene rediretto per evitare che trasmetta password in chiaro sulla rete. Questa la configurazione da aggiungere:
<Directory /usr/share/davical/htdocs> DirectoryIndex index.php AllowOverride None Require all granted </Directory> <VirtualHost *:80> ServerName dav.server.org DocumentRoot /var/www/html/default # Redirect everything to https, except /.well-known/ directory. RedirectMatch permanent ^/((?!\.well-known).*)$ https://dav.server.org/$1 </VirtualHost> <VirtualHost *:443> SSLEngine on ServerName dav.server.org SSLCertificateFile /etc/letsencrypt/live/dav.server.org/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/dav.server.org/privkey.pem DocumentRoot /var/www/html/default ServerAdmin webmaster@server.org ErrorLog ${APACHE_LOG_DIR}/dav.server.org/error.log CustomLog ${APACHE_LOG_DIR}/dav.server.org/access.log combined Alias /dav /usr/share/davical/htdocs RewriteEngine On # PT is important if you are using an alias, it implies L # Redirect /.well-known URLs RewriteRule ^/\.well-known/(.*)$ /dav/caldav.php/.well-known/$1 [NC,PT] # Optionally: redirect /principals/users/ as well RewriteRule ^/principals/users/(.*)$ /dav/caldav.php/$1 [NC,PT] RewriteRule ^/principals/resources/(.*)$ /dav/caldav.php/$1 [NC,PT] RewriteRule ^/calendars/__uids__/(.*)$ /dav/caldav.php/$1 [NC,PT] RewriteRule ^/addressbooks/__uids__/(.*)$ /dav/caldav.php/$1 [NC,PT] # Redirect / requests to web login page RedirectMatch permanent ^/$ https://dav.server.org/dav/ </VirtualHost>
L'URL base del server sarà https://dav.server.org/dav/ e sarà accessibile sia con il protocollo WebDAV che con il protocollo HTTPS.
L'accesso in HTTPS presenta un'interfaccia minimale di amministrazione web: sarà possibile creare utenti (principals), creare address book e calendar (collections), ma per le normali operazioni di gestione contatti ed eventi si dovrà utilizzare un client dedicato. Nel nostro caso il client è rappresentato dalla app DAVdroid installata su uno smartphone Android, che darà accesso ai contatti e agli eventi di calendario a tutte le app relative.
L'amministratore del server DAViCal si collega all'URL di gestione https://dav.server.org/dav/, quindi accede alla pagina User Functions ⇒ Create Principal. I parametri da inserire sono:
Username | È prassi abbastanza diffusa utilizzare l'indirizzo di posta elettronica come nome utente. |
---|---|
Password | Immettere una password. |
Fullname | Normalmente si inserisce nome e cognome. Gli altri utenti del server DAViCal potranno vedere questa informazione. |
Email Address | Informazione di base richiesta per la creazione di un account, di solito coincide con lo Username. Anche questa informazione sarà pubblica per tutti gli utenti del server DAViCal. |
Principal Type | Selezionare Person per la creazione di un utente. |
Al termine dell'operazione sarà stato attivato un utente DAViCal; automaticamente sarà stato creato anche un address book (CardDAV) e un calendario (CalDAV) a lui assegnati. Se il nome di login è user@server.org, gli URL dei rispettivi oggetti saranno del tipo:
Address book | https://dav.server.org/dav/caldav.php/user@server.org/addresses/ |
---|---|
Calendar | https://dav.server.org/dav/caldav.php/user@server.org/calendar/ |
In generale non sarà necessario ricordare il percorso completo dei due oggetti, con l'autodiscover dovrebbe essere sempre sufficiente indicare solo l'URL base del server e gli oggetti disponibili dovrebbero essere automaticamente mostrati.
Esistono diverse app per Android per la sincronizzazione di contatti ed eventi calendario verso server DAV. Purtroppo si tratta spesso di app che offrono solo una delle due funzionalità e spesso le versioni free hanno limitazioni o problemi (ad esempio continui alert se la connessione con il server fallisce). Pare invece che l'app DAVx5 (prima conosciuto come DAVdroid) abbia tutte le carte in regola per essere scelta: si tratta di software open source disponibile anche su F-Droid e sembra sufficientemente stabile e maturo.
Una volta scaricata e installata l'app, si deve creare un nuovo account sullo smartphone. Nel nostro caso si procede con l'opzione Login with URL and user name. Con l'installazione di DAViCal vista in precedenza si inserisce qualcosa del genere:
Base URL | https://dav.server.org/dav/ |
---|---|
User name | email@server.org |
Password | ****** |
Lasciare attiva l'opzione predefinita Groups are separate VCards. Il server DAViCal support il formato vCard v.3.0 e quindi DAVx5 gestirà i gruppi come vCard separate (i gruppi sono usati ad esempio per creare le etichette da assegnare ai contatti). Vedere il paragrafo Contact group method nella documentazione sugli Account.
DAVx5 si collega al server e tramite l'autodiscovery sul percorso /.well-known/ si accorge che esistono già due collection collegate all'account: un addressbook e un calendar. Per impostazione predefinita infatti DAViCal crea queste due collection per ogni principal di tipo person (cioè per ogni account) che viene creato. Nella schermata che segue (vedi figura) bisogna attivare la sincronizzazione per queste due collection.
Questo è ciò che compare nello smartphone:
Maggiori dettagli nella pagina Accounts del manuale di DAVdroid.
Il sistema Android usa tecniche aggressive per il risparmi di batteria, questo affligge soprattutto le app non di sistema tipo DAVdroid. In pratica accade che viene inibita la sincronizzazione con il server: quando l'app è in background non viene mai svegliata.
Avviando l'app DAVx5 si viene avvisati di questo potenziale problema da tre pop-up:
Ci si può accorgere che qualcosa non va dal menu Strumenti ⇒ Utenti e account ⇒ DAVdroid ⇒ Sincronizzazione account. Sebbene l'opzione sincronizzazione sia attiva e si scelga l'azione Sincronizza ora dal menu in alto a destra, l'orario di sincronizzazione non si aggiorna!
Nel nostro caso Android 8.1.0 Oreo su Xiaomi Mi A1, è stato necessario …
In genere la via più comoda per aggiungere un calendario è utilizzare il client CalDAV preferito. Anche DAVdroid ha questa funzione agendo dalla app DAVdroid, Account ⇒ CalDAV ⇒ Hamburger menu ⇒ Crea nuovo calendario.
Il calendario può essere di tipo Calendario oppure Elenco attività o meglio ancora la combinazione dei due. Tale impostazione viene registrata nel database nella colonna property_value della tabella property. Le attività (task in inglese), a differenza degli eventi di calendario, di solito sono associati ad una data senza l'orario e sono pensati per potersi sovrapporre gli uni con gli altri (molte attività vengono portate avanti in parallelo. L'app calendario stock di Android non consente di visualizzare i task.
In alternativa l'utente (anche non amministratore) può effettuare login alla pagina di amministrazione web di DAViCal, quindi sceglie l'opzione User Functions ⇒ View My Details ⇒ Principal Collections ⇒ Create Collection. Nella pagina di creazione si deve attivare l'opzione Is a Calendar. Il calendario creato in questo modo sarà di tipo combinato Calendario ed Elenco attività.
Per attivare il nuovo calendario nello smartphone si accede alla app DAVdroid, dopo aver selezionato l'account opportuno, si effettua tap sull'Hamburger menu di CalDAV, quindi si sceglie l'azione Aggiorna lista calendari.
Per poter disporre del nuovo calendario sullo smartphone è necessario:
Per fortuna è possibile esportare in formato aperto tutti i contatti che abbiamo associato al nostro account Google. È sufficiente autenticarsi su Gmail all'url https://mail.google.com/, quindi aprire l'url https://contacts.google.com/. Aprendo il menù Di più è possibile scegliere l'opzione Esporta. Nel dialog-box è possibile indicare Esporta come vCard. Al termine sul PC avremo il file contacts.vcf che deve essere trasferito sullo smartphone, ad esempio con il tool adb push e il cavetto USB.
L'importazione va fatta dall'app Contatti, noi abbiamo usato quella stock di Android Oreo 8.1.0. Anzitutto dal menu Impostazioni abbiamo indicato come Account predefinito per i nuovi contatti quello aggiunto con DAVdroid, quindi, sempre da Impostazioni, si è scelto la voce Importa ⇒ File .vcf.
Non ha funzionato l'import delle foto associate ai contatti, infatti Google le include nel formato vCard come link ad un indirizzo web esterno (eventualmente da scaricare a parte), non come allegato JPEG.
L'app Contatti può mostrare i contatti provenienti dall'account Google, dall'account DAVdroid, oppure da tutti e due; dall'hamburger menu vi è un menu a tendina per la scelta. Fare attenzione a quando si rimuove un account, perché non è chiaro se lo stiamo rimuovendo anche dall'account Google e/o DAVdroid. Per sicurezza conviene rimuovere gli account Google facendo accesso con il browser all'url https://contacts.google.com/.
Per l'esportazione è necessario fare accesso con un PC e un browser alla pagina https://calendar.google.com/, ovviamente dopo aver effettuato il login ad esempio alla casella Gmail. Dall'icona ingranaggio si sceglie Impostazioni ⇒ Importazione ed esportazione ⇒ Esporta. Viene fatto scaricare un file zip che contiene un file .ics per ogni calendario esistente nell'account Google.
Nei file .ics esportati è opportuno modificare il tag X-WR-CALNAME, impostando la descrizione breve che identificherà il calendario nell'interfaccia di DAVdroid.
È possibile caricare ogni singolo file .ics in un calendario DAViCal dall'interfaccia web. Dopo aver fatto login come utente proprietario del calendario, si clicca View My Details ⇒ Principal Collections ⇒ ID ⇒ Load From File. L'opzione Append consente di aggiungere gli eventi a quelli già esistenti, altrimenti il file caricato sostituisce del tutto il contenuto esistente.
Per altri dettagli vedere la pagina How can I migrate to DAViCal using already generated .ics files?.
Dall'interfaccia di amministrazione web di DAViCal non è possibile impostare il colore predefinito di un calendario. Né la app calendario di AOSP stock (Android Open Source Project) né DAVdroid consentono di impostare il colore di un calendario esistente. È possibile tuttavia agire direttamente sul database di DAViCal per impostare il colore predefinito.
Anzitutto verificate nella app DAVdroid, aprendo l'account interessato, che nelle Impostazioni (icona ingranaggio) l'opzione Cambia il colore del calendario sia attiva; in questo modo DAVdroid gestirà i colori dei calendari forniti dal server. Anche l'opzione Supporto colore dell'evento può essere attivata; in questo modo ogni singolo evento potrà essere colorato in modo diverso rispetto al calendario di appartenenza (funzione con alcuni problemi: non funziona con la app Calendario stock, manda in crash l'app calendario Etar, ecc.).
Dopo essersi collegati al database come amministratore, si cerca l'utente proprietario del calendario:
davical=# SELECT principal_id, user_no, displayname FROM principal; principal_id | user_no | displayname --------------+---------+----------------------- 1 | 1 | DAViCal Administrator 1001 | 1001 | Niccolo Rigacci
quindi si cerca il dav_name del calendario desiderato:
davical=# SELECT user_no, dav_name, is_calendar FROM collection WHERE user_no = 1001; user_no | dav_name | is_calendar ---------+---------------------------------+------------- 1001 | /niccolo@rigacci.org/addresses/ | f 1001 | /niccolo@rigacci.org/calendar/ | t 1001 | /niccolo@rigacci.org/famiglia/ | t
Infine si aggiunge una riga alla tabella property:
INSERT INTO property (dav_name, property_name, property_value, changed_by) VALUES ('/niccolo@rigacci.org/famiglia/', 'http://apple.com/ns/ical/:calendar-color', '#F8BE14', 1);
Sullo smartphone è necessaria una sincronizzazione per vedere l'effetto:
A margine di questa esperienza vorrei segnalare un comportamento poco evidente e rischioso della app Calendario di Google. Su uno smartphone con CyanogenMod v.12.1 (basato on Android 5.1 Lollipop) era stata installata la app Etar; poiché il Calendario di Google non veniva più utilizzato, la app era stata disattivata dal menu Impostazioni ⇒ App.
La app Etar e le altre app di tipo calendario continuavano a mostrare gli eventi di calendario come associati all'account Google, permettendo anche di inserirne di nuovi. In realtà la sincronizzazione con l'account Google non funzionava più: tutti gli eventi erano salvati solo in locale sul device Android e non erano presenti sui server Google. Il tutto accadeva in modo silente, senza alcun messaggio di errore o di warning. Due circostanze potevano evidenziare il problema:
Per effettuare la corretta esportazione dei calendari è stato necessario riattivare la App Google e forzare la sincronizzazione.
Scenario: si vuole creare un calendario e condividerlo con due o più utenti.
Il principal di tipo group avrà il suo login e la sua password, ma le credenziali non verranno condivise con gli utenti che avranno accesso al calendario. Il calendario (in effetti una collection) sarà creato come appartenente a questo gruppo.
Serve davvero? Oppure è sufficiente creare il Ticket (vedi avanti)?
L'URL completo del calendario è https://dav.domain.tld/dav/caldav.php/caldavtest@domain.tld/calendar/, ma non si userà questo per l'accesso. La risorsa verrà ricollocata (bind) come risorsa di ciascun utente.
Con questa operazione, il calendario condiviso (che ha URL /caldavtest@domain.tld/calendar/) verrà mappato come risorsa dell'utente (con URL /user1@domain.tld/boundcalendar/):
L'URL completo del calendario diventa quindi https://dav.domain.tld/dav/caldav.php/user1@domain.tld/boundcalendar/. In generale non si dovrà indicare l'URL per esteso, perché il client (es DAVx5 su Android) elencherà il nuovo calendario nell'elenco di quelli disponibili, con l'etichetta impostata in Displayname.
https://dav.domain.tld/dav/caldav.php/user1@domain.tld/calendar/?ticket=7edu4Cpt
Dopo l'aggiornamento da Debian 9 Stretch a Debian 10 Buster, quando ci si collega all'interfaccia web di Davical (nella nostra installazione è qualcosa del tipo https://dav.host.tld/dav/), si legge il seguente warning:
Database schema needs upgrading. Current: 1.3.2, Desired: 1.3.3
Si è deciso di agire da riga di comando. Anzitutto si crea un file /etc/davical/administration.yml con le credenziali per accedere al database (proteggere il file con mode 600):
admin_db_user: davical_dba admin_db_pass: MySecret admin_db_host: 127.0.0.1
Quindi si esegue lo script /usr/share/davical/dba/update-davical-database che provvede ad applicare tutte le patch incrementali allo schema del database. Ovviamente si consiglia di fare un backup del database prima di eseguire la procedura.