[英]Android NFC Reading a Tag
在我的應用程序中,我有兩個選擇:編寫和讀取NFC標簽。 我正在另一個稱為WriteNFC的活動中進行NFC標簽編寫過程。 我希望我的主要活動在標簽進入范圍時讀取並顯示標簽數據。 編寫過程似乎還可以。 但是每當我嘗試讀取標簽時。 它什么也不顯示。
public class MainActivity extends Activity {
public static int id = 1;
public static int bakiye = 5;
public static Context myContext;
public static boolean availableForRead = true;
private Button myButton;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myButton = (Button) findViewById(R.id.button1);
myButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
Intent i = new Intent(getApplicationContext(), nfcWrite.class);
startActivity(i);
}
});
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
}
@Override
protected void onNewIntent(Intent intent) {
System.out.println("Intent detected");
if (intent.getType() != null && intent.getType().equals("application/" + getPackageName())) {
// Read the first record which contains the NFC data
Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
NdefRecord relayRecord = ((NdefMessage) rawMsgs[0]).getRecords()[0];
String nfcData = new String(relayRecord.getPayload());
System.out.println("Reading Process is Complete...");
// Display the data on the tag
Toast.makeText(this, nfcData, Toast.LENGTH_SHORT).show();
}
}
}
這是我的nfcWrite活動:
package com.example.nfchandler;
import java.io.IOException;
import java.nio.charset.Charset;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.nfc.FormatException;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.TagLostException;
import android.nfc.tech.Ndef;
import android.nfc.tech.NdefFormatable;
import android.os.Bundle;
import android.widget.Toast;
public class nfcWrite extends Activity {
private int id = 1;
private int balance = 5;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.nfc_write);
}
@Override
protected void onNewIntent(Intent intent) {
// TODO Auto-generated method stub
super.onNewIntent(intent);
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
String nfcMessage = intent.getStringExtra("nfcMessage");
if(nfcMessage != null) {
writeTag(this, tag, nfcMessage);
}
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
setupIntent();
}
public void setupIntent() {
String nfcMessage = id + "-" + balance;
// When an NFC tag comes into range, call the main activity which
// handles writing the data to the tag
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
Intent nfcIntent = new Intent(this, nfcWrite.class).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
nfcIntent.putExtra("nfcMessage", nfcMessage);
PendingIntent pi = PendingIntent.getActivity(this, 0, nfcIntent, PendingIntent.FLAG_UPDATE_CURRENT);
IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);
nfcAdapter.enableForegroundDispatch((Activity) this, pi, new IntentFilter[] { tagDetected }, null);
}
public boolean writeTag(Context context, Tag tag, String data) {
// Record to launch Play Store if app is not installed
NdefRecord appRecord = NdefRecord.createApplicationRecord(context.getPackageName());
// Record with actual data we care about
NdefRecord relayRecord = new NdefRecord(NdefRecord.TNF_MIME_MEDIA,
new String("application/" + context.getPackageName()).getBytes(Charset.forName("US-ASCII")),
null, data.getBytes());
// Complete NDEF message with both records
NdefMessage message = new NdefMessage(new NdefRecord[] { relayRecord, appRecord });
try {
// If the tag is already formatted, just write the message to it
Ndef ndef = Ndef.get(tag);
if (ndef != null) {
ndef.connect();
// Make sure the tag is writable
if (!ndef.isWritable()) {
Toast.makeText(getApplicationContext(), "Etiket yazılabilir değil", Toast.LENGTH_SHORT).show();
return false;
}
// Check if there's enough space on the tag for the message
int size = message.toByteArray().length;
if (ndef.getMaxSize() < size) {
Toast.makeText(getApplicationContext(), "Etikette yeterli alan yok...", Toast.LENGTH_SHORT).show();
return false;
}
try {
// Write the data to the tag
ndef.writeNdefMessage(message);
Toast.makeText(getApplicationContext(), "Bilgileri yazma başarılı...", Toast.LENGTH_SHORT).show();
return true;
} catch (TagLostException tle) {
return false;
} catch (IOException ioe) {
return false;
} catch (FormatException fe) {
return false;
}
// If the tag is not formatted, format it with the message
} else {
NdefFormatable format = NdefFormatable.get(tag);
if (format != null) {
try {
format.connect();
format.format(message);
return true;
} catch (TagLostException tle) {
return false;
} catch (IOException ioe) {
return false;
} catch (FormatException fe) {
return false;
}
} else {
return false;
}
}
} catch (Exception e) {
}
return false;
}
}
以下代碼解決了我的問題:
Intent intent=getIntent();
NdefMessage[] msgs;
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
NdefRecord relayRecord = ((NdefMessage)rawMsgs[0]).getRecords()[0];
String nfcData = new String(relayRecord.getPayload());
Toast.makeText(getApplicationContext(),nfcData,Toast.LENGTH_LONG).show();
}
您的代碼有幾個有關NFC功能的問題:
在您的閱讀活動中,您僅在onNewIntent
方法中檢查與NFC相關的意圖。 但是,僅在某些條件下才調用onNewIntent
方法。 例如,在您的活動開始時不會調用它(例如,由於清單中的意圖過濾器觸發了它)。 在這種情況下,您將需要在onCreate
, onStart
或onResume
處理收到的意圖。 即使當你掃描標簽您的活動已經可見, onNewIntent
如果你的活動被標記為將僅singleTop
。 在這種情況下(當您希望在活動處於前台時在檢測到標簽時收到通知時,最好注冊NFC前台調度。
在寫活動中,您可以通過onResume
方法注冊NFC前台調度系統。 但是,您不會在onPause
釋放前台調度。 盡管這將在最新的Android版本(4.4+?)中起作用,但這會導致較舊的Android版本出現嚴重問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.