Skip to content

Instantly share code, notes, and snippets.

@PaulCreusy
Created October 22, 2024 20:09
Show Gist options
  • Save PaulCreusy/47de0bac3d050b5dba8022d4101621fe to your computer and use it in GitHub Desktop.
Save PaulCreusy/47de0bac3d050b5dba8022d4101621fe to your computer and use it in GitHub Desktop.
NFC Reader Android application with Python and Kivy
__version__ = '1.0'
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.clock import Clock
# Android NFC-specific imports
from jnius import autoclass, cast
from android import activity
# Accessing Android NFC Java classes
Context = autoclass('android.content.Context')
NfcAdapter = autoclass('android.nfc.NfcAdapter')
NfcAdapterReader = autoclass('android.nfc.NfcAdapter$ReaderCallback')
Ndef = autoclass('android.nfc.tech.Ndef')
NdefMessage = autoclass('android.nfc.NdefMessage')
Intent = autoclass('android.content.Intent')
PendingIntent = autoclass('android.app.PendingIntent')
IntentFilter = autoclass('android.content.IntentFilter')
NfcAdapter = autoclass('android.nfc.NfcAdapter')
class NFCReaderApp(App):
def build(self):
self.layout = BoxLayout(orientation='vertical')
self.label = Label(text="Please scan your NFC card", font_size=42)
self.layout.add_widget(self.label)
# Schedule the setup of NFC adapter after the app starts
Clock.schedule_once(self.setup_nfc, 0)
return self.layout
def setup_nfc(self, dt):
# Get the current Android activity and context
self.activity = autoclass('org.kivy.android.PythonActivity').mActivity
self.context = self.activity.getApplicationContext()
# Get the NFC Adapter
self.nfc_adapter = NfcAdapter.getDefaultAdapter(self.context)
if not self.nfc_adapter:
self.label.text = "NFC not supported on this device."
return
# Create a PendingIntent to start your app when an NFC tag is discovered
intent = Intent(self.context, self.activity.getClass())
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
self.pending_intent = PendingIntent.getActivity(
self.context, 0, intent, 0)
# Create an intent filter for detecting NFC tags
nfc_intent_filter = IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED)
self.nfc_intent_filter = [nfc_intent_filter]
# Enable foreground dispatch to ensure the app catches NFC intents
self.nfc_adapter.enableForegroundDispatch(
self.activity, self.pending_intent, self.nfc_intent_filter, None)
# Bind activity lifecycle events to properly manage NFC (pause/resume)
activity.bind(on_new_intent=self.on_new_intent)
def on_pause(self):
# Disable NFC foreground dispatch when the app goes to background
# self.disable_nfc_foreground_dispatch()
return True
def on_resume(self):
# Re-enable NFC foreground dispatch when the app is resumed
self.enable_nfc_foreground_dispatch()
def enable_nfc_foreground_dispatch(self, *args):
print("enable nfc")
if self.nfc_adapter:
self.nfc_adapter.enableForegroundDispatch(
self.activity, self.pending_intent, self.nfc_intent_filter, None)
def disable_nfc_foreground_dispatch(self, *args):
print("disable nfc")
if self.nfc_adapter:
self.nfc_adapter.disableForegroundDispatch(self.activity)
def on_new_intent(self, intent):
# This method is called when an NFC intent is received
action = intent.getAction()
if action == NfcAdapter.ACTION_TAG_DISCOVERED:
self.handle_nfc_tag(intent)
def handle_nfc_tag(self, intent):
# Get the tag from the intent and cast it to android.nfc.Tag
tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)
if tag is not None:
# Cast the Parcelable tag to the correct Tag object
tag = cast('android.nfc.Tag', tag)
# Get the tag's UID (Unique Identifier)
tag_id = tag.getId()
tag_uid = ''.join('{:02X}'.format(byte)
for byte in tag_id) # Convert to hexadecimal format
# Get the list of technologies supported by the tag
tech_list = tag.getTechList()
# Display the UID and technology list in the app
self.label.text = f"Tag UID: {tag_uid}\nTechnologies: {tech_list}"
else:
self.label.text = "No valid NFC tag detected."
if __name__ == "__main__":
NFCReaderApp().run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment