How to read Nfc tags in android?
How can i read and display the NDEF messages from NFC tags? Please help me. Can any开发者_如何学JAVAone provide the sample source code to read the Nfc tag?
1) The general description of the NFC on android is here
2) The NFCDemo is here
3) Very good information are also here
4) Also the book "Programming Android" from "Zigurd Mednieks" has a chapter about the NFC
BR
STeN
We have two option to read the nfc card.
Read from cache
Ndef ndef = Ndef.get(tag); if (ndef == null) { // NDEF is not supported by this Tag. return null; } NdefMessage ndefMessage = ndef.getCachedNdefMessage(); if (ndefMessage == null) { mTextView.setText("The tag is empty !"); return null; } NdefRecord[] records = ndefMessage.getRecords(); for (NdefRecord ndefRecord : records) { if (ndefRecord.getTnf() == NdefRecord.TNF_WELL_KNOWN && Arrays.equals(ndefRecord.getType(), NdefRecord.RTD_TEXT)) { try { return readText(ndefRecord); } catch (UnsupportedEncodingException e) { Log.e(TAG, "Unsupported Encoding", e); } } }
Read directly by using
public void readFromTag(Intent intent){
Ndef ndef = Ndef.get(detectedTag);
try{
ndef.connect();
txtType.setText(ndef.getType().toString());
txtSize.setText(String.valueOf(ndef.getMaxSize()));
txtWrite.setText(ndef.isWritable() ? "True" : "False");
Parcelable[] messages = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
if (messages != null) {
NdefMessage[] ndefMessages = new NdefMessage[messages.length];
for (int i = 0; i < messages.length; i++) {
ndefMessages[i] = (NdefMessage) messages[i];
}
NdefRecord record = ndefMessages[0].getRecords()[0];
byte[] payload = record.getPayload();
String text = new String(payload);
txtRead.setText(text);
ndef.close();
}
}
catch (Exception e) {
Toast.makeText(getApplicationContext(), "Cannot Read From Tag.", Toast.LENGTH_LONG).show();
}
}
- Make sure the AndroidManifest.xml file contains the use-permision, intent-filter and meta-data for the NFC, it should look like this.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.mynfcreader">
<uses-permission android:name="android.permission.NFC" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.MyNFCReader">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
<meta-data
android:name="android.nfc.action.TECH_DISCOVERED"
android:resource="@xml/nfc_filter" />
</activity>
</application>
</manifest>
- Create the xml file nfc_filter.xml referenced in the above manifest file, at the res/xml folder, create the xml folder if it is not yet there, the content should contain the following.
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<tech-list>
<tech>android.nfc.tech.Ndef</tech>
<!-- class name -->
</tech-list>
</resources>
- activity_main.xml the layout file with a TextView for displaying the message read from NFC tag.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/nfc_contents"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:padding="32dp"
android:textAlignment="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
- The MainActivity.kt with the code for reading message from NFC tag and displaying it to the screen.
package com.example.mynfcreader
import android.app.PendingIntent
import android.content.Intent
import android.content.IntentFilter
import android.nfc.NdefMessage
import android.nfc.NfcAdapter
import android.nfc.Tag
import android.os.Bundle
import android.os.Parcelable
import android.util.Log
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.example.mynfcreader.databinding.ActivityMainBinding
import java.io.UnsupportedEncodingException
import java.nio.charset.Charset
import kotlin.experimental.and
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var tvNFCContent: TextView
private lateinit var nfcAdapter: NfcAdapter
private lateinit var pendingIntent: PendingIntent
var myTag: Tag? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
tvNFCContent = binding.nfcContents
tvNFCContent.text = "Place the back of the phone over a NFC tag to read message from NFC tag"
nfcAdapter = NfcAdapter.getDefaultAdapter(this)
if (nfcAdapter == null) {
// Stop here, we definitely need NFC
Toast.makeText(this, "This device doesn't support NFC.", Toast.LENGTH_LONG).show()
finish()
}
readFromIntent(intent)
pendingIntent = PendingIntent.getActivity(
this,
0,
Intent(this, javaClass).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),
0
)
val tagDetected = IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED)
tagDetected.addCategory(Intent.CATEGORY_DEFAULT)
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
readFromIntent(intent)
}
private fun readFromIntent(intent: Intent) {
val action = intent.action
if (NfcAdapter.ACTION_TAG_DISCOVERED == action || NfcAdapter.ACTION_TECH_DISCOVERED == action || NfcAdapter.ACTION_NDEF_DISCOVERED == action) {
myTag = intent.getParcelableExtra<Parcelable>(NfcAdapter.EXTRA_TAG) as Tag?
val rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)
var msgs = mutableListOf<NdefMessage>()
if (rawMsgs != null) {
for (i in rawMsgs.indices) {
msgs.add(i, rawMsgs[i] as NdefMessage)
}
buildTagViews(msgs.toTypedArray())
}
}
}
private fun buildTagViews(msgs: Array<NdefMessage>) {
if (msgs == null || msgs.isEmpty()) return
var text = ""
val payload = msgs[0].records[0].payload
val textEncoding: Charset = if ((payload[0] and 128.toByte()).toInt() == 0) Charsets.UTF_8 else Charsets.UTF_16 // Get the Text Encoding
val languageCodeLength: Int = (payload[0] and 51).toInt() // Get the Language Code, e.g. "en"
try {
// Get the Text
text = String(
payload,
languageCodeLength + 1,
payload.size - languageCodeLength - 1,
textEncoding
)
} catch (e: UnsupportedEncodingException) {
Log.e("UnsupportedEncoding", e.toString())
}
tvNFCContent.text = "Message read from NFC Tag:\n $text"
}
}
- Install the app on an Android phone, and place the back of the android phone over a NFC tag, the app will be launched and displays message on the screen if the NFC tag has any messages stored on it.
精彩评论