Replacing proprietary libraries¶
We are speaking about F/LOSS here: Free/Libre Open Source Software. So proprietary libraries are tainting your otherwise fine F/LOSS app. Sometimes it seems there are no alternatives – but quite often, there are:
Push notifications¶
First thing coming to mind is probably Firebase Cloud Messaging here, which is proprietary (and involves the servers of a big advertisement company). Well, actually the very first question would be if your app really needs cloud messaging (I've seen Calculators implementing it, honestly!). And then, if they are needed: are there alternatives? You can find them in our page on Push Notifications.
Firebase per se¶
As we just mentioned Firebase: you might use other features of that framework. How to replace those? There are two F/LOSS frameworks covering most of it:
- appwrite provides database, auth, storage and more (BSD-3-Clause); see e.g. this appwrite-example for a quick intro
- Supabase provides database, auth, storage and more (Apache-2.0 license)
Analytics¶
You think your cannot do without some analytics? There are some F/LOSS libraries you might want to consider. They might not be as fancy as Firebase Analytics with its Console, but: do you really need that? Often you are mostly concerned about crash reporting, ideally in a privacy friendly way (speaking of which: always make your implementation opt-in to get the clear consent of those whose data will be transmitted). Well, there are some candidates:
- ACRA (Apache-2.0) is the best known library for crash reporting. You can e.g. configure it to show a dialog showing the details to be sent, so it's clear and transparent. This was the default in the past, but ACRA now defaults to silent reports (without notifying the user). Make sure to explicitly use the Dialog option.
- Countly (MIT) is a Java library which has a Flutter SDK without GMS and Firebase. On pub.dev it is listed way below the normal package list, and seemingly not mentioned in the docs. (source of this hint)
- CrashReporter (GPL-3.0) will record and prompt to share the log into contactDetails after the occurrence of any crash
- Sentry.io (MIT) would also give you some fance Dashboards, and can be self-hosted.
- aptabase (AGPL-3.0) describes itself as „Open Source, Privacy-First and Simple Analytics for Mobile, Desktop and Web Apps“. It also comes with a Dashboard, and can be self-hosted.
- backtrace-android (MIT) might be another alternative for crash reporting.
- Plausible Analytics (AGPL-3.0) describes itself as „Easy to use and privacy-friendly Google Analytics alternative“
Some more candidates are listed in this snippet. Note that we didn't test them, so we cannot give a clear recommendation here.
License Dialogs¶
How comes that my app suddenly includes Google Mobile Services (GMS)? I only added this play-services-oss-licenses library! – Yeah, that's why. The name might be a little misleading: it is intended to list „OSS licenses“, not that it is „pure F/LOSS“ itself (you probably missed the leading „play-services“ part). Actually, the library itself is – but it depends on, voila, Google Mobile Services, thus dragging them into your app. But luckily, here too we have several alternatives to choose from. Again, the list is unlikely to be complete:
AboutLibraries (Apache-2.0) is the most popular candidate. Some more alternatives are listed in this snippet, but have mostly not seen any updates for a year or more.
Flutter and GeoLocation¶
Flutter's geolocator pulls in Google Mobile Services. To avoid that, follow these steps:
add the regular geolocator as a dependency in pubspec.yaml:
dependencies:
geolocator: ^14.0.2
then, override dependencies in pubspec.yaml:
dependency_overrides:
geolocator_android:
git:
url: https://github.com/Zverik/flutter-geolocator.git
ref: floss
path: geolocator_android
Another approach would be to instead use libre-location, which advertizes itself as Background location tracking for Flutter without Google Play Services. Pure AOSP LocationManager + CoreLocation – and comes with the Apache-2.0 license.
ML Kit¶
- MLKit for QR Code scanning:
- there is a maintained port of ZXing reported working pretty well and fast. Also, the original ZXing is still maintained (though not as active as its fork).
- for JS runtimes (React Native, Node, etc), there's a pure JavaScript QR encoder & decoder: @paulmillr/qr (Apache-2.0/MIT licensed). Even works in a web browser.
- MLKit for OCR:
- a potential replacement would be Tesseract OCR, see Tesseract4Android. A detailed description can be found in this article: Implementing OCR in Android and iOS apps with open-source SDKs.
Wear OS¶
Note: IzzyOnDroid cannot currently accept Wear OS apps that share a package name with another app, which is the setup that Google wants.
Note: The links in this section will refer to old commits, at the time of writing this section. Improvements may have been made to this code, but these old versions have been chosen on purpose to ensure the implementation is more basic.
For Wear OS, a common setup is to have a main app on the phone and a slimmed down separate "companion app" on the watch. While most Wear OS devices will require a proprietary app for setup and connecting to the phone, it is possible to avoid the GMS Wearable libraries for communicating between your phone and watch. While this does not make Wear OS itself a platform usable without proprietary apps (as you will still likely need the Google Pixel, Samsung Wearable or similar proprietary app to connect your watch to your phone), you can at least keep your FOSS app free from proprietary libraries this way.
Say you have a todo list on the phone and you want to make it accessible on the watch. In these cases, it may be good to remember that a Wear OS watch is connected through Bluetooth and thus basic communication can be done over the existing Bluetooth connection (using Rfcomm).
To talk over Bluetooth, you will need a setup similar to Catima's WearOS app:
- A simple "Bluetooth service" on the phone, with a specific Bluetooth UUID to uniquely mark such service (generating a random ID is sufficient). For an example, see
app/src/main/java/protect/card_locker/wearos/BluetoothServerService.kt. - A simple "Bluetooth client" on the watch, using the same Bluetooth UUID as the service on the phone. For an example, see
wear/src/main/java/me/hackerchick/catima/wear/BluetoothCardClient.kt.
See this commit for a basic initial implementation.
Then, you need to decide on a protocol for what commands the watch and phone send each other and what they will receive in response. Do note that the amount of data you can send over Bluetooth in one go is limited, so you may need to build basic pagination or chunking into your Bluetooth API.
Note: When using a simple Bluetooth setup like this, it is important to remember that any connected Bluetooth device that knows the UUID can talk to your phone or watch app. Not all connected Bluetooth devices may be trusted by the user. It is therefore important to build some kind of authentication protocol to protect sensitive data. An example of such a protocol implementation is in this commit.
Misc¶
- Cronet (
play-services-cronet): take a look at kwik - GMS & Co: check microG Implementation status if using GmsCore might be an option (e.g.
org.microg.gms:play-services-locationas replacement forcom.google.android.gms:play-services-location– same API surface, so this should even be a drop-in replacement)
My app contains some proprietary lib, but how did that got in?¶
To find the culprit, depending on how you wrote your app there are e.g. the following commands to find out:
gradle :app:dependenciesshows a gradle depency treeflutter pub depsdoes the same for your Flutter appnpm listshows a NodeJS dependency tree, see this post on stackoverflowyarn why mime-dbcan be used with NodeJS to find out what dragged in the given library, heremime-db(see How to view the dependency tree of a given npm module?)
If you use Gradle, you then might be interested in the article on How to exclude Gradle dependencies.