{"id":24501068,"url":"https://github.com/androidcrypto/androidbasicnfcreader","last_synced_at":"2025-06-22T16:33:56.514Z","repository":{"id":257221026,"uuid":"856809962","full_name":"AndroidCrypto/AndroidBasicNfcReader","owner":"AndroidCrypto","description":"This app is a basic NFC reader demonstrating the Reader Mode technology for accessing NFC tags.","archived":false,"fork":false,"pushed_at":"2024-09-18T15:50:30.000Z","size":485,"stargazers_count":5,"open_issues_count":0,"forks_count":4,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-04-01T00:34:29.579Z","etag":null,"topics":["android","nfc","nfc-card-reader","nfc-reader","reader-mode"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AndroidCrypto.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-09-13T08:46:52.000Z","updated_at":"2025-02-13T10:13:39.000Z","dependencies_parsed_at":"2025-01-21T22:29:03.831Z","dependency_job_id":null,"html_url":"https://github.com/AndroidCrypto/AndroidBasicNfcReader","commit_stats":null,"previous_names":["androidcrypto/androidbasicnfcreader"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AndroidCrypto%2FAndroidBasicNfcReader","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AndroidCrypto%2FAndroidBasicNfcReader/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AndroidCrypto%2FAndroidBasicNfcReader/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AndroidCrypto%2FAndroidBasicNfcReader/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AndroidCrypto","download_url":"https://codeload.github.com/AndroidCrypto/AndroidBasicNfcReader/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253776565,"owners_count":21962508,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","nfc","nfc-card-reader","nfc-reader","reader-mode"],"created_at":"2025-01-21T22:23:09.920Z","updated_at":"2025-05-12T16:30:06.512Z","avatar_url":"https://github.com/AndroidCrypto.png","language":"Java","readme":"# Android Basic NFC Reader\n\nThis is a simple app showing how to detect and read some data from an NFC tag tapped to the Android's NFC reader.\n\nAs there are a lot of questions on Stackoverflow.com that use an **Intent-based** NFC detection system I'm showing here how to use the more modern **Reader Mode** for NFC communication.\n\nThis is from an answer by *[Andrew](https://stackoverflow.com/users/2373819/andrew)* regarding the two modes:\n\n*Also note that using enableForegroundDispatch is actually not the best way to use NFC. Using enableReaderMode is a newer and much better API to use. NFC.enableReaderMode does not use Intent's and gives you more control, it is easy to do NFC operations in a background Thread (which is recommended), for writing to NFC Tag's it is much more reliable and leads to less errors.*\n\nThis application is described in an tutorial on medium.com: **[How to use NFC Reader Mode in Android to connect to NFC tags (Java)](https://medium.com/@androidcrypto/how-to-use-nfc-reader-mode-in-android-to-connect-to-nfc-tags-java-d70641a5def4)**\n\nThere are 4 simples steps to **implement the Reader mode**:\n\n1) in `AndroidManifest.xml` add one line: `\u003cuses-permission android:name=\"android.permission.NFC\" /\u003e`\n2) in your activity or fragment expand your class definition by `implements NfcAdapter.ReaderCallback`\n3) create an `onTagDiscovered` method where all the work with the tag is done.\n4) create an `onResume` method to define the technologies and settings for the Reader Mode:\n\n```plaintext\n@Override                                                                                      \nprotected void onResume() {                                                                    \n    super.onResume();                                                                          \n    if (myNfcAdapter != null) {                                                                \n        if (!myNfcAdapter.isEnabled())                                                         \n            showWirelessSettings();                                                            \n        Bundle options = new Bundle();                                                         \n        // Work around for some broken Nfc firmware implementations that poll the card too fast\n        options.putInt(NfcAdapter.EXTRA_READER_PRESENCE_CHECK_DELAY, 250);                     \n        // Enable ReaderMode for all types of card and disable platform sounds                 \n        // The option NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK is NOT set                        \n        // to get the data of the tag after reading                                            \n        myNfcAdapter.enableReaderMode(this,                                                    \n                this,                                                                          \n                NfcAdapter.FLAG_READER_NFC_A |                                                 \n                        NfcAdapter.FLAG_READER_NFC_B |                                         \n                        NfcAdapter.FLAG_READER_NFC_F |                                         \n                        NfcAdapter.FLAG_READER_NFC_V |                                         \n                        NfcAdapter.FLAG_READER_NFC_BARCODE |                                   \n                        NfcAdapter.FLAG_READER_NO_PLATFORM_SOUNDS,                             \n                options);                                                                      \n    }                                                                                          \n}                                                                                              \n```\nThe flags are responsible for defining the NFC classes the NFC reader should detect. If you e.g. delete \nthe line `NfcAdapter.FLAG_READER_NFC_A` your app will not detect any NFC tags using the NfcA technology.  \n\nThe last flag `NfcAdapter.FLAG_READER_NO_PLATFORM_SOUNDS` is useful for a better user experience. Using \nthe **Intent based** mode a system sound will appear when the NFC tag is detected **at the beginning**. \nThis causes some uses to move the NFC tag out of the reader field and you receive a \"Tag Lost Exception\". \nWhen using the **Reader Mode** the flag prohibits the device to give any feedback to the user. In my app \nI'm playing a short *beep* **at the end** or the reading process, signalizing that everything is done. \n\nNote: **the `onTagDetected` method is not running on the User Interface (UI) thread**, so you are not allowed to write directly to any UI elements like \ne.g. TextViews or Toasts - you need to encapsulate them in a `run onUiTHread` construct. This method is running in an background thread:\n```plaintext\nrunOnUiThread(() -\u003e {\n   Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();\n});\n```\n\n## Steps to read an NFC tag using Reader Mode\n\nHere are some commands to get the first information's about the tag:\n\n`byte[] tagUid = tag.getId();`: receive the tag Unique Identifier (the length depending on tag type).\n`String[] techlist = tag.getTechList();`: this is very important as the **NFC tag informs us about the NFC technologies \nit is been able to communicate** with us (e.g. *android.nfc.tech.NfcA*).\n\nNow it is time to **assign the received tag to an NFC technology class**, e.g. to the NDEF class. It is \nimportant to double check that the ndef variable is not NULL to avoid any errors. If e.g. the ndef-var is not \nnull you can **connect** to the NFC tag. Always surround the tag operations with a *try.. catch* clause.\n\n### Example workflow for an NfcA type tag\n\nFrom the tag I'm getting the *ATQA* and *SAK* value - they are required to identify an NfcA tag on the first level. \nThe *maxTransceiveLength* is important when trying to read data from tag - if the data length including some \nprotocol bytes is extending this maximum you will receive an error from your device, as the maximum is the \nsize of your device's NFC reader unit.\n\nThe next steps would be to send commands to the tag using the `transceive` method. I don't show any code for this \nwithin the app as commands are tag specific.\n\nPlease don't forget to close the NfcA class after your work is done. \n\n```plaintext\nNfcA nfcA = null;                                                               \nnfcA = NfcA.get(tag);                                                           \nif (nfcA == null) {                                                             \n    output += \"This tag is NOT supporting the NfcA class\" + \"\\n\";               \n    output += lineDivider + \"\\n\";                                               \n} else {                                                                        \n    // I'm trying to get more information's about the tag and connect to the tag\n    byte[] atqa = nfcA.getAtqa();                                               \n    byte sak = (byte) nfcA.getSak();                                            \n    int maxTransceiveLength = nfcA.getMaxTransceiveLength();                    \n                                                                                \n    output += \"-= NfcA Technology =-\" + \"\\n\";                                   \n    output += \"ATQA: \" + bytesToHex(atqa) + \"\\n\";                               \n    output += \"SAK: \" + byteToHex(sak) + \"\\n\";                                  \n    output += \"maxTransceiveLength: \" + maxTransceiveLength + \"\\n\";             \n    output += lineDivider + \"\\n\";                                               \n                                                                                \n    try {                                                                       \n        nfcA.connect();                                                         \n        output += \"Connected to the tag using NfcA technology\" + \"\\n\";          \n        output += lineDivider + \"\\n\";                                           \n        nfcA.close();                                                           \n    } catch (IOException e) {                                                   \n        output += \"NfcA connect to tag IOException: \" + e.getMessage() + \"\\n\";  \n        output += lineDivider + \"\\n\";                                           \n    }                                                                           \n}                                                                               \n```\n\n### Example workflow for an NDEF Message\n\nThis example has a very limited NDEF workflow and just print out the raw NDEF data. Usually you will divide \nthe NDEF Message in separate NDEF records and work with the data depending on the NDEF Record type (not shown \nin this app).\n\nPlease don't forget to close the technology after reading is done.\n\n```plaintext\nNdef ndef = null;                                                                                    \nndef = Ndef.get(tag);                                                                                \nif (ndef == null) {                                                                                  \n    output += \"This tag is NOT supporting the NDEF class\" + \"\\n\";                                    \n    output += lineDivider + \"\\n\";                                                                    \n} else {                                                                                             \n    try {                                                                                            \n        ndef.connect();                                                                              \n        output += \"Connected to the tag using NDEF technology\" + \"\\n\";                               \n        output += lineDivider + \"\\n\";                                                                \n        NdefMessage ndefMessage = ndef.getNdefMessage();                                             \n        String ndefMessageString = ndefMessage.toString();                                           \n        byte[] ndefMessageBytes = ndefMessage.toByteArray();                                         \n        output += \"NDEF message: \" + ndefMessageString + \"\\n\";                                       \n        if (ndefMessageBytes != null) {                                                              \n            output += \"NDEF message: \" + bytesToHex(ndefMessageBytes) + \"\\n\";                        \n            output += \"NDEF message: \" + new String(ndefMessageBytes, StandardCharsets.UTF_8) + \"\\n\";\n        }                                                                                            \n        output += lineDivider + \"\\n\";                                                                \n        ndef.close();                                                                                \n    } catch (IOException e) {                                                                        \n        output += \"NDEF connect to tag IOException: \" + e.getMessage() + \"\\n\";                       \n        output += lineDivider + \"\\n\";                                                                \n    } catch (FormatException e) {                                                                    \n        output += \"NDEF connect to tag RunTimeException: \" + e.getMessage() + \"\\n\";                  \n        output += lineDivider + \"\\n\";                                                                \n    }                                                                                                \n}                                                                                                    \n```\n\n## Screen after reading a tag with an NDEF message\n\n![Screen of the Main](screenshot/small/app_home_01.png)\n\n## Example outputs for some tag types\n\nBelow you find outputs for some tags with different technologies involved:\n\n### Example for an NTAG216 tag with NfcA technology:\n```plaintext\nNFC tag detected\nTag UID length: 7 UID: 04be7982355b80\n--------------------\nThe TechList contains 3 entry/ies:\nEntry 0: android.nfc.tech.NfcA\nEntry 1: android.nfc.tech.MifareUltralight\nEntry 2: android.nfc.tech.NdefFormatable\n--------------------\nTAG: Tech [android.nfc.tech.NfcA, android.nfc.tech.MifareUltralight, android.nfc.tech.NdefFormatable]\n--------------------\n-= NfcA Technology =-\nATQA: 4400\nSAK: 00\nmaxTransceiveLength: 253\n--------------------\nConnected to the tag using NfcA technology\n--------------------\nThis tag is NOT supporting the NfcV class\n--------------------\nThis tag is NOT supporting the NDEF class\n--------------------\n```\n\n### Example for an NTAG216 tag containing an NDEF message:\n```plaintext\nNFC tag detected\nTag UID length: 7 UID: 04be7982355b80\n--------------------\nThe TechList contains 3 entry/ies:\nEntry 0: android.nfc.tech.NfcA\nEntry 1: android.nfc.tech.MifareUltralight\nEntry 2: android.nfc.tech.Ndef\n--------------------\nTAG: Tech [android.nfc.tech.NfcA, android.nfc.tech.MifareUltralight, android.nfc.tech.Ndef]\n--------------------\n-= NfcA Technology =-\nATQA: 4400\nSAK: 00\nmaxTransceiveLength: 253\n--------------------\nConnected to the tag using NfcA technology\n--------------------\nThis tag is NOT supporting the NfcV class\n--------------------\nConnected to the tag using NDEF technology\n--------------------\nNDEF message: NdefMessage [NdefRecord tnf=1 type=54 payload=02656E416E64726F696443727970746F]\nNDEF message: d101105402656e416e64726f696443727970746f\nNDEF message: enAndroidCrypto\n```\n\n### Example for a MIFARE Classic tag:\n```plaintext\nNFC tag detected\nTag UID length: 4 UID: 641a35cf\n--------------------\nThe TechList contains 3 entry/ies:\nEntry 0: android.nfc.tech.NfcA\nEntry 1: android.nfc.tech.MifareClassic\nEntry 2: android.nfc.tech.NdefFormatable\n--------------------\nTAG: Tech [android.nfc.tech.NfcA, android.nfc.tech.MifareClassic, android.nfc.tech.NdefFormatable]\n--------------------\n-= NfcA Technology =-\nATQA: 0400\nSAK: 08\nmaxTransceiveLength: 253\n--------------------\nConnected to the tag using NfcA technology\n--------------------\nThis tag is NOT supporting the NfcV class\n--------------------\nThis tag is NOT supporting the NDEF class\n--------------------\n```\n\n### Example for an NFC enabled Credit Card:\n```plaintext\nNFC tag detected\nTag UID length: 4 UID: b58fcc6d\n--------------------\nThe TechList contains 2 entry/ies:\nEntry 0: android.nfc.tech.IsoDep\nEntry 1: android.nfc.tech.NfcA\n--------------------\nTAG: Tech [android.nfc.tech.IsoDep, android.nfc.tech.NfcA]\n--------------------\n-= NfcA Technology =-\nATQA: 0400\nSAK: 20\nmaxTransceiveLength: 253\n--------------------\nConnected to the tag using NfcA technology\n--------------------\nThis tag is NOT supporting the NfcV class\n--------------------\nThis tag is NOT supporting the NDEF class\n--------------------\n```\n\n### Example for an ICODE SLIX tag with NfcV technology:\n```plaintext\nNFC tag detected\nTag UID length: 8 UID: 18958608530104e0\n--------------------\nThe TechList contains 2 entry/ies:\nEntry 0: android.nfc.tech.NfcV\nEntry 1: android.nfc.tech.NdefFormatable\n--------------------\nTAG: Tech [android.nfc.tech.NfcV, android.nfc.tech.NdefFormatable]\n--------------------\nThis tag is NOT supporting the NfcA class\n--------------------\n-= NfcV Technology =-\nDsfId: 00\nmaxTransceiveLength: 253\n--------------------\nConnected to the tag using NfcV technology\n--------------------\nThis tag is NOT supporting the NDEF class\n--------------------\n```\n\n## License\n\nAndroid Basic NFC Reader is available under the MIT license. See the LICENSE.md file for more info.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandroidcrypto%2Fandroidbasicnfcreader","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandroidcrypto%2Fandroidbasicnfcreader","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandroidcrypto%2Fandroidbasicnfcreader/lists"}