I'm trying to send large string from device to device with NFC. I understand that is possible in specs? But how to do it?
At the moment I have this kind of solution
NdefRecord data = NdefRecord.createExternal("A", "ROW2", selected.substring(0, 4000).getBytes(Charset.forName("UTF-8")));
NdefMessage msg = new NdefMessage(new NdefRecord[]{
data
});
Log.d(TAG, msg.getByteArrayLength() + " Byte array");
nfcAdapter.setNdefPushMessage(msg, this, this);
I try to send string from 0 to 4000 but it don't work.
Related
I'm trying to write to a tag but I don't want to send a text, I want to send an array of bytes because that way I'll have a better sending control and I'll be able to establish fixed data according to the position of the array when I read it, I was investigating and I didn't find anything in particular .
The tag I have has NfcV and Ndef as techlist. I tried MifareClassic but it doesn't show up as null. Any other ideas please.
I want to emphasize that the byte array must be exclusively the data that I send, because I have seen other scripts like NdefRecord but they respect parameters at the beginning of the frame by writing data that I do not want but that function needs it to write.
private void write(String text, Tag tag) throws IOException, FormatException {
//byte[] data= Const.ResponseDataDeviceWrite;
//NdefRecord records = new NdefRecord(data);
// NdefRecord[] records = { createRecord(text) };
byte[] data = {66,104,111,108,97,32,32,32,32,32,32,32,32};
//records=data;
// NdefMessage message = new NdefMessage(records);
//NdefMessage message = createRecord(text);
// Get an instance of Ndef for the tag.
Ndef ndef = Ndef.get(tag);
// If Ndef.get is null then try formatting it and adding message
if (ndef != null) {
// Enable I/O
ndef.connect();
// Write the message
/* NdefRecord[] records = {
NdefRecord.createMime("text/plain", data)
};*/
//NdefMessage message = new NdefMessage(data);
ndef.writeNdefMessage(new NdefMessage(new NdefRecord(NdefRecord.TNF_UNKNOWN, null, null, data)));
//ndef.writeNdefMessage(message);
// Close the connection
ndef.close();
} else {
NdefFormatable ndefFormatable = NdefFormatable.get(tag);
// Really should do a null test on ndefFormatable here but as the code is looking for an exception don't test for null
ndefFormatable.connect();
// Format at write message at the same time
// ndefFormatable.format(message);
ndefFormatable.close();
}
}
Example what came out in writing and what should be, previously it was possible to write but in an application in c#
enter image description here
There is a Mifare Classic-specific solution as they have a java library. You just need to identify the tag as MifareClassic and then you can use the writeBlock() method.
https://developer.android.com/reference/android/nfc/tech/MifareClassic#writeBlock(int,%20byte[])
You can initalize a tag using for example
MifareClassic mifareTag = MifareClassic.get(tag);
Make sure to import android.nfc.tech.MifareClassic;
Im new on this about working with arduino cards and i have a problem, because i have done an application to send a "STRING" from my android phone to another via nfc, and that worked very well... but the thing is when i started to work with a nfc card adafruit pn532, it can't recieve anything and i'd like to know if you can help me or if you have done this before.. thanks!
#Override
protected void onNewIntent(Intent intent) {
if (intent.getAction().equals(NfcAdapter.ACTION_TAG_DISCOVERED)) {
/*String result = "";
Toast.makeText(this, "Etiqueta NFC detectada", Toast.LENGTH_SHORT).show();
result = ByteArrayToHexString(intent.getByteArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES));
etiqueta = result;
mEditText.setText(etiqueta);*/
Parcelable[] rawMessages = intent.getParcelableArrayExtra(
NfcAdapter.EXTRA_NDEF_MESSAGES);
NdefMessage message = (NdefMessage) rawMessages[0]; // only one message transferred
mEditText.setText(new String(message.getRecords()[0].getPayload()));
}}
#Override
public NdefMessage createNdefMessage(NfcEvent nfcEvent) {
String message = mEditText.getText().toString();
NdefRecord ndefRecord = NdefRecord.createMime("text/plain", message.getBytes());
NdefMessage ndefMessage = new NdefMessage(ndefRecord);
return ndefMessage;
}
Is there any tutorial or example that explains how I can make my android program write a specific contact (name and phone number) to NFC tag. So when the user touches the tag with his phone, it saves the contact to his phone contacts?
Yes. Using the VCARD type.
Inside your NFC event intent handler, use this method to build your NdefRecord:
public NdefRecord createVcardRecord(String name, String org, String tel, String email)
throws UnsupportedEncodingException {
String payloadStr = "BEGIN:VCARD" +"\n"+
"VERSION:2.1" +"\n" +
"N:;" + name + "\n" +
"ORG:"+org+"\n"+
"TEL:"+tel+"\n"+
"EMAIL:"+email+"\n
"+"END:VCARD";
byte[] uriField = payloadStr.getBytes(Charset.forName("US-ASCII"));
byte[] payload = new byte[uriField.length + 1];
System.arraycopy(uriField, 0, payload, 1, uriField.length);
NdefRecord nfcRecord = new NdefRecord(NdefRecord.TNF_MIME_MEDIA,
"text/vcard".getBytes(),
new byte[0],
payload);
return nfcRecord;
}
Then add the record to your records array:
NdefRecord[] records = new NdefRecord[1];
records[0] = createVcardRecord("Henry", "Henry's Company", "0412345678", "henry#domain.com");
Pass the records array into an NdefMessage and you are ready to write:
NdefMessage message = new NdefMessage(records);
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
writeToTag(message, tag); // your tag writing function
I'm trying the following:
Write a message to an NFC tag that contains a reference to my application as well as a short string with which I can identify the tag.
Read that message.
To speed up testing a bit at the beginning I've used the app Tagwriter (https://play.google.com/store/apps/details?id=com.nxp.nfc.tagwriter&hl=de) to write a tag with my needs: "Create plain text" and "Add launch application" in the next window.
Upon contact with the tag my phone will start up my application, it'll even read the identifying string correctly. However I also want it to write the tag from my own application instead of referring to another one.
I've tested several approaches, none of them worked. Either my application isn't started at all or it can't read the string. Can anyone help me?
public static boolean writeTag(String textToWrite, Tag tag)
{
Miscellaneous.logEvent("i", "NFC", "Attempting to write tag...", 2);
String packageName = Miscellaneous.getAnyContext().getPackageName();
NdefRecord appRecord = NdefRecord.createApplicationRecord(packageName);
// Record with actual data we care about
NdefRecord textRecord = new NdefRecord(NdefRecord.TNF_MIME_MEDIA,
new String("application/" + packageName)
.getBytes(Charset.forName("US-ASCII")),
null, textToWrite.getBytes());
// Complete NDEF message with both records
NdefMessage completeMessageToWrite = new NdefMessage(new NdefRecord[] {textRecord, appRecord});
int size = completeMessageToWrite.toByteArray().length;
try
{
Ndef ndef = Ndef.get(tag);
if (ndef != null)
{
ndef.connect();
if (ndef.isWritable() && ndef.getMaxSize() > size)
{
ndef.writeNdefMessage(completeMessageToWrite);
Miscellaneous.logEvent("i", "NFC", "Done writing tag.", 2);
return true;
}
}
else
{
NdefFormatable format = NdefFormatable.get(tag);
if (format != null)
{
try
{
format.connect();
format.format(completeMessageToWrite);
Miscellaneous.logEvent("i", "NFC", "Done writing tag.", 2);
return true;
}
catch(IOException e)
{
Miscellaneous.logEvent("e", "NFC", "Error writing tag: " + Log.getStackTraceString(e), 2);
}
}
}
}
catch(Exception e)
{
Miscellaneous.logEvent("e", "NFC", "Error writing tag: " + Log.getStackTraceString(e), 2);
}
return false;
}
I'm sorry, could have been a bit more detailed. It appears I kind of solved my problem myself. I've been taking a bit of example code from this website and a bit from that website and...
That's why I had to first do some cleaning up before answering here. In that process I kind of found the mistake. The write-function now looks like this:
public static boolean writeTag(String textToWrite, Tag tag)
{
Miscellaneous.logEvent("i", "NFC", "Attempting to write tag...", 2);
String packageName = Miscellaneous.getAnyContext().getPackageName();
NdefRecord appRecord = NdefRecord.createApplicationRecord(packageName);
// Record with actual data we care about
byte[] textBytes = textToWrite.getBytes();
byte[] textPayload = new byte[textBytes.length + 3];
textPayload[0] = 0x02; // 0x02 = UTF8
textPayload[1] = 'e'; // Language = en
textPayload[2] = 'n';
System.arraycopy(textBytes, 0, textPayload, 3, textBytes.length);
NdefRecord textRecord = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], textPayload);
// Complete NDEF message with both records
NdefMessage completeMessageToWrite = new NdefMessage(new NdefRecord[] {textRecord, appRecord});
[...]
}
It appears the "apprecord" was fine, but the text record was not.
I am writing an Android App that is using NFC tags in order to transfer some information. For the moment I have the read function which reads the content from the NFC tag:
protected NdefMessage[] getNdefMessages(Intent intent) {
// Parse the intent
NdefMessage[] msgs = null;
String action = intent.getAction();
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)
|| NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
Parcelable[] rawMsgs =
intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
if (rawMsgs != null) {
msgs = new NdefMessage[rawMsgs.length];
for (int i = 0; i < rawMsgs.length; i++) {
msgs[i] = (NdefMessage) rawMsgs[i];
}
} else {
// Unknown tag type
byte[] empty = new byte[] {};
NdefRecord record = new NdefRecord(NdefRecord.TNF_UNKNOWN, empty, empty, empty);
NdefMessage msg = new NdefMessage(new NdefRecord[] {
record
});
msgs = new NdefMessage[] {
msg
};
}
} else {
finish();
}
return msgs;
}
Now, I would like to add security to the communication, that is SSL. However, I really don't know what steps do I have to take in order to implement this functionality.
Is there some NFCSecurity class or something like that, that does all the work for you?
Any idea?
The Android NFC API gives you access to both the (low-level) tag communication and the (high-level) NDEF message storage on a tag (or transferred via Android Beam).
Adding security to that, while still retaining the benefits of automatic NDEF message reading and writing, could be done by, for example, encrypting the payload of the NdefRecord you use.
SSL/TLS works on the connection level. There are no tags that support such a thing, as far as I am aware. You could consider adding SSL/TLS to NFC peer-to-peer communication, but that does currently not exist. It would involve modifying the Android NFC stack and building a custom Android system image (if it is possible at all). It is not something that can be added on top of Android Beam by an app.