[英]Not Reading Nfc 4K Card details in Android
我想讀取 NFC 4K 卡詳細信息,它不讀取數據,這是我使用的代碼,
AndroidManifest.xml
<uses-permission android:name="android.permission.NFC" />
<uses-feature android:name="android.hardware.nfc" android:required="true" />
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<action android:name="android.nfc.action.TECH_DISCOVERED" />
<action android:name="android.nfc.action.TAG_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_tech_filter" />
</activity>
nfc_tech_filter.xml
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<tech-list>
<tech>android.nfc.tech.IsoDep</tech>
<tech>android.nfc.tech.NfcA</tech>
<tech>android.nfc.tech.NfcB</tech>
<tech>android.nfc.tech.NfcF</tech>
<tech>android.nfc.tech.NfcV</tech>
<tech>android.nfc.tech.Ndef</tech>
<tech>android.nfc.tech.NdefFormatable</tech>
<tech>android.nfc.tech.MifareClassic</tech>
<tech>android.nfc.tech.MifareUltralight</tech>
</tech-list>
</resources>
MainActivity.java
public class MainActivity extends Activity implements NfcAdapter.ReaderCallback {
public static final String TAG = " --NFC-- " + MainActivity.class.getSimpleName();
private NfcAdapter nfcAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
nfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (nfcAdapter == null) {
showToast("No NFC found...");
} else {
showToast("NFC Enables Device...");
enableReaderMode();
}
}
@Override
public void onResume() {
super.onResume();
showToast("On Resume...");
enableReaderMode();
}
@Override
protected void onPause() {
super.onPause();
showToast("On Pause...");
disableReaderMode();
}
private void showToast(String message) {
Log.d(TAG, message);
try {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
} catch (Exception e) {
showToast("Show Toast Exception : " + message);
}
}
private void enableReaderMode() {
showToast("Enabling reader mode...");
Activity activity = MainActivity.this;
nfcAdapter = NfcAdapter.getDefaultAdapter(activity);
if (nfcAdapter != null) {
nfcAdapter.enableReaderMode(activity, this, Integer.MAX_VALUE, null);
}
}
private void disableReaderMode() {
showToast("Disabling reader mode...");
Activity activity = MainActivity.this;
nfcAdapter = NfcAdapter.getDefaultAdapter(activity);
if (nfcAdapter != null)
nfcAdapter.disableReaderMode(activity);
}
@Override
public void onTagDiscovered(Tag tag) {
Log.d(TAG, "New tag discovered...");
}
@Override
protected void onNewIntent(Intent intent) {
Log.d(TAG, "New Intent...");
super.onNewIntent(intent);
}
}
您沒有在 onNewIntent() 中處理您的意圖數據。 每當您掃描 NFC 卡時,都會調用 onNewIntent()。 像下面的例子:
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Log.d(TAG, "New Intent...");
handleIntent(intent);
}
private void handleIntent(Intent intent) {
val bundle = intent.extras
if (bundle != null) {
Log.e(TAG,intent.getParcelableExtra(NfcAdapter.EXTRA_TAG))
}
}
已編輯
添加適配器后,您需要從 onResume() 調用此方法。
private fun setupForegroundDispatch(activity : Activity, adapter
: NfcAdapter) {
val intent = Intent(activity.applicationContext,
activity.javaClass)
intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP
val pendingIntent =
PendingIntent.getActivity(activity.applicationContext, 0,
intent, 0)
// val filters = arrayOfNulls<IntentFilter>(1)
// val techList = arrayOf<Array<String>>()
val ndef = IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED)
val filters = arrayOf(ndef)
// val techList = arrayOf<Array<String>>()
val techList = arrayOf(arrayOf(NfcV::class.java.name))
// Notice that this is the same filter as in our manifest.
filters[0] = IntentFilter()
filters[0].addAction(NfcAdapter.ACTION_NDEF_DISCOVERED)
filters[0].addCategory(Intent.CATEGORY_DEFAULT)
try {
filters[0].addDataType(MIME_TEXT_PLAIN)
}
catch (e : IntentFilter.MalformedMimeTypeException) {
throw RuntimeException("Check your mime type.")
}
adapter.enableForegroundDispatch(activity, pendingIntent,
filters, techList)
}
如下所示:
private void enableReaderMode() {
showToast("Enabling reader mode...");
Activity activity = MainActivity.this;
nfcAdapter = NfcAdapter.getDefaultAdapter(activity);
if (nfcAdapter != null) {
nfcAdapter.enableReaderMode(activity, this,
Integer.MAX_VALUE, null);
setupForegroundDispatch(this,nfcAdapter);
}
}
當您使用enableReaderMode
時,您不需要onNewIntent
方法。
此外,清單中的intent-filter
和 nfc_tech_filter.xml 可能不需要(如果您不希望應用程序在未運行的情況下由 NFC 標簽啟動,則不需要它們,那么您將在onCreate
中處理 NFC 意圖)
您沒有做的是正確設置enableReaderMode
。
@Override
protected void onResume() {
super.onResume();
if(nfcAdapter!= null) {
Bundle options = new Bundle();
options.putInt(NfcAdapter.EXTRA_READER_PRESENCE_CHECK_DELAY, 250);
nfcAdapter.enableReaderMode(this,
this,
NfcAdapter.FLAG_READER_NFC_A |
NfcAdapter.FLAG_READER_NFC_B |
NfcAdapter.FLAG_READER_NFC_F |
NfcAdapter.FLAG_READER_NFC_V |
NfcAdapter.FLAG_READER_NFC_BARCODE |
NfcAdapter.FLAG_READER_NO_PLATFORM_SOUNDS,
options);
}
}
如果您想生成自己的閱讀通知而不是操作系統執行此操作,則關閉NfcAdapter.FLAG_READER_NO_PLATFORM_SOUNDS
是可選的。
請注意,較新的 NFC API 的enableReaderMode
為您提供了比舊的enableForegroundDispatch
更多的控制權,並且在寫入 NFC 標簽時比enableForegroundDispatch
更可靠,並且它沒有enableForegroundDispatch
的一些負面影響,所以我建議始終使用enableReaderMode
除非你想支持真正舊的 API
另請注意,不建議使用 Mifare 4K 卡,因為它們是專有格式,並非所有 Android 硬件都支持(無論您使用哪種 API)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.