我正在嘗試從 Xamarin Forms Android 應用程式中 Mifare Classic 卡的扇區 0 塊 1 讀取用戶資料。在大多數設備上,它每次都能完美運行,但在 Unitech EA510 上,身份驗證始終失敗,除非我首先使用 Mifare Classic 工具(https://play.google.com/store/apps/details?id=de)讀取卡。 syss.MifareClassicTool)。一旦我使用 Mifare Classic Tool 檢測到任何標簽,我的代碼每次都能完美運行。我檢查了 Mifare Classic Tool 源代碼,看看它還在做什么,并借用了 patchTag 邏輯(它沒有幫助!)。
- 首次使用應用掃描標簽: Mifare Classic 標簽認證失敗:8250A9B9
- 使用 Mifare Classic 工具掃描標簽
- 使用應用重新掃描標簽: 找到 Mifare Classic 標簽:8250A9B9 10240472
- 使用應用程式掃描另一個標簽: 找到 Mifare Classic 標簽:8250A9C7 10395802
public void OnTagDiscovered(Android.Nfc.Tag tag)
{
string tagId = string.Empty;
string[] techList = tag.GetTechList();
string sUid = string.Empty;
if (Array.IndexOf(techList, "android.nfc.tech.MifareClassic") > -1) {
MifareClassic mfc = null;
try {
sUid = BitConverter.ToString(tag.GetId()).Replace("-", "");
mfc = MifareClassic.Get(tag);
mfc.Connect();
bool bAuthenticated = false;
if (mfc.AuthenticateSectorWithKeyA(0, MifareClassic.KeyDefault.ToArray()))
bAuthenticated = true;
else if (mfc.AuthenticateSectorWithKeyB(0, MifareClassic.KeyDefault.ToArray()))
bAuthenticated = true;
else if (mfc.AuthenticateSectorWithKeyA(0, MifareClassic.KeyMifareApplicationDirectory.ToArray()))
bAuthenticated = true;
else if (mfc.AuthenticateSectorWithKeyB(0, MifareClassic.KeyMifareApplicationDirectory.ToArray()))
bAuthenticated = true;
else if (mfc.AuthenticateSectorWithKeyA(0, MifareClassic.KeyNfcForum.ToArray()))
bAuthenticated = true;
else if (mfc.AuthenticateSectorWithKeyB(0, MifareClassic.KeyNfcForum.ToArray()))
bAuthenticated = true;
if (bAuthenticated) {
int blockOffset = mfc.SectorToBlock(0);
byte[] block = mfc.ReadBlock(blockOffset 1); // Sector 0/block 0 is the UID so go straight to block 1 for the payload
tagId = System.Text.Encoding.ASCII.GetString(block);
if (tagId.Length == 1 && tagId[0] == 0x04)
// Ignore if ReadBlock returns a single byte 0x04, which appears to happen if there's a delay between the tag discovery and ReadBlock (e.g. running in the debugger) and we don't want to treat it as a conventional tag by acciden
tagId = string.Empty;
else if (tagId.Length > 0 && tagId.Contains('\0'))
tagId = tagId.Substring(0, tagId.IndexOf('\0'));
} else {
Console.WriteLine($"Mifare Classic tag authentication failure: {sUid}");
}
}
catch (Exception ex) {
Console.WriteLine($"Mifare Classic tag read exception: {ex.Message}");
}
finally {
if (mfc != null && mfc.IsConnected)
mfc.Close();
if (tagId != string.Empty)
Console.WriteLine($"Mifare Classic tag found: {sUid} {tagId}");
}
}
if (tagId != string.Empty)
Do stuff
}
uj5u.com熱心網友回復:
當手機不支持 Mifare Classic 并且它不會修復所有設備時,這看起來是一種嘗試啟用 Mifare Classic 支持的超級 hacky 方式。
但是您的問題是,當您使用舊 API時,hack 依賴于修改您的應用程式從 Intent 創建的標記物件 enableForegrounDispatch
這個舊 API 還有一些其他問題,當您使用更新和更好的enableReaderModeAPI(因為您使用的是方法OnTagDiscovered)時,它會直接提供標簽物件。
我沒有通過Android代碼來解決所有這些問題,但我的猜測是它是某種形式的共享記憶體物件,雖然它被定義為“單向”回呼。
因此,由于您的 App 行程不是Tag物件的創建者,因此您無法修改它。
enableForegrounDispatch因此,只有當您在自己的 App ( ) 中使用舊的方式對 Parceled 物件進行解包Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);并擁有對 Tag 物件的完全訪問權限時,此 hack 可能才會起作用,因為您的行程創建了它。
使用 Mifare Classic Tool App 后您的代碼可以正常作業的原因是,一旦標簽硬體經過身份驗證,它就會一直處于“身份驗證”狀態,直到它從射頻場中移除并失去電源。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/465922.html
