Android设备作为另一个Android HCE的NFC Reader

时间:2015-07-07 14:15:06

标签: android nfc hce

我已经意识到当一个Android设备作为NFC阅读器与安装在另一个Android设备上的HCE应用程序通信时的情况。但有两个问题:

  1. 仅当充当NFC阅读器的Android版设备为4.4及以上时才有效。
  2. 手机之间的通信失败并且一直在恢复(停用的原因是DEACTIVATION_LINK_LOSS)。
  3. 以下是我的NFC阅读器应用的主要类别:

    public class ReadingCardActivity 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()
                }
        };
        TextView tv;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.tag);
            tv = (TextView) findViewById(R.id.tv);
            tv.setMovementMethod(new ScrollingMovementMethod());
        }
    
        @Override
        protected void onResume() {
            super.onResume();
            // creating pending intent:
            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();
            // disabling foreground dispatch:
            NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
            nfcAdapter.disableForegroundDispatch(this);
        }
    
        @Override
        protected void onNewIntent(Intent intent) {
            if (intent.getAction().equals(NfcAdapter.ACTION_TAG_DISCOVERED)) {
                if (intent.getAction() != null) {
                    Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
                    try {
                        IsoDep iso = IsoDep.get(tagFromIntent);
                        iso.connect();
                        tv.setText(tv.getText() + "\nResponse from card: " + Utils.byteArrayToHexString(selectAID(iso)));
                        iso.close();
                    } catch (Exception ex) {
                        tv.setText(tv.getText() + "\nException: " + ex.toString());
                    }
                }
            }
        }
    
        public byte[] selectAID(IsoDep iso) throws Exception {
            byte[] wakeUpCommand = {(byte) 0x00, (byte) 0xA4, (byte) 0x04,(byte) 0x00, (byte) 0x08,
                    (byte) 0x4C, (byte) 0x65, (byte) 0x6C,(byte) 0x61,
                    (byte) 0x6E, (byte) 0x74, (byte) 0x6F, (byte) 0x73,
                    (byte) 0x00};
            return iso.transceive(wakeUpCommand);
        }
    }
    

    这是我在HCE应用程序中的服务:

    @Override
        public byte[] processCommandApdu(byte[] apdu, Bundle extras) {
            sendResult("Terminal sent apdu " + Utils.byteArrayToHexString(apdu));
            byte[] response = Hex.decodeHex(SUCCESSFUL_RESPONSE.toCharArray());
            return response;
    }
    

    您可能还想查看我的apduservice.xml文件以查看我的AID号码:

    <?xml version="1.0" encoding="utf-8"?>
    <host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
                       android:requireDeviceUnlock="false">
        <aid-group android:category="other">
            <aid-filter android:name="4C656C616E746F73"/>
        </aid-group>
    </host-apdu-service>
    

    它是HCE应用程序中的onDeactivated方法:

    @Override
        public void onDeactivated(int reason) {
            switch (reason) {
                case DEACTIVATION_LINK_LOSS:
                    sendResult("\nDeactivation was due to the NFC link being lost.\n");
                    break;
                case DEACTIVATION_DESELECTED:
                    sendResult("\nDeactivation was due to a different AID being selected.\n");
                    break;
            }
        }
    

    HCE申请的输出:

    +---------------------------------------------+
    Terminal sent apdu 00A40400084C656C616E746F7300
    Deactivation was due to the NFC link being lost.
    Terminal sent apdu 00A40400084C656C616E746F7300
    Deactivation was due to the NFC link being lost.
    Terminal sent apdu 00A40400084C656C616E746F7300
    Deactivation was due to the NFC link being lost.
    +---------------------------------------------+
    

    任何人都可以帮我解决这些问题吗?

0 个答案:

没有答案