Android app to write and read NFC tags that can be used on the TonUINO DIY music box.
For discussion, see this thread (in German), or use github issues.
You can download releases on github, or install the app from the Google Play Store or the F-Droid Store.
Every commit is also built and bundled as an .apk on CircleCI, the latest state is
For differences between release versions, consult the change log.
If you don't plan to program for Android often, and have nix available, I would recommend using that.
With nix
it is very easy to install and setup the needed tools in a clean environment. No need for nixOS, just the package manager is enough.
I used https://github.com/tadfisher/android-nixpkgs to configure both nix develop
and nix-shell
.
# Uses the configuration of `./flake.shell.nix`
nix develop
# or as an alternative (without nix flakes) use `./shell.nix`
nix-shell
This is my only Android app, so every time I want to create another update, I would spend a lot of time upgrading the SDKs, Android Studio, Gradle and kotlin and have now switched to the nix approach.
But the links below should still work. If not, please create a pull request so I can update them.
Install Android studio, and then follow the tutorial "run this app on a real Android device".
If you want more control instead of using Android Studio, check the docs on building and testing from cli.
If you have problems connecting to your Android device, have a look at this help page on on how to run apps on a real hardware Android device.
These are a few commands I find useful:
# show attached devices
adb devices
# Create a clean build
./gradlew clean bundle
# If something fails, check the output of
./gradlew --version
# Run the linter
./gradlew lint
# Run the test suite with
./gradlew test
# Or
bundle exec fastlane test
# Deploy a debug build to a connected Android device
./gradlew installDebug
# Check if the Android device was properly connected
./gradlew connectedCheck
# Get a list of available gradle tasks
./gradlew tasks
- Migrate away from deprecated
kotlin-android-extensions
plugin
Warning: The 'kotlin-android-extensions' Gradle plugin is deprecated. Please use this migration guide (https://goo.gle/kotlin-android-extensions-deprecation) to start working with View Binding (https://developer.android.com/topic/libraries/view-binding) and the 'kotlin-parcelize' plugin. - [ ] Recreate the UI with Jetpack compose - [ ] Use KTX extension libs https://developer.android.com/kotlin/ktx
- Replace qr code scanner lib as it is no longer maintained
- Get BytesFormatter to work without issues
- Hide on-screen-keyboard when switching between edit fragments
- Allow users to write a note or title to the NFC tag
- Allow users to keep a list of tags
- Simulate NFC tag
- Use proper Material design theming instead of faking it
- On MainActivity if NFC is not available
# | name | range | description |
---|---|---|---|
0 | cookie | uint32 | identifies TonUINO, expected 0x1337b347 |
4 | version | uint8 | always 1 |
5 | folder | uint8 | values between 1 and 99, see dfplayer docs |
6 | mode | uint8 | values between 1 and 5, see next table |
7 | special | uint8 |
Different Modes
Based on the value of byte mode and what happens, when the next and previous buttons are
pressed
# | title | description | next | previous |
---|---|---|---|---|
1 | Hörspiel audio book (single file) |
plays a single file in the folder | stop | Start title again from the beginning |
2 | Album | play every file in the folder | next file | previous file |
3 | Party | play files in the folder in random order | play random file | start title again from the beginning |
4 | Einzel single |
play a single file in the folder | stop | start title again from the beginning |
5 | Hörbuch audio book (multiple files) |
play all files in the folder and keep track of the progress (will start at the last file the next time | next file | previous file |
6 | Admin | Not functionality | - | - |
Special
Is only used in specific modes to specify variables:
- mode 4: file number
- mode 6: placeholder, no functionaliy yet
# | name | range | description |
---|---|---|---|
0 | cookie | uint32 | Identifies a Tonuino tag, usually 0x1337b347 |
4 | version | uint8 | always 2 |
5 | folder | uint8 | Values from 1 to 99, see dfplayer docs |
6 | mode | uint8 | Values from 1 to 5, see next table |
7 | special | uint8 | |
8 | special2 | uint8 |
Different Modes
It supports all modes of TonUINO 2.0 and adds these
# | title | description | next | previous |
---|---|---|---|---|
7 | Von-Bis Hörspiel | play a random file from the folder between special and special2 | stop | start title again from the beginning |
8 | Von-Bis Album | play all files between special and special2 | next file | start title again from the beginning |
9 | Von-Bis Party | play all files between special and special2 in random order | random file | start title again from the beginning |
All have a folder value of 0
Modifier | byte 6 | byte 7 | Description |
---|---|---|---|
SleepTimer | 1 | Play duration in minutes (255 max) | Pauses playback after timer |
FreezeDance | 2 | - | Randomly pauses the track after 5 to 30 seconds |
Locked | 3 | - | All buttons are locked and no new card will be read |
ToddlerMode | 4 | - | All buttons are locked |
KindergartenMode | 5 | - | Previous and back buttons are locked. Adding a new card will not stop the current track but will schedule it as next track |
RepeatSingleModifier | 6 | - | Repeat current track |
FeedbackModifier | 7 | - | Will e.g. tell volume before changing it |
Is a full rewrite of the original TonUINO software in C++
Different Modes
It supports all modes of TonUINO 2.1 and adds these
# | title | description | next | previous |
---|---|---|---|---|
10 | Hörbuch Einzeln | Play the next file from the folder and store the progress | stop | start title again from the beginning |
11 | Repeat last | Repeat the last card or shortcut | ?? | ?? |
12 | Quiz game | See tonuino/TonUINO-TNG#155 | ?? | ?? |
13 | Memory game | See tonuino/TonUINO-TNG#176 | ?? | ?? |
14 | Bluetooth | See tonuino/TonUINO-TNG#215 |
Wiederhole Karte Modus: die letzte Karte oder der letzte Shortcut wird wiederholt.
Same as TonUINO 2.1 but replaced the FeedbackModifier
card with value 7
with Bluetooth pairing
Modifier | byte 6 | byte 7 | Description |
---|---|---|---|
Bluetooth | 7 | - | See tonuino/TonUINO-TNG#215 |
It would be great if the app also can act as an NFC tag to simulate TonUINO tags, some links to this: Official Android docs
From a question on Mifare support forum:
Here is a very good example https://github.com/grundid/host-card-emulation-sample which will write to you "Hello Desktop!" The App emulates a MIFARE card with this AID 0xF0, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 You should make your self familiar with the HCE code.
In the other side you should have an NFC reader (in your case MIFARE NFC) which will be looking for the same AID as in the HCE App. Normally you should send this cmd to the Android phone from your reader after you have brought the two devices close enough 0x00 [CLA], 0xA4 [INS], 0x04, 0x00, 0x07 [Lc], 0xF0, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x00 [Le]
Explanation of how discovered NFC tags are dispatched to activities in Android
Currently only Mifare Classic and Ultralight are supported, but in case generic NfcA support is wished, start with these links:
- Android Tag Technology (NfcA, NfcB, ..)
- Stackoverflow answer that also contains a command overview of NfcA commands
- Stackoverflow answer with general help on NfcA
- Summary of Open Source projects using Android's NfcA API
- Example of writing NTAG215 tags (for cloning Amiibos)
- ...but they use Mifare Ultralight
- Explanation how to use it