Android Contacts/Calendar Sync without Google

On Android, you are supposed to sync contacts and calendar to the (Google) cloud. But what if you dont trust the cloud? Would rather sync to your home computer/laptop only? There are a few options; most require Windows and an additional app on the phone. And you can always setup your own Exchange or WebDAV server, even if this is quite some effort.

I first locally synced my HTC Desire to Outlook via HTC Sync and then my travel phone, an LG P350 optimus, via Android Sync Manager Wi-Fi. My Galaxy Nexus (Android 4.0) got Local Sync until it began to behave suspiciously on Windows. Since then, I have used DavX5 with radicale on an WSGI-enabled Apache web server.

Sync with WebDAV (2020)

For quite some time, it was difficult to get Android phones synced to non-Windows applications. Fortunately people have developed standard-based sync e.g. with WebDAV, which works over HTTP(s). On my Linux server, I installed radicale, a Python app that writes vcf (contacts) and ics (calendar) text files to the local file system, where I can version them with git and include them in my backup/restore routine.

To access radicale from the network, I added it into my Apache web server, using WSGI as Apache-Python bridge. On Android clients, DavX5 connects to Apache. On Linux, Thunderbird with CardBook (contacts) and Lightning (calendar) add-ons has cross-platform Apache access.

Radicale 3.0

We start with some insights on radicale [tutorial]:

apt-get install python3-pip python3-bcrypt python3-passlib
python3 -m pip install --upgrade radicale # installs radicale3 (2020)
mkdir /etc/radicale

# directories:
#   /etc/radicale
#   /usr/local/lib/python3.7/dist-packages/radicale/

nano -w /etc/radicale/config.apache
    [server]
    hosts = 0.0.0.0:5232
    ssl = True
    certificate = /etc/ssl/dyndns.mydomain.de/myhost.crt
    key = /etc/ssl/dyndns.mydomain.de/myhost.key

    [auth]
    type = remote_user
    htpasswd_filename = /etc/radicale/htpasswd.cfg
    htpasswd_encryption = bcrypt

    [storage]
    filesystem_folder = /opt/radicale/

    [logging]
    level = warning

# create HT passwd, used by apache too:
cd /etc/radicale
htpasswd -cB htpasswd.cfg myuser

# create data directory, for www-data user:
mkdir /opt/radicale
chown -R www-data.www-data /opt/radicale

Time for a test run with a browser of your choice! Here you will also create the contact/calendar files and directories for the first time.

# as root:
su www-data
python3 -m radicale
# will hang and display log; start the browser now
# ctrl-c on "python3 -m radicale" to stop server

https://server.local:5232/
# create contacts and calendar in web interface
# to compensate for your short password, they have long coded names

# rename accounts (there goes the extra security):
cd /opt/radicale/data/collections
mv 65435459-6e51-2543-b805-7cb54378768f con
mv be5a2453-8645-ebff-cfaf-e6b686565a2b cal
# reload web interface

... and once we have this, we can use git for versioning.

# git control:
cd /opt/radicale/collection-root
nano -w .gitignore
    .Radicale.cache
    .Radicale.lock
    .Radicale.tmp-*

git init .
git add .
git commit -a -m "Initial upload."

Make sure that port 5232 is never reachable from the outside, though we will not use it because Apache is routed locally, not via daemon.

Apache to Radicale

Next, we connect radicale to Apache.

apt-get install libapache2-mod-wsgi-py3

nano -w /etc/apache2/sites-available/myhost.conf
    WSGIDaemonProcess radicale user=www-data group=www-data threads=1
    WSGIScriptAlias /radicale /var/www/dyndns.mydomain.de/radicale/radicale.wsgi
    WSGIProcessGroup radicale
    <Location /radicale>
        AllowOverride None
        AuthType basic
        AuthName "dyndns.mydomain.de"
        AuthUserFile /etc/radicale/htpasswd.cfg
        Require user myuser
        SSLRequireSSL
    </Location>

su www-data
nano -w /var/www/dyndns.mydomain.de/radicale/radicale.wsgi
    import os
    from radicale import Application, config, log
    config_paths = [('/etc/radicale/config.apache', False)]
    configuration = config.load(config_paths)
    application = Application(configuration)

chown -R www-data.www-data /var/www/dyndns.mydomain.de

... and after a systemctl restart apache2 whip out your browser again:

https://dyndns.mydomain.de/radicale/
clear && tail -f /var/log/apache2/access.log

... and watch the console to see your accesses.

DavX5

Get DavX5 for free on F-Droid or give them a 5€ donation on GPlay. The configuration is very short:

new account
    base url: https://dyndns.mydomain.de/radicale
    username: myuser

You might want to prod around in the settings to avoid over-eager syncing behavior. After that, press the sync button, ssh onto your server and watch the vcf and ics files come in.

Thunderbird

And on we go for radicale clients on the Linux desktop.

# lightning for calendar
apt-get install xul-ext-lightning

# cardbook for contacts
Tools -> Addons-> Search on addons.thunderbird.net -> cardbook

# sync contacts:
Addons -> Cardbook (Shift+Ctrl+B)
    left area -> RMB, new address book
    Remote, CardDAV, url: https://dyndns.mydomain.de/radicale/myuser/con/, Validate

# sync calendar:
Events and Tasks -> Calendar (Shift+Ctrl+C)
    left area -> RMB, new calendar
    Network, CalDAV, location: https://dyndns.mydomain.de/radicale/myuser/cal/

Isnt that nice? Just what I wanted, cross-platform sync on my own server and my own terms.

LocalSync (2012)

Once upon a time, I used LocalSync with Android 4.0 and Outlook on Windows -- until the Windows box opened unexplained connections. So the recipe below should not be followed and is only here for historical purposes.

Start VirtualBox and LocalSync on it (use a firewall to forbid funky connection attempts), which will also start Outlook. On Linux in VirtualBox settings, choose "Settings->Network->Advanced->Port forwarding" and add tcp 8889, tcp 1160, udp 1160 and udp 17659 to establish first authentication. The actual sync is a bit more elaborate:

On Linux shell, sudo tcptrack -i eth0 (or whatever your network device is) to see which ports LocalSync uses (changes every time). On phone, choose "Sync->Synchronize calendar" (smaller than contacts) first and note the ports on Linux shell, e.g. by screenshot, this should give a port usually in the range tcp 1037..1044. On Linux in VirtualBox settings, choose "Settings->Network->Advanced->Port forwarding" again and add the port. This must be repeated everytime LocalSync on the VirtualBox is restarted.

Now on phone, choose "Sync->Synchronize all". In Outlook, choose "File->Options->Advanced->Export" to export to XLS. Restore also from "Export" dialog.

... and I really do wonder why the ports were made so complicated.

Other Sync Options (2010)

Some ancient history: In the 2010s, it had to be mostly Outlook. Below is my list of options from back then; I have not tried all of them. The "version" column is from the information that I could infer (e.g. if the Galaxy Nexus is not in the supported devices list, I conclude that Android 4.0 ICS [ice cream sandwich] is not supported).

App Description OSes Desktop Versions Cost
DavX5 2020s Android app that works e.g. with radicale (usable with Apache) and other WebDAV software. Open source so privacy is almost guaranteed. I trust this. Linux
Windows
Mac
Thunderbird 5.0+ free
NextCloud 2020s Linux/Android app pair that makes your home server "the cloud" and syncs to NextCloud server plugins. Open source, so I trust this. Messes up your contact phones and calendar birthdays though, and backup/restore does not work because easily because backup contains machine-specific ids. Linux Browser 5.0+ free
Local Sync 2010s Windows/Android app pair from Ondrej Psencik. Requires dotNet 3.5, Outlook PIA (Primary Interop Assemblies, free from Microsoft), works an Android 4.0, requires only sensible security permissions. Will create local calendar on first sync, if so requested. Opens iffy connections into the Internet from Windows, though. I do not trust this. Windows Outlook 2.1-4.0 free
Android Sync Manager Wi-Fi 2005s Windows/Android app pair from mobileaction. Has some ads on windows app, but syncs contacts/cal nicely. But not on Galaxy Nexus (4.0). Has some funny permissions such as "edit sms", "send sms". I do not trust this. Windows Outlook 2.1-2.3 free
MyPhoneExplorer Windows/Android app pair from FJ soft. Android app crashes on Android 4.0 when trying "Settings->Calendars to sync". Has some funny permissions such as "intercept outgoing calls", "edit sms", "send sms". I do not trust this. Windows Outlook
Thunderbird
1.6-2.3 free
Funambol Java/Android app pair, open source. Primitive browsing GUI on desktop. Had some trouble with duplicate entries when used in conjunction with HTC sync on other computer. Linux
Windows
Mac
Own app 2.1-4.0 free
HTC Sync Windows app only for HTC devices. Crashes sometimes for no appearant reason, sometimes clean and re-push of contacts/cal necessary, otherwise decent. Works ok with HTC Desire. Windows Outlook 2.1-2.3 free
KIES Samsung Windows/Mac app only for Samsung devices. Cannot sync to Android 4.0. Not tried. Windows
Mac
Outlook 2.1-2.3 free
Missing sync Windows or Mac/Android app pair from markspace. Not tried. Windows
Mac
Outlook
Entourage
2.1-2.3 40€
android-sync.com Windows/Android app pair from Android sync. With USB cable only. Not tried. Windows Outlook 2.1-4.0 20€
companionlink Windows/Android app pair from Companion Link. Not tried. Windows Outlook
Lotus
2.1-4.0 50€

... and thus ends our amusing history lesson full of dead links to long-deceased sync software.

Conclusion

Android sync is still a wild ride, as evidenced by the effort required to get rid of Google even a little bit. Hopefully the information above could make you fractionally more knowledgeable in that regard. Always strive for freedom, and have a good day!

EOF (Apr:2021)