阅读MifareClassic标签会抛出java.io.IOException:Transceive Failed

时间:2015-09-29 14:42:39

标签: c# android xamarin.android nfc mifare

最近我正在尝试阅读一张MifareClassic 1K卡。在了解了这一事实之后,只有某些带有NXP芯片的手机能够读取这些标签,并且其中一个我正面临一个新问题。
我试图读取的卡抛出标题中提到的错误,但只有在没有单步执行代码的情况下运行时。 这里有一些细节: 起初,我从Xamarin那里拿走了NFCSample并改变了一些事情:

    protected override void OnNewIntent(Intent intent)
    {
        if(_inWriteMode)
        {
            _inWriteMode = false;
            var tag = intent.GetParcelableExtra(NfcAdapter.ExtraTag) as Tag;

            if(tag == null)
            {
                return;
            }
            MifareClassic mifc = MifareClassic.Get(tag);
            DisplayMessage("NFC recognized");
            try
            {
                mifc.ConnectAsync().Wait();
                DisplayMessage("Connected to Mifare Tag");
                DisplayMessage("SectorCount:" + mifc.SectorCount);
                DisplayMessage("BlockCount in Sector 1:" + mifc.GetBlockCountInSector(1));
                byte[] blargh = new byte[6];
                MifareClassic.KeyDefault.CopyTo(blargh,0);
                if(Task.Factory.StartNew<bool>(() => mifc.AuthenticateSectorWithKeyA(1, blargh)).Result)
                {
                    DisplayMessage("Auth A Complete");
                    blargh = new byte[6];
                    MifareClassic.KeyDefault.CopyTo(blargh, 0);
                    if(Task.Factory.StartNew<bool>(() => mifc.AuthenticateSectorWithKeyB(1, blargh)).Result)
                    {
                        DisplayMessage("Auth B Complete");
                        DisplayMessage("Read All Blocks of Section 1 ...");
                        int firstBlock = mifc.SectorToBlock(1);
                        int lastBlock = firstBlock + 3;
                        List<byte[]> lstBlocks = new List<byte[]>();
                        for(int i = firstBlock; i < lastBlock; i++)
                        {
                            DisplayMessage("Read Block " + i);
                            byte[] block = mifc.ReadBlockAsync(i).Result; //fails without stepping through in Debug mode
                            lstBlocks.Add(block);
                        }
                        string BlockData = string.Empty;
                        foreach(var item in lstBlocks)
                        {
                            BlockData += Encoding.ASCII.GetString(item) + "\r\n";
                        }
                        DisplayMessage(BlockData);
                    }
                }
                DisplayMessage("Close Connection");
                mifc.Close();
            }
            catch(Exception ex)
            {
                DisplayMessage(ex.ToString());
            }
        }
    }

所以,如果我单步执行代码,ReadBlock / ReadBlockAsync的工作完全正常。如果没有断点,它将抛出上述异常。这有什么不对吗?

编辑: 异常的StackTraces: 外部例外:

One or more errors occurred.
at System.Threading.Tasks.Task.ThrowIfExceptional (Boolean includeTaskCanceledExceptions) [0x00014] in <filename unknown>:0  
at System.Threading.Tasks.Task`1[System.Byte[]].GetResultCore (Boolean waitCompletionNotification) [0x00034] in <filename unknown>:0 
at System.Threading.Tasks.Task`1[System.Byte[]].get_Result () [0x0000b] in <filename unknown>:0  
at NfcXample.MainActivity.OnNewIntent (Android.Content.Intent intent) [0x001d0] in c:\\Users\\user\\Desktop\\monodroid-samples-master\\NfcSample\\MainActivity.cs:94 "

内部例外:

Exception of type 'Java.IO.IOException' was thrown.
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000b] in <filename unknown>:0  
at Android.Runtime.JNIEnv.CallObjectMethod (IntPtr jobject, IntPtr jmethod, Android.Runtime.JValue* parms) [0x00064] in /Users/builder/data/lanes/monodroid-mavericks-monodroid-5.1-series/d419c934/source/monodroid/src/Mono.Android/src/Runtime/JNIEnv.g.cs:195
at Android.Nfc.Tech.MifareClassic.ReadBlock (Int32 p0) [0x00044] in /Users/builder/data/lanes/monodroid-mavericks-monodroid-5.1-series/d419c934/source/monodroid/src/Mono.Android/platforms/android-10/src/generated/Android.Nfc.Tech.MifareClassic.cs:360  
at Android.Nfc.Tech.MifareClassic+<ReadBlockAsync>c__AnonStorey2.<>m__0 () [0x00000] in /Users/builder/data/lanes/monodroid-mavericks-monodroid-5.1-series/d419c934/source/monodroid/src/Mono.Android/platforms/android-10/src/generated/Android.Nfc.Tech.MifareClassic.cs:367  
at System.Threading.Tasks.Task`1[System.Byte[]].InnerInvoke () [0x00012] in <filename unknown>:0  
at System.Threading.Tasks.Task.Execute () [0x00016] in <filename unknown>:0  
--- End of managed exception stack trace ---
java.io.IOException: Transceive failed
at android.nfc.TransceiveResult.getResponseOrThrow(TransceiveResult.java:52)
at android.nfc.tech.BasicTagTechnology.transceive(BasicTagTechnology.java:151)
at android.nfc.tech.MifareClassic.readBlock(MifareClassic.java:425)
at dalvik.system.NativeStart.run(Native Method)

1 个答案:

答案 0 :(得分:0)

太快了!
设备正在快速读取卡片。插入System.Threading.Thread.Sleep(100)后它终于奏效了! for循环现在看起来像这样:

for(int i = firstBlock; i < lastBlock; i++)
{
    if(mifc.IsConnected)
    {
        DisplayMessage("Read Block " + i);
        System.Threading.Thread.Sleep(100);
        byte[] block = mifc.ReadBlockAsync(i).Result;
        lstBlocks.Add(block);
    }
    else
    {
        DisplayMessage("Card Disconnected");
    } 
}