Metrodroid: reading your transit card with an Android phone
Read data from public transit cards using your NFC Android phone! (iOS 13 and PC/SC support coming soon)
At a glance
- What is it?
- Metrodroid is an open source Android app that reads contactless public transport cards over NFC and shows the balance, recent trips and card history, covering FeliCa, CEPAS, Calypso, MIFARE Classic, DESFire, Ultralight and Vicinity cards across a long list of cities. It grew out of Farebot and depends on reverse engineering that is often not permitted by the card issuer.
- Who is it for?
- Adopt Metrodroid if you want to see what is actually stored on a transit card, because the balance and trip history the operator's own app shows you is often less than what the card contains, and you want that data in a tool you control. Do not adopt it as a ticket wallet, since the project reads cards rather than managing them, and check the locked icon in the agency table before you try a card, because a locked card cannot be written to.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 21 days ago.
- What is it written in?
- Mainly Kotlin, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What the app actually shows
Metrodroid reads data from public transit cards using NFC on an Android phone, and the project description gives the scope plainly: view remaining balance, recent trips, and other info from contactless public transit cards using NFC on Android, with an iOS version coming soon.
That framing matters. This is a reader, not a ticket wallet. It inspects what is on the card and presents it, and it does not manage a journey or hold a ticket. The iOS version is linked from the readme as coming soon, and the repository description mentions PC/SC support coming soon as well, which suggests the roadmap includes reaching the card through a contactless smart card reader attached to a computer rather than through the phone's own radio.
The authorship is worth noting too. The readme credits Michael Farrell, who is also behind Farebot, and the thanks section says the project is based on Farebot. Eric Butler is credited for Farebot, Karl Koscher for ORCA, Sean Cross for CEPAS and EZ-Link, and there is a long list of individual contributors who each added support for a specific card family or city, from the nfc-felica and IC SFCard Fan projects for Suica through to a contributor covering Podorozhnik, Troika, Compass, Shenzhen Tong, Rav-Kav, T-money, Leap, CharlieCard, EN1545, Intercode, IstanbulKart, Lisboa Viva, Mobib, RicaricaMi, Chinese cards, Adelaide Metrocard and Rejsekort.
The scale of that list is the interesting fact about the project. Supporting a transit card is not a protocol problem, it is a per-operator reverse engineering problem, and the project has been accumulating those answers for years.
The card protocols, and the hardware caveat
The supported protocols section is short and it is the technical core of the project.
FeliCa and FeliCa Lite are supported, which covers the Japanese card family. Under ISO/IEC 7816-4 there are three listed: Calypso, CEPAS and T-Money. ISO/IEC 15693 Vicinity is supported, which is the family used by contactless bank cards. Then MIFARE Classic, MIFARE DESFire and MIFARE Ultralight.
Two of those carry a warning in the same list, and the parenthetical notes are the important part. MIFARE Classic is marked as not compatible with all devices, and MIFARE Ultralight likewise.
That is a hardware limitation rather than a software one. MIFARE Classic and Ultralight cards rely on a unique encryption scheme tied to the card UID, and the ability of a phone to talk to them depends on the hardware and driver being able to present the right keys. Some devices and some Android versions can, others cannot, and the app therefore works inconsistently across phones even for the same card.
The repository topics reflect the same spread, listing iso14443a, mifare, mifare-classic, mifare-desfire, mifare-ultralight, felica, cepas, nfc and pcsc. The pcsc entry is the smart card interface, which is the route to the coming PC/SC support.
The readme also links a talk by Michael Farrell, given at linux.conf.au 2018, called Tap on to reverse engineering, about the work that went into supporting a number of Australian agencies' cards. That talk is the closest thing to a design document for how a new card gets added.
Reading the agency table, where the locked icon does the talking
The supported cards and agencies table is long, and its notes column is where the practical information lives.
The icons in the notes column mark two things. A lock with a key means the card is locked and cannot be written to, and the new marker means the support is new, and the eyes and IOS markers flag a card that can be read on iOS.
Reading a few rows makes the pattern clear. bip! in Santiago, Chile is new and locked with a key and uses MFC. Bilhete Único in São Paulo is locked with a key and uses MFC. BUS-IT in Greater Hamilton, New Zealand is new, locked and MFC. CharlieCard in Boston is new, locked and MFC. Calypso, CEPAS and T-Money are the ISO/IEC 7816-4 family and are not marked as locked, and Clipper in San Francisco is listed with IOS but no lock.
So there is a clear split. The older, operator-controlled card formats in Europe and North America tend to be cryptographically locked, and a locked card can be read but not modified, which is what you want for inspecting balance and history and exactly what stops the app from being a ticket writer. The Japanese FeliCa family and several newer cards are not locked in the same way.
The consequence for a user is that the app is a diagnostic and inspection tool. It can show you what is on the card, which is useful when the operator's own app does not show everything, and it cannot be used to write a ticket onto a locked card.
The table is also the clearest documentation of the project's scope. It lists Amiibo as a worldwide card, AT HOP in Auckland, Beijing Municipal Card, Carta Mobile in Pisa, City Union in mainland China, Compass in Vancouver, Crimea's Trolleybus, and Cubic Nextfare across the Americas, among many more, and each row corresponds to code someone contributed.
An Android app with a desktop companion and an unusual repository shape
The repository is not a single Android application project, and the top level entries make that clear.
There is a src directory holding the app, and the usual Android build machinery around it: build.gradle, settings.gradle, gradle.properties, a gradlew wrapper, a buildSrc directory, proguard.cfg and a lintchecks directory. There is a config directory and a data directory, which is where the card format definitions and the transit agency data live, and a cardimages directory for the card artwork.
Then there are the parts that are not an Android app. A jvmcli directory, which is a command line interface on the JVM, and a native directory. A proto directory, which suggests the card format descriptions are defined as protocol buffer style definitions rather than as hand written parsers, which is a sensible way to express many similar but different card layouts. A third_party directory, and a stops-dot-farebot-m directory, which is the transit stop metadata module inherited from Farebot, the project Metrodroid is based on.
There is also a fastlane directory for the release automation, an mdst directory, a docs directory, and a config directory. The presence of the data directory is the part that tells you how a new card is added, because the data for each card family and each agency is configuration rather than code, and the code that interprets it is shared.
The build and CI setup is Travis based, with a .travis.yml and a .travis directory, and the app is translated through Weblate, with the readme's translation status badge pointing at that service and a long list of translators credited for Dutch, Finnish, French, Hebrew, Indonesian, Japanese, Kabyle, Norwegian Bokmal, Brazilian Portuguese, Russian, Spanish and Turkish.
Distribution, licence, and what a user actually gets
The app is distributed widely, which is unusual for a project of this kind and reflects that it has a real user base rather than only a developer audience.
The readme links a F-Droid badge, an IzzyOnDroid repository badge, a Google Play listing and a direct APK download from the GitHub releases page. The homepage is metrodroid.org, and the current version stated in the readme is 3.1.0, which matches the v3.1.0 release from 2025-11-14. The version history before that has a long tail, with v3.0.0 from 2019-11-02 and v2.9.43 from 2019-07-20, so the 3.0 line sat for years and the 3.1 release is recent.
The last push to the repository was on 2026-10-02, so the code is being worked on.
The licence is GPL-3.0, with a COPYING file at the root, and the language is Kotlin with a native component in the native directory, which is presumably for the card communication that the Android NFC APIs do not expose directly.
The last thing worth understanding is what the project is doing, legally and technically, because it touches other people's systems. Reading a card you hold is one thing, and the readme is clear that the app inspects cards rather than writing them. But the card data itself belongs to a transit operator, and the operator may not have published the format. A team deploying Metrodroid for its own operators, or in a jurisdiction where card data has privacy rules, needs to establish that before it does anything with a card.
The project is open source and the formats are documented in the data directory, but an operator that has not published its format can still object, and that is a risk a company takes rather than an individual.
Editorial conclusion
Adopt Metrodroid if you want to see what is actually stored on a transit card, because the balance and trip history the operator's own app shows you is often less than what the card contains, and you want that data in a tool you control. Do not adopt it as a ticket wallet, since the project reads cards rather than managing them, and check the locked icon in the agency table before you try a card, because a locked card cannot be written to. Before you commit, look at the supported card list for your city, note that MIFARE Classic and Ultralight are marked as not compatible with all devices, and read the project description carefully about what the app does and does not do with your card data.
Frequently asked questions
What is Metrodroid?
Metrodroid is an open source Android app that reads contactless public transit cards using NFC and shows the remaining balance, recent trips and other information on the card. It is based on Farebot and is written in Kotlin, with an iOS version and PC/SC support described as coming soon.
Which card protocols does Metrodroid support?
FeliCa, FeliCa Lite, ISO/IEC 7816-4 with Calypso, CEPAS and T-Money, ISO/IEC 15693 Vicinity, and MIFARE Classic, DESFire and Ultralight. MIFARE Classic and MIFARE Ultralight are marked as not compatible with all devices.
Can Metrodroid write tickets onto a transit card?
No. It is a reader rather than a ticket wallet, and the agency table marks many cards as locked with a key, meaning they can be read but not written. The readme frames the project as viewing balance, recent trips and other information on the card.
How is Metrodroid distributed and what licence does it use?
It is on F-Droid, IzzyOnDroid and Google Play, with a direct APK download from the GitHub releases page. The licence is GPL-3.0, and the current version is 3.1.0, published in November 2025.
How does someone add support for a new transit card?
The repository keeps card format and agency definitions in a data directory with the parsing code shared, and the readme credits a long list of individual contributors who each added a specific card family, along with a talk by the author on the reverse engineering work behind the Australian agency support.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/metrodroid-metrodroid)Was this useful?