I'm trying to write and read to/from multiple records in a NDEFMessage. Is my code here right? Also, my process terminates itself when I'm reading the tag. I'm not sure where I went wrong..
Writing part:
private NdefMessage getTagAsNdef() {
String text123="Hello";
//boolean addAAR = true;
String uniqueId = "starbucks.com";
byte[] uriField = uniqueId.getBytes(Charset.forName("US-ASCII"));
byte[] payload = new byte[uriField.length + 1]; //add 1 for the URI Prefix
payload[0] = 0x01; //prefixes http://www. to the URI
System.arraycopy(uriField, 0, payload, 1, uriField.length); //appends URI to payload
NdefRecord rtdUriRecord = new NdefRecord(
NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_URI, new byte[0], payload);
//Wi-FI test writing code
byte[] textbytes = text123.getBytes();
NdefRecord textRecord = new NdefRecord(NdefRecord.TNF_WELL_KNOWN,
text123.getBytes(), new byte[]{}, textbytes);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
// note: returns AAR for different app (couponmanager)
return new NdefMessage(new NdefRecord[] {
rtdUriRecord, textRecord, NdefRecord.createApplicationRecord("com.example.ponpon")
});
} else {
return new NdefMessage(new NdefRecord[] {
rtdUriRecord,textRecord});
}
}
Reading part:
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
SharedPreferences preferences = getSharedPreferences(PREF_FILE_NAME, MODE_PRIVATE);
int storedPreference = preferences.getInt("storedInt", 0);
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) {
NdefMessage[] messages = null;
Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
if (rawMsgs != null) {
messages = new NdefMessage[rawMsgs.length];
for (int i = 0; i < rawMsgs.length; i++) {
messages[i] = (NdefMessage) rawMsgs[i];
}
}
if(messages[0] != null) {
String result="";
byte[] payload = messages[0].getRecords()[0].getPayload();
// this assumes that we get back am SOH followed by host/code
for (int b = 1; b<payload.length; b++) { // skip SOH
result += (char) payload[b];
}
//grabbing 2nd payload
String result2="";
byte[] payload2 = messages[0].getRecords()[1].getPayload();
for (int test = 1; test<payload2.length; test++) { // skip SOH
result2 += (char) payload2[test];
Toast.makeText(this,result2,Toast.LENGTH_SHORT).show();
}
You're skipping the first byte i.e. the H.
In the first record you're pre-pending a byte which you correctly skip when reading.
As for speed I thats just the OS buffering the toasts
Related
Hey guys im testing NFC and i have an issue with i think it is formating..
I added a string value in the tag with an app to write.
when i scan it with that same store app it shows ok...
when i scan with my app it shows the correct name in the app but adds a "en" before the message..
and a white space.. so if i add a name in the tag then scan and get a API it shows 404 cause there is an en and white space..
http://myapisite.com/API/getdevice.php?id= enTagString
before the = space and then en before the id or even name i put..
i tried a few ways..
public class MainActivity extends Activity {
// list of NFC technologies detected:
private final String[][] techList = new String[][]{
new String[]{
NfcA.class.getName (),
NfcB.class.getName (),
NfcF.class.getName (),
NfcV.class.getName (),
IsoDep.class.getName (),
MifareClassic.class.getName (),
MifareUltralight.class.getName (), Ndef.class.getName ()
}
};
private TextView mTextView;
private ImageView mImageView;
private String ID, machineName, MachineImg, MachinePart, level;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate (savedInstanceState);
setContentView (R.layout.activity_main);
mImageView = findViewById (R.id.imageView);
mTextView = findViewById (R.id.textView_explanation);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater ().inflate (R.menu.menu, menu);
return true;
}
#Override
protected void onResume() {
super.onResume ();
PendingIntent pendingIntent = PendingIntent.getActivity (this, 0, new Intent (this, getClass ()).addFlags (Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
// creating intent receiver for NFC events:
IntentFilter filter = new IntentFilter ();
filter.addAction (NfcAdapter.ACTION_TAG_DISCOVERED);
filter.addAction (NfcAdapter.ACTION_NDEF_DISCOVERED);
filter.addAction (NfcAdapter.ACTION_TECH_DISCOVERED);
// enabling foreground dispatch for getting intent from NFC event:
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter (this);
nfcAdapter.enableForegroundDispatch (this, pendingIntent, new IntentFilter[]{filter}, this.techList);
}
#Override
protected void onPause() {
super.onPause ();
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter (this);
nfcAdapter.disableForegroundDispatch (this);
}
void parseNdefMessage(Intent intent) {
Parcelable[] ndefMessageArray = intent.getParcelableArrayExtra (
NfcAdapter.EXTRA_NDEF_MESSAGES);
NdefMessage ndefMessage = (NdefMessage) ndefMessageArray[0];
String text = new String (ndefMessage.getRecords ()[0].getPayload ());
Log.d (TAG, "PAYLOAD MESS" + text);
ID = text;
getApiInfos ();
}
#Override
protected void onNewIntent(Intent intent) {
parseNdefMessage (intent);
if (intent.getAction ().equals (NfcAdapter.ACTION_TAG_DISCOVERED)) {
mTextView.setText ("NFC Tag\n" + ByteArrayToHexString (intent.getByteArrayExtra (NfcAdapter.EXTRA_ID)));
Parcelable tagN = intent.getParcelableExtra (NfcAdapter.EXTRA_TAG);
if (tagN != null) {
NdefMessage[] msgs;
byte[] empty = new byte[0];
byte[] id = intent.getByteArrayExtra (NfcAdapter.EXTRA_ID);
byte[] payload = dumpTagData (tagN).getBytes ();
NdefRecord record = new NdefRecord (NdefRecord.TNF_UNKNOWN, empty, id, payload);
NdefMessage msg = new NdefMessage (new NdefRecord[]{record});
msgs = new NdefMessage[]{msg};
Log.d (TAG, msgs[0].toString ());
} else {
Log.d (TAG, "Parcelable NULL");
}
Parcelable[] messages1 = intent.getParcelableArrayExtra (NfcAdapter.EXTRA_NDEF_MESSAGES);
if (messages1 != null) {
Log.d (TAG, "Found " + messages1.length + " NDEF messages");
for (int i = 0; i < messages1.length; ++i) {
Log.d (TAG, "Found M " + messages1[i].toString ());
}
} else {
Log.d (TAG, "Not EXTRA_NDEF_MESSAGES");
}
Tag tag = intent.getParcelableExtra (NfcAdapter.EXTRA_TAG);
Ndef ndef = Ndef.get (tag);
if (ndef != null) {
Parcelable[] messages = intent.getParcelableArrayExtra (NfcAdapter.EXTRA_NDEF_MESSAGES);
if (messages != null) {
Log.d (TAG, "Found " + messages.length + " NDEF messages");
}
} else {
Log.d (TAG, "Write to an unformatted tag not implemented");
}
}
}
private String dumpTagData(Parcelable p) {
StringBuilder sb = new StringBuilder ();
Tag tag = (Tag) p;
byte[] id = tag.getId ();
sb.append ("Tag ID (hex): ").append (getHex (id)).append ("\n");
sb.append ("Tag ID (dec): ").append (getDec (id)).append ("\n");
sb.append ("ID (reversed): ").append (getReversed (id)).append ("\n");
String prefix = "android.nfc.tech.";
sb.append ("Technologies: ");
for (String tech : tag.getTechList ()) {
sb.append (tech.substring (prefix.length ()));
sb.append (", ");
}
sb.delete (sb.length () - 2, sb.length ());
for (String tech : tag.getTechList ()) {
if (tech.equals (MifareClassic.class.getName ())) {
sb.append ('\n');
MifareClassic mifareTag = MifareClassic.get (tag);
String type = "Unknown";
switch (mifareTag.getType ()) {
case MifareClassic.TYPE_CLASSIC:
type = "Classic";
break;
case MifareClassic.TYPE_PLUS:
type = "Plus";
break;
case MifareClassic.TYPE_PRO:
type = "Pro";
break;
}
sb.append ("Mifare Classic type: ");
sb.append (type);
sb.append ('\n');
sb.append ("Mifare size: ");
sb.append (mifareTag.getSize () + " bytes");
sb.append ('\n');
sb.append ("Mifare sectors: ");
sb.append (mifareTag.getSectorCount ());
sb.append ('\n');
sb.append ("Mifare blocks: ");
sb.append (mifareTag.getBlockCount ());
}
if (tech.equals (MifareUltralight.class.getName ())) {
sb.append ('\n');
MifareUltralight mifareUlTag = MifareUltralight.get (tag);
String type = "Unknown";
switch (mifareUlTag.getType ()) {
case MifareUltralight.TYPE_ULTRALIGHT:
type = "Ultralight";
break;
case MifareUltralight.TYPE_ULTRALIGHT_C:
type = "Ultralight C";
break;
}
sb.append ("Mifare Ultralight type: ");
sb.append (type);
}
}
DateFormat TIME_FORMAT = SimpleDateFormat.getDateTimeInstance ();
Date now = new Date ();
mTextView.setText (TIME_FORMAT.format (now) + '\n' + sb.toString ());
return sb.toString ();
}
private String getHex(byte[] bytes) {
StringBuilder sb = new StringBuilder ();
for (int i = bytes.length - 1; i >= 0; --i) {
int b = bytes[i] & 0xff;
if (b < 0x10)
sb.append ('0');
sb.append (Integer.toHexString (b));
if (i > 0) {
sb.append (" ");
}
}
return sb.toString ();
}
private long getDec(byte[] bytes) {
long result = 0;
long factor = 1;
for (int i = 0; i < bytes.length; ++i) {
long value = bytes[i] & 0xffl;
result += value * factor;
factor *= 256l;
}
return result;
}
private long getReversed(byte[] bytes) {
long result = 0;
long factor = 1;
for (int i = bytes.length - 1; i >= 0; --i) {
long value = bytes[i] & 0xffl;
result += value * factor;
factor *= 256l;
}
return result;
}
private String ByteArrayToHexString(byte[] inarray) {
int i, j, in;
String[] hex = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"};
String out = "";
for (j = 0; j < inarray.length; ++j) {
in = (int) inarray[j] & 0xff;
i = (in >> 4) & 0x0f;
out += hex[i];
i = in & 0x0f;
out += hex[i];
}
Log.d ("ByteArrayToHexString", String.format ("%0" + (inarray.length * 2) + "X", new BigInteger (1, inarray)));
return out;
}
enter code here
Most likely this is because the App writing is storing it as a "WELL_KNOWN" type of text/plain
The specs for NFC Text format can be found at NFCForum-TS-RTD_Text_1.0.pdf.
The extra characters in the payload are as below:
language length (1 byte) + language (n bytes) + Text
So the space is the actually a non printable size of the language.
The "en" is defining that the text is English.
https://developer.android.com/reference/android/nfc/NdefRecord#getPayload()
returns a byte array.
So below should work to trim it (tested) as there don't seem to be nice helper methods to decode it, only create this format.
// Create Test Record
NdefRecord record = NdefRecord.createTextRecord("en", "Hello");
//Get Bytes of payload
// byte[] payload = ndefMessage.getRecords ()[0].getPayload ();
// Get Bytes of test NDEF Record
byte[] payload = record.getPayload ();
// Read First Byte and then trim off the right length
byte[] textArray = Arrays.copyOfRange(payload, (int) payload[0] + 1 , payload.length);
// Convert to Text
String text = new String(textArray);
UPDATE:
As the code given in the question is a bit of a mess and you do things you don't need to do and don't do things you do need to do (e.g. you have asked to be sent data from cards that won't have NDef data in them and then you parse for Ndef data without checking there is some data to parse)
I've simplified the code just to read a text NDEF record (Note not tested, but based on how I used to read NDEF data, I now use a better method to read cards that is more reliable especially if you want to write to cards as well)
public class MainActivity extends Activity {
private TextView mTextView;
private ImageView mImageView;
private String ID, machineName, MachineImg, MachinePart, level;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mImageView = findViewById(R.id.imageView);
mTextView = findViewById(R.id.textView_explanation);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
return true;
}
#Override
protected void onResume() {
super.onResume();
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
// creating intent receiver for NFC events:
IntentFilter filter = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
// enabling foreground dispatch for getting intent from NFC event:
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
nfcAdapter.enableForegroundDispatch(this, pendingIntent, new IntentFilter[]{filter}, null);
}
#Override
protected void onPause() {
super.onPause();
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
nfcAdapter.disableForegroundDispatch(this);
}
void parseNdefMessage(Intent intent) {
Parcelable[] ndefMessageArray = intent.getParcelableArrayExtra(
NfcAdapter.EXTRA_NDEF_MESSAGES);
// Test if there is actually a NDef message passed via the Intent
if (ndefMessageArray != null) {
NdefMessage ndefMessage = (NdefMessage) ndefMessageArray[0];
//Get Bytes of payload
byte[] payload = ndefMessage.getRecords()[0].getPayload();
// Read First Byte and then trim off the right length
byte[] textArray = Arrays.copyOfRange(payload, (int) payload[0] + 1, payload.length);
// Convert to Text
String text = new String(textArray);
ID = text;
getApiInfos();
}
}
#Override
protected void onNewIntent(Intent intent) {
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) {
parseNdefMessage(intent);
}
}
}
Ok thx to #Andrew i used part of your code and adapted it to my tests.. it works great now i can clean it up and removed what is not used or needed.Thx happy holidays!:)
void parseNdefMessage(Intent intent) {
Parcelable[] ndefMessageArray = intent.getParcelableArrayExtra(
NfcAdapter.EXTRA_NDEF_MESSAGES);
// Test if there is actually a NDef message passed via the Intent
if (ndefMessageArray != null) {
NdefMessage ndefMessage = (NdefMessage) ndefMessageArray[0];
//Get Bytes of payload
byte[] payload = ndefMessage.getRecords()[0].getPayload();
// Read First Byte and then trim off the right length
byte[] textArray = Arrays.copyOfRange(payload, (int) payload[0] + 1, payload.length);
// Convert to Text
String text = new String(textArray);
ID = text;
getApiInfos();
}
}
If anyone is facing the same issue in React Native, here's my solution. Here, the react-native-nfc-manager package is used
// register for the NFC tag with NDEF in it
await NfcManager.requestTechnology(NfcTech.Ndef);
// the resolved tag object will contain `ndefMessage` property
const tag = await NfcManager.getTag();
// access the payload
const payload = tag?.ndefMessage[0].payload;
//remove the language code from payload
const subPayload = payload?.slice(3, payload.length);
const decoded = Ndef.util.bytesToString(subPayload);
I have a problem with NFC. Is there any posible way to turn off the NFC sound in Android API 16 and higher?
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_traveller_read_tag);
context = this;
tvNFCContent = findViewById(R.id.nfc_contents);
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(getIntent());
pendingIntent = PendingIntent.getActivity(context, 0, new Intent(context, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);
tagDetected.addCategory(Intent.CATEGORY_DEFAULT);
writeTagFilters = new IntentFilter[]{tagDetected};
findViewById(R.id.menu).setVisibility(View.GONE);
}
private void readFromIntent(Intent intent) {
String action = intent.getAction();
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)
|| NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)
|| NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
NdefMessage[] msgs = null;
if (rawMsgs != null) {
msgs = new NdefMessage[rawMsgs.length];
for (int i = 0; i < rawMsgs.length; i++) {
msgs[i] = (NdefMessage) rawMsgs[i];
}
}
buildTagViews(msgs);
}
}
private void buildTagViews(NdefMessage[] msgs) {
if (msgs == null || msgs.length == 0) return;
String text = "";
//String tagId = new String(msgs[0].getRecords()[0].getType());
byte[] payload = msgs[0].getRecords()[0].getPayload();
String textEncoding = ((payload[0] & 128) == 0) ? "UTF-8" : "UTF-16"; // Get the Text Encoding
int languageCodeLength = payload[0] & 0063; // Get the Language Code, e.g. "en"
// String languageCode = new String(payload, 1, languageCodeLength, "US-ASCII");
try {
// Get the Text
text = new String(payload, languageCodeLength + 1, payload.length - languageCodeLength - 1, textEncoding);
} catch (UnsupportedEncodingException e) {
Log.e("UnsupportedEncoding", e.toString());
}
int tempCoin = Integer.parseInt( DB.getValue(context, UserValue.KEY_COIN) ) + Integer.parseInt( text );
DB.setValue(context,UserValue.KEY_COIN,String.valueOf(tempCoin));
tvNFCContent.setText("حساب شما " + text +" تومان شارژ شد.");
beep.playBeep(context, beep.TypeBeep.OK);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
finish();
}
},1000);
}
#Override
protected void onNewIntent(Intent intent) {
setIntent(intent);
readFromIntent(intent);
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) {
myTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
}
}
No, disabling the NFC discovery sound is not possible on Android API level 16. Only the reader-mode API introduced in Android API level 19 allows you to disable the platform sounds normally generated for NFC discovery events:. See NfcAdapter.enableReaderMode and the flag NfcAdapter.FLAG_READER_NO_PLATFORM_SOUNDS.
I have a device with Android 4.4 in a board but it doesn't have a SIM card module.
Please, tell me , how i can emulate incoming SMS from my application?
I just wanna see standart notification aboute incoming sms.
I tried this example:
enter code here
private static void createFakeSms(Context context, String sender,
String body) {
byte[] pdu = null;
byte[] scBytes =PhoneNumberUtils.networkPortionToCalledPartyBCD("0000000000");
byte[] senderBytes = PhoneNumberUtils.networkPortionToCalledPartyBCD(sender);
int lsmcs = scBytes.length;
byte[] dateBytes = new byte[7];
Calendar calendar = new GregorianCalendar();
dateBytes[0] = reverseByte((byte) (calendar.get(Calendar.YEAR)));
dateBytes[1] = reverseByte((byte) (calendar.get(Calendar.MONTH) + 1));
dateBytes[2] = reverseByte((byte) (calendar.get(Calendar.DAY_OF_MONTH)));
dateBytes[3] = reverseByte((byte) (calendar.get(Calendar.HOUR_OF_DAY)));
dateBytes[4] = reverseByte((byte) (calendar.get(Calendar.MINUTE)));
dateBytes[5] = reverseByte((byte) (calendar.get(Calendar.SECOND)));
dateBytes[6] = reverseByte((byte) ((calendar.get(Calendar.ZONE_OFFSET) + calendar
.get(Calendar.DST_OFFSET)) / (60 * 1000 * 15)));
try {
ByteArrayOutputStream bo = new ByteArrayOutputStream();
bo.write(lsmcs);
bo.write(scBytes,0,scBytes.length);
bo.write(0x04);
bo.write((byte) sender.length());
bo.write(senderBytes,0,senderBytes.length);
bo.write(0x00);
bo.write(0x00); // encoding: 0 for default 7bit
bo.write(dateBytes,0,dateBytes.length);
try {
String sReflectedClassName = "com.android.internal.telephony.GsmAlphabet";
Class cReflectedNFCExtras = Class.forName(sReflectedClassName);
Method stringToGsm7BitPacked = cReflectedNFCExtras.getMethod(
"stringToGsm7BitPacked", new Class[] { String.class });
stringToGsm7BitPacked.setAccessible(true);
byte[] bodybytes = (byte[]) stringToGsm7BitPacked.invoke(null,
body);
bo.write(bodybytes);
} catch (Exception e) {
}
pdu = bo.toByteArray();
}finally {
}
Intent intent = new Intent();
intent.setClassName("com.android.mms",
"com.android.mms.transaction.SmsReceiverService");
intent.setAction("android.provider.Telephony.SMS_RECEIVED");
intent.putExtra("pdus", new Object[] { pdu });
intent.putExtra("format", "3gpp");
context.startService(intent);
}
private static byte reverseByte(byte b) {
return (byte) ((b & 0xF0) >> 4 | (b & 0x0F) << 4);
}
But when i call this function my application is crashed.
Please help me.
I'm new Android and I don't know how to solve this problem: I'm using an intent in the onCreate in order to read NFC tags, and I'm trying to use the text read from the tag.
I manage for the moment to read the tag, and display this text, but only in the method "resolveIntent" (the TextView "tvResponse" shows correctly my data in "resolveIntent", but everywhere else is empty). My problem is I need to use this value in my onCreate method, and I don't know how to get it out from resolveIntent.
Can anybody help me? Thanks a lot!
Here is the corresponding section in my onCreate:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_nfcpositioning_main);
mTagContent = (LinearLayout) findViewById(R.id.list);
tvResponse = (TextView) findViewById(R.id.tvResponse);
//TAGS READING
resolveIntent(getIntent());
mDialog = new AlertDialog.Builder(this).setNeutralButton("Ok", null).create();
mAdapter = NfcAdapter.getDefaultAdapter(this);
if (mAdapter == null) {
showMessage(R.string.error, R.string.no_nfc);
finish();
return;
}
mPendingIntent = PendingIntent.getActivity(this, 0,
new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
mNdefPushMessage = new NdefMessage(new NdefRecord[] { newTextRecord(
"Message from NFC Reader :-)", Locale.ENGLISH, true) });
tvResponse.setText(getIntent().getStringExtra("MSG"));
and the void "resolveIntent" which is also in the main activity:
public void resolveIntent(Intent Xintent) {
String action = Xintent.getAction();
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)
|| NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)
|| NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
Parcelable[] rawMsgs = Xintent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
NdefMessage[] msgs;
if (rawMsgs != null) {
msgs = new NdefMessage[rawMsgs.length];
for (int i = 0; i < rawMsgs.length; i++) {
msgs[i] = (NdefMessage) rawMsgs[i];
}
NdefMessage msg = msgs[0];
byte[] payload = msg.getRecords()[0].getPayload();
String result="";
for (int b = 3; b<payload.length; b++) {
result += (char) payload[b];
}
String StringNdefMessagePart = result;
//tvResponse.setText(StringNdefMessagePart);
Xintent.putExtra("MSG", StringNdefMessagePart);
} else {
Toast.makeText(this, "Empty NFC tag", Toast.LENGTH_LONG).show();
}
}
}
I leave an example of a personal code, I hope it helps you
Intent i = new Intent(this,DetalleEventoActivity.class);
Bundle b = new Bundle();
b.putLong("IDEV", e.getId());
b.putLong("FECHA", e.getFecha());
b.putString("NOMBRE_EVENTO", e.getNombreEvento());
b.putString("NUMERO_MAQUINA", e.getNroMaquinaDGC());
b.putString("SECTOR", e.getSector());
b.putString("SOCIO", e.getNroSocio());
b.putString("CATEGORIA", e.getCategoriaSocio());
i.putExtras(b);
startActivity(i);
---IN DetalleEventoActivity-------------------------------------------
Bundle bundle = this.getIntent().getExtras();
id = bundle.getLong("IDEV");
fechaLong = bundle.getLong("FECHA");
fecha = formatter.format(fechaLong);
nombreEvento = bundle.getString("NOMBRE_EVENTO");
nroMaquina = bundle.getString("NUMERO_MAQUINA");
sector = bundle.getString("SECTOR");
socio = bundle.getString("SOCIO");
categoria = bundle.getString("CATEGORIA");
The online source codes for NFC are done using Activity. I would like to ask if it is possible to develop using Fragment instead?
This is the error i hit when i run the codes
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.mobile.countmein/com.mobile.countmein.activities.NFCScanner}: java.lang.ClassCastException: com.mobile.countmein.activities.NFCScanner cannot be cast to android.app.Activity
public class TagViewer extends Fragment {
private static final SimpleDateFormat TIME_FORMAT = new SimpleDateFormat();
private LinearLayout mTagContent;
private NfcAdapter mAdapter;
private PendingIntent mPendingIntent;
private NdefMessage mNdefPushMessage;
private AlertDialog mDialog;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.tag_viewer, container, false);
}
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mTagContent = (LinearLayout)view.findViewById(R.id.list);
resolveIntent(getActivity().getIntent());
mDialog = new AlertDialog.Builder(getActivity()).setNeutralButton("Ok", null).create();
mAdapter = NfcAdapter.getDefaultAdapter(getActivity());
if (mAdapter == null) {
showMessage(R.string.error, R.string.no_nfc);
}
mPendingIntent = PendingIntent.getActivity(getActivity(), 0,
new Intent(getActivity(), getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
mNdefPushMessage = new NdefMessage(new NdefRecord[] { newTextRecord(
"Message from NFC Reader :-)", Locale.ENGLISH, true) });
}
private void showMessage(int title, int message) {
mDialog.setTitle(title);
mDialog.setMessage(getText(message));
mDialog.show();
}
private NdefRecord newTextRecord(String text, Locale locale, boolean encodeInUtf8) {
byte[] langBytes = locale.getLanguage().getBytes(Charset.forName("US-ASCII"));
Charset utfEncoding = encodeInUtf8 ? Charset.forName("UTF-8") : Charset.forName("UTF-16");
byte[] textBytes = text.getBytes(utfEncoding);
int utfBit = encodeInUtf8 ? 0 : (1 << 7);
char status = (char) (utfBit + langBytes.length);
byte[] data = new byte[1 + langBytes.length + textBytes.length];
data[0] = (byte) status;
System.arraycopy(langBytes, 0, data, 1, langBytes.length);
System.arraycopy(textBytes, 0, data, 1 + langBytes.length, textBytes.length);
return new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], data);
}
#Override
public void onResume() {
super.onResume();
if (mAdapter != null) {
if (!mAdapter.isEnabled()) {
showMessage(R.string.error, R.string.nfc_disabled);
}
mAdapter.enableForegroundDispatch(getActivity(), mPendingIntent, null, null);
mAdapter.enableForegroundNdefPush(getActivity(), mNdefPushMessage);
}
}
#Override
public void onPause() {
super.onPause();
if (mAdapter != null) {
mAdapter.disableForegroundDispatch(getActivity());
mAdapter.disableForegroundNdefPush(getActivity());
}
}
private void resolveIntent(Intent intent) {
String action = intent.getAction();
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)
|| NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)
|| NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
NdefMessage[] msgs;
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[0];
byte[] id = intent.getByteArrayExtra(NfcAdapter.EXTRA_ID);
Parcelable tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
byte[] payload = dumpTagData(tag).getBytes();
NdefRecord record = new NdefRecord(NdefRecord.TNF_UNKNOWN, empty, id, payload);
NdefMessage msg = new NdefMessage(new NdefRecord[] { record });
msgs = new NdefMessage[] { msg };
}
// Setup the views
buildTagViews(msgs);
}
}
private String dumpTagData(Parcelable p) {
StringBuilder sb = new StringBuilder();
Tag tag = (Tag) p;
byte[] id = tag.getId();
sb.append("Tag ID (hex): ").append(getHex(id)).append("\n");
sb.append("Tag ID (dec): ").append(getDec(id)).append("\n");
String prefix = "android.nfc.tech.";
sb.append("Technologies: ");
for (String tech : tag.getTechList()) {
sb.append(tech.substring(prefix.length()));
sb.append(", ");
}
sb.delete(sb.length() - 2, sb.length());
for (String tech : tag.getTechList()) {
if (tech.equals(MifareClassic.class.getName())) {
sb.append('\n');
MifareClassic mifareTag = MifareClassic.get(tag);
String type = "Unknown";
switch (mifareTag.getType()) {
case MifareClassic.TYPE_CLASSIC:
type = "Classic";
break;
case MifareClassic.TYPE_PLUS:
type = "Plus";
break;
case MifareClassic.TYPE_PRO:
type = "Pro";
break;
}
sb.append("Mifare Classic type: ");
sb.append(type);
sb.append('\n');
sb.append("Mifare size: ");
sb.append(mifareTag.getSize() + " bytes");
sb.append('\n');
sb.append("Mifare sectors: ");
sb.append(mifareTag.getSectorCount());
sb.append('\n');
sb.append("Mifare blocks: ");
sb.append(mifareTag.getBlockCount());
}
if (tech.equals(MifareUltralight.class.getName())) {
sb.append('\n');
MifareUltralight mifareUlTag = MifareUltralight.get(tag);
String type = "Unknown";
switch (mifareUlTag.getType()) {
case MifareUltralight.TYPE_ULTRALIGHT:
type = "Ultralight";
break;
case MifareUltralight.TYPE_ULTRALIGHT_C:
type = "Ultralight C";
break;
}
sb.append("Mifare Ultralight type: ");
sb.append(type);
}
}
return sb.toString();
}
private String getHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (int i = bytes.length - 1; i >= 0; --i) {
int b = bytes[i] & 0xff;
if (b < 0x10)
sb.append('0');
sb.append(Integer.toHexString(b));
if (i > 0) {
sb.append(" ");
}
}
return sb.toString();
}
private long getDec(byte[] bytes) {
long result = 0;
long factor = 1;
for (int i = 0; i < bytes.length; ++i) {
long value = bytes[i] & 0xffl;
result += value * factor;
factor *= 256l;
}
return result;
}
void buildTagViews(NdefMessage[] msgs) {
if (msgs == null || msgs.length == 0) {
return;
}
LayoutInflater inflater = LayoutInflater.from(getActivity());
LinearLayout content = mTagContent;
// Parse the first message in the list
// Build views for all of the sub records
Date now = new Date();
List<ParsedNdefRecord> records = NdefMessageParser.parse(msgs[0]);
final int size = records.size();
for (int i = 0; i < size; i++) {
TextView timeView = new TextView(getActivity());
timeView.setText(TIME_FORMAT.format(now));
content.addView(timeView, 0);
ParsedNdefRecord record = records.get(i);
content.addView(record.getView(getActivity(), inflater, content, i), 1 + i);
content.addView(inflater.inflate(R.layout.tag_divider, content, false), 2 + i);
}
}
}
I removed the following because a fragment does not have the method:
#Override
public void onNewIntent(Intent intent) {
setIntent(intent);
resolveIntent(intent);
}
A fragment is to control a portion of the user interface in an Activity.
Why not put your NFC code in the activity?
If you really need the Intent in the fragment you can pass it in a Bundle because an Intent is Parceable.
See: Pass intent to my fragment