What is Fdroid?
Fdroid is an open source app store for Android. While the Google Play Store is full of ads, in app-purchases, and apps that like to request permissions, Fdroid apps generally do not have ads, in-app purchases, or permission requests. All apps on Fdroid are required to be floss (free/libre open source software). Fdroid apps tend to be simple, offline, and privacy respecting.
Why publish on Fdroid?
- The F-Droid app database is tiny compared to the Google Play Store, so your app will get more exposure.
- You can include donation links in your app description.
- You will support the FLOSS community.
- You will learn a lot about your app and android development. F-droid has a very strict publishing process, and will run reports on your dependencies, code, and permissions.
What are reproducible builds?
Reproducible builds are optional but highly recommended.
Reproducible builds is a way to guarantee that an app was built from the published source code. This is done by building and signing the apk with a key, and publishing the fingerprint of the key. F-Droid will then build the app from the source code, and verify that it built the exact same apk as the one you published. Luckily, F-Droid and Github together make this process very easy, and this guide will walk you through it.
1. Create Metadata
Fdroid uses metadata files to find app descriptions and storefront images. Here is a list of files you should create, at the root of your project:
Ignore the changelogs for now, they will be used for noting changes in your app.
- icon = 512x512
- feature graphic = 1024x500
- screenshots = any size
all images can be png or jpg
- short description = max 80 characters
The title, short description, and long description are shown on the app page in Fdroid, like so:
2. Build and Sign your app
If you are using Android Studio, you can build your app by going to Build > Generate Signed Bundle / APK
.
If you are using Gradle, you can build your app with ./gradlew assembleRelease
. This will generate an apk file in app/build/outputs/apk/release/app-release.apk
. See my guide on Signing Android Apps with Gradle for more details.
If you are using the command line, you can sign your app with the following command:
apksigner sign --ks-key-alias YOUR_KEY_ALIAS --ks YOUR_KEYSTORE_PATH app-release.apk
See my guide on Signing an Android apk with the command line for more details.
3. Create a Github release
F-Droid needs to download your signed APK file from somewhere. The best place to put this file is in a Github release, tagged with the same tag that Fdroid will use pull your source code from. That way it is all connected. If you have never created a release before, you can follow Github’s instructions.
4. Clone the Fdroid repository
Fdroid uses gitlab to host their repositories. You will need to create an account on gitlab.com if you don’t already have one.
Clone the Data Repo. This repo holds the metadata for all the apps published on Fdroid.
On your cloned repo, create a new branch for your app. The branch name should be the package name of your app. For example, “com.example.myapp”.
5. Create your Metadata file
Create a new file in the metadata/
directory. The file name should be the package name of your app, with a .yml extension. For example, metadata/com.example.myapp.yml
.
The file should contain the metadata for your app. Here is an example:
Categories:
- Science & Education
- Reading
License: MIT
AuthorName: John Doe
AuthorEmail: john@example.com
AuthorWebSite: https://example.com
SourceCode: https://github.com/username/myapp
IssueTracker: https://github.com/username/myapp/issues
Changelog: https://github.com/username/myapp/releases
AutoName: My App Name
RepoType: git
Repo: https://github.com/username/myapp.git
Binaries: https://github.com/username/myapp/releases/download/v%v/MyApp-%v.apk
Builds:
- versionName: 1.0.1
versionCode: 1
commit: v1.0.1
subdir: app
sudo:
- apt-get update
- apt-get install -y openjdk-17-jdk-headless
- update-java-alternatives -a
gradle:
- yes
AllowedAPKSigningKeys: 046e269cfdb4816b4ef3d554a63de6be063e40008b524c04397d3b04315eaccd
AutoUpdateMode: Version
UpdateCheckMode: Tags
CurrentVersion: 1.0.1
CurrentVersionCode: 1
Let’s go over each section:
Categories
Categories:
- Science & Education
- Reading
The categories your app belongs to. The available categories are Connectivity, Development, Games, Graphics, Internet, Money, Multimedia, Navigation, Phone & SMS, Reading, Science & Education, Security, Sports & Health, System, Theming, Time, Writing
License
License: MIT
This needs to be an open source license. Some common examples are MIT, GPL-3.0-only, and Apache-2.0.
Author Details
AuthorName: John Doe
AuthorEmail: john@example.com
AuthorWebSite: https://example.com
These details are optional but recommended.
Source Code
SourceCode: https://github.com/username/myapp
IssueTracker: https://github.com/username/myapp/issues
Changelog: https://github.com/username/myapp/releases
The SourceCode
link is required, and should be a link to the source code of your app. The IssueTracker
and Changelog
links are optional.
AutoName
AutoName: My App Name
The name of your app. This is used when F-Droid finds an update for your app, and automatically generates a commit in their repo.
Repo
RepoType: git
Repo: https://github.com/username/myapp.git
The link to your git repo. This is used to pull your code and build your app. Notice that the URL ends with .git
. The Binaries
property is related to Reproducible Builds and links to a signed apk file of your app.
Binaries
Binaries: https://github.com/username/myapp/releases/download/v%v/MyApp-%v.apk
This is where Fdroid will download your signed apk file from. This example uses Github releases, but you can use any file hosting service.
This url uses the %v
placeholder, which will be replaced with the version name of your app. So if your app’s version name is 1.0.1
, the url will be https://github.com/username/myapp/releases/download/v1.0.1/MyApp-1.0.1.apk
You can also use the %c
placeholder, which will be replaced with the version code of your app.
Builds
Builds:
- versionName: 1.0.1
versionCode: 1
commit: v1.0.1
subdir: app
sudo:
- apt-get update
- apt-get install -y openjdk-17-jdk-headless
- update-java-alternatives -a
gradle:
- yes
This is where you specify how to build your app. The versionName
and versionCode
properties are the version name and version code of your app. The commit
property is the git tag or commit hash of the latest version of your app. The subdir
property is the directory of your app’s source code.
The sudo
property is a list of commands to run before building. Here we are installing the latest version of Java. This is required for the build to work.
The gradle
property specifies whether to build with Gradle as opposed to Ant.
AllowedAPKSigningKeys
AllowedAPKSigningKeys: 046e269cfdb4816b4ef3d554a63de6be063e40008b524c04397d3b04315eaccd
This is the fingerprint of the key used to sign your app. To get this fingerprint, run the following command:
apksigner verify --print-certs app-release.apk
This will output something like the following:
Signer #1 certificate DN: CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
Signer #1 certificate SHA-256 digest: 467b191ab3a180cf99db79aef870c52ff2f8ebd5967d4c0e923626a0dc422528
Signer #1 certificate SHA-1 digest: ed9d1cede4e3a4b586655e97993b00c7ba9eb1cd
Signer #1 certificate MD5 digest: 6ecd4e59e7cc26253763ca9590443fa1
You will want to copy the SHA-256 digest and add it to the AllowedAPKSigningKeys
property in your metadata file.
Auto Update
AutoUpdateMode: Version
UpdateCheckMode: Tags
CurrentVersion: 1.0.1
CurrentVersionCode: 1
The AutoUpdateMode
property specifies if F-Droid will check for updates to your app. This should be set to either Version
or None
. The UpdateCheckMode
property specifies how F-Droid will check for updates. It can be set to either Tags
or HTTP
, but Tags
is recommended. The CurrentVersion
and CurrentVersionCode
properties are the version name and version code of your app.
Full Metadata Reference
See the Full Metadata Reference for more details on all the properties you can include in your metadata file.
6. Testing your build
Push your metadata file to your branch on gitlab, and it will kick off a build. Go to Build -> Pipelines to see the results. If there are any errors, you can keep pushing changes until it runs successfully.
Some potential issues you could run into:
- Metadata linting failure, meaning your metadata file is formatted incorrectly. This is a common issue since Fdroid expects the properties to be in a specific order. The build output will tell you what it expected, so it is an easy fix.
- Version mismatch. If the commit tag you specified in your metadata file does not exist, or the version in your gradle file does not match the version in the metadata file, the build will fail.
- APK integrity check failed. If the apk you published does not match the apk that Fdroid built, the build will fail.
7. Creating a merge request
Once you have a successful build, it’s time to create a merge request.
First create a Request for Packaging issue for your app. This will let the F-Droid team know that you want your app published. Fill in the minimal template to the best of your ability.
Next, create a merge request on your branch. The merge request should be titled New app: My App Name
. The description should include a link to the Request for Packaging issue you created above. Once you create the merge request, it will kick off another build, and the Fdroid team will review your app.
Updating your app after its published
To get your app updated on Fdroid, you will need to do a few things:
- Update the version name and version code in your gradle build file.
- Create a new change log in the metadata directory (/metadata/en-US/changelogs/{version code}.txt), and put a description of changes in the file.
- Tag and create a release on Github with the new version. Make sure you include the signed apk file in the release.
- Fdroid will automatically see your update, and include it in the next build. This may take a few days or longer to happen.