简体   繁体   English

如何通过基于主机的卡仿真(HCE)将移动设备设置为NFC标签

[英]How to set mobile as NFC tag with host-based card emulation (HCE)

I want to write a program that can store a unique ID and then send it as NFC tag to another NFC reader devices. 我想编写一个可以存储唯一ID的程序,然后将其作为NFC标签发送到另一个NFC阅读器设备。 How can I send my code ( nfcTag ) to the NFC reader? 如何将我的代码( nfcTag )发送到NFC阅读器? Can I do this without having an AID for my application? 我可以在没有应用程序AID的情况下这样做吗?

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        PackageManager pm = this.getPackageManager();
        String nfcTag="123456789";                          //the code wants to work as NFC tag
        TextView msg = (TextView) findViewById(R.id.txtShow);
        byte[] t2 = new byte[9];                            //t2 return from processCommandApdu

        t2 = nfcTag.getBytes();

        @Override
        public byte[] processCommandApdu(byte[] apdu, Bundle extras) {
            msg.setText(nfcTag);



            return t2;                  //return nfcTag too read with NFC tag reader devices
        }
        @Override
        public void onDeactivated(int reason) {
            msg.setText("Your phone does not has HCE hardware.");

            if (!pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)) {
                // HCE is not available on the device.
                Toast.makeText(this, "The device does not has HCE hardware.",
                        Toast.LENGTH_SHORT).show();
            }
            else {
                Toast.makeText(this, "HCE supported on your device.",
                        Toast.LENGTH_SHORT).show();
            }
        }
    }
}

and here is AndroidManifest.xml 这是AndroidManifest.xml

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <service android:name=".MyHostApduService" android:exported="true"
            android:permission="android.permission.BIND_NFC_SERVICE">
            <intent-filter>
                <action android:name="android.nfc.cardemulation.action.HOST_APDU_SERVICE"/>
            </intent-filter>
        </service>

        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

For Android HCE, you will first need to create a service component (that's a separate class and not part of your activity): 对于Android HCE,您首先需要创建一个服务组件(这是一个单独的类,而不是您的活动的一部分):

public class MyHostApduService extends HostApduService {
    @Override
    public byte[] processCommandApdu(byte[] apdu, Bundle extras) {
        // TODO: process the incoming APDU command(s) and give reasonable responses
    }

    @Override
    public void onDeactivated(int reason) {
    }
}

Smartcard readers (actually the software that accesses cards through them) use ISO/IEC 7816-4 APDU command sequences to communicate with (emulated) contactless smartcards. 智能卡读取器(实际上是通过它们访问卡的软件)使用ISO / IEC 7816-4 APDU命令序列与(模拟)非接触式智能卡进行通信。 Therefore, your HCE service needs to process these APDUs and create proper respondes for the reader. 因此,您的HCE服务需要处理这些APDU并为读取器创建正确的响应。 This command sequence will consist of at least the SELECT (by AID) command that was used to select your HCE service. 该命令序列将至少包含用于选择HCE服务的SELECT(通过AID)命令。 You should respond to that SELECT command with status word 9000 (ie new byte[] { (byte)0x90, (byte)0x00 } ) and, optionally, a file control information structure. 您应该以状态字9000 (即new byte[] { (byte)0x90, (byte)0x00 } )和一个可选的文件控制信息结构来响应SELECT命令。

You further need to define an AID filter for your HCE service: 您还需要为您的HCE服务定义AID过滤器:

<service android:name=".MyHostApduService" android:exported="true"
         android:permission="android.permission.BIND_NFC_SERVICE">
    <intent-filter>
        <action android:name="android.nfc.cardemulation.action.HOST_APDU_SERVICE"/>
    </intent-filter>
    <meta-data android:name="android.nfc.cardemulation.host_apdu_service"
               android:resource="@xml/apduservice"/>
</service>

And in res/xml/apduservice.xml : 并在res/xml/apduservice.xml

<host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
           android:description="My HCE Service"
           android:requireDeviceUnlock="false">
    <aid-group android:description="My HCE Service" android:category="other">
        <aid-filter android:name="F0010203040506"/>
    </aid-group>
</host-apdu-service>

Replace the AID F0010203040506 with whatever your reader (software) uses to access the application on your (emulated) smartcard. 用您的阅读器(软件)用来访问(模拟)智能卡上的应用程序的内容替换AID F0010203040506

What you cannot do with Android HCE: 无法使用Android HCE执行以下操作:

  • Emulate a specific anti-collision identifier (UID) 模拟特定的防冲突标识符(UID)
  • Choose the RF signaling protocol (can be either NFC-A or NFC-B) 选择RF信令协议(可以是NFC-A或NFC-B)
  • Communicate with readers that don't send an ISO SELECT (by AID/DF name) command 与不发送ISO SELECT(通过AID / DF名称)命令的阅读器进行通信

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM