Most visited

Recently visited

Added in API level 19

HostApduService

public abstract class HostApduService
extends Service

java.lang.Object
   ↳ android.content.Context
     ↳ android.content.ContextWrapper
       ↳ android.app.Service
         ↳ android.nfc.cardemulation.HostApduService


HostApduService是一个便利的 Service类,可以扩展为模拟Android服务组件内的NFC卡。

Developer Guide

For a general introduction to card emulation, see Host-based Card Emulation.

NFC Protocols

该类仿真的卡基于NFC-Forum ISO-DEP协议(基于ISO / IEC 14443-4),并支持ISO / IEC 7816-4规范中定义的处理命令应用协议数据单元(APDU)。

Service selection

当远程NFC设备想要与您的服务通话时,它会发送ISO / IEC 7816-4规范中定义的所谓“SELECT AID”APDU。 AID是ISO / IEC 7816-4中定义的应用程序标识符。

AID的注册程序在ISO / IEC 7816-5规范中定义。 如果您不想注册AID,则可以在专有范围内自由使用AID:第一个字节的第8-5位必须各设置为“1”。 例如,“0xF00102030405”是专有的AID。 如果确实使用专有AID,则建议选择至少6个字节的AID,以降低与可能使用专有AID的其他应用程序发生冲突的风险。

AID groups

在某些情况下,服务可能需要注册多个AID来实现某个应用程序,并且需要确定它是所有这些AID的默认处理程序(而不是组中的某些AID转到其他服务)。

一个AID组是应该被OS视为一起归属的AID列表。 对于AID组中的所有AID,操作系统将保证以下之一:

In other words, there is no in-between state, where some AIDs in the group can be routed to this service, and some to another.

AID groups and categories

每个AID组都可以与一个类别关联。 这允许Android OS对服务进行分类,并允许用户在类别级别而不是AID级别设置默认值。

您可以使用 isDefaultServiceForCategory(android.content.ComponentName, String)来确定您的服务是否是某个类别的默认处理程序。

在这个版本的平台中,唯一已知的类别是CATEGORY_PAYMENTCATEGORY_OTHER 没有类别的AID组或者当前平台版本无法识别的类别将自动分组到CATEGORY_OTHER类别中。

Service AID registration

为了告知平台哪些AIDs组被这个服务请求,一个SERVICE_META_DATA条目必须包含在服务声明中。 HostApduService清单声明的示例如下所示:

 <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_ervice" android:resource="@xml/apduservice"/>
 </service>
This meta-data tag points to an apduservice.xml file. An example of this file with a single AID group declaration is shown below:
 <host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
           android:description="@string/servicedesc" android:requireDeviceUnlock="false">
       <aid-group android:description="@string/aiddescription" android:category="other">
           <aid-filter android:name="F0010203040506"/>
           <aid-filter android:name="F0394148148100"/>
       </aid-group>
 </host-apdu-service>
 

<host-apdu-service>需要包含<android:description>属性,其中包含可能在UI中显示的用户友好的服务说明。 可以使用<requireDeviceUnlock>属性指定在调用此服务来处理APDU之前必须先解锁设备。

<host-apdu-service>必须包含一个或多个<aid-group>标签。 每个<aid-group>必须包含一个或多个<aid-filter>标签,每个标签包含一个AID。 AID必须以十六进制格式指定,并且包含偶数个字符。

AID conflict resolution

Multiple HostApduServices may be installed on a single device, and the same AID can be registered by more than one service. The Android platform resolves AID conflicts depending on which category an AID belongs to. Each category may have a different conflict resolution policy. For example, for some categories the user may be able to select a default service in the Android settings UI. For other categories, to policy may be to always ask the user which service is to be invoked in case of conflict. To query the conflict resolution policy for a certain category, see getSelectionModeForCategory(String).

Data exchange

一旦平台将“SELECT AID”命令APDU解析为特定服务组件,“SELECT AID”命令APDU和所有后续命令APDU将通过 processCommandApdu(byte[], Bundle)发送到该服务,直到:

These two scenarios are indicated by a call to onDeactivated(int).

使用此类需要 FEATURE_NFC_HOST_CARD_EMULATION在设备上。

Summary

Constants

int DEACTIVATION_DESELECTED

原因为 onDeactivated(int)

int DEACTIVATION_LINK_LOSS

原因为 onDeactivated(int)

String SERVICE_INTERFACE

必须声明为由服务处理的 Intent操作。

String SERVICE_META_DATA

包含有关此服务的更多信息的元数据元素的名称。

Inherited constants

From class android.app.Service
From class android.content.Context
From interface android.content.ComponentCallbacks2

Public constructors

HostApduService()

Public methods

final void notifyUnhandled()

调用此方法允许服务告诉操作系统它将无法完成此事务 - 例如,因为它需要当时不存在的数据连接。

final IBinder onBind(Intent intent)

将通信信道返回给服务。

abstract void onDeactivated(int reason)

这种方法将在两种可能的情况下被调用:

  • The NFC link has been deactivated or lost
  • A different AID has been selected and was resolved to a different service component

  • abstract byte[] processCommandApdu(byte[] commandApdu, Bundle extras)

    当从远程设备接收到命令APDU时,将调用此方法。

    final void sendResponseApdu(byte[] responseApdu)

    将响应APDU发送回远程设备。

    Inherited methods

    From class android.app.Service
    From class android.content.ContextWrapper
    From class android.content.Context
    From class java.lang.Object
    From interface android.content.ComponentCallbacks2
    From interface android.content.ComponentCallbacks

    Constants

    DEACTIVATION_DESELECTED

    Added in API level 19
    int DEACTIVATION_DESELECTED

    原因为 onDeactivated(int)

    指示取消激活是由于选择了不同的AID(隐式取消选择当前在逻辑通道上激活的AID)。

    请注意,这个下一个AID仍然可以解析为此服务,在这种情况下 processCommandApdu(byte[], Bundle)将再次被调用。

    常数值:1(0x00000001)

    DEACTIVATION_LINK_LOSS

    Added in API level 19
    int DEACTIVATION_LINK_LOSS

    原因为onDeactivated(int) 表示取消激活是由于NFC链路丢失。

    常量值:0(0x00000000)

    SERVICE_INTERFACE

    Added in API level 19
    String SERVICE_INTERFACE

    Intent必须声明为由服务处理的操作。

    常量值:“android.nfc.cardemulation.action.HOST_APDU_SERVICE”

    SERVICE_META_DATA

    Added in API level 19
    String SERVICE_META_DATA

    包含有关此服务的更多信息的元数据元素的名称。

    常量值:“android.nfc.cardemulation.host_apdu_service”

    Public constructors

    HostApduService

    Added in API level 19
    HostApduService ()

    Public methods

    notifyUnhandled

    Added in API level 19
    void notifyUnhandled ()

    调用此方法允许服务告诉操作系统它将无法完成此事务 - 例如,因为它需要当时不存在的数据连接。 操作系统可以使用该指示为用户提供可以处理所选择的最后AID的替代应用程序的列表。 如果用户从列表中选择应用程序,则该操作本身不会导致默认值被更改; 所选的应用程序将只为下一次点击而被调用。 如果没有其他应用程序可以处理此事务,则操作系统将显示一个错误对话框,指出您的服务无法完成该事务。

    注意:可以在第一个 processCommandApdu(byte[], Bundle)调用和 onDeactivated(int)调用之间的任何地方调用此方法。

    onBind

    Added in API level 19
    IBinder onBind (Intent intent)

    将通信信道返回给服务。 如果客户端无法绑定到服务,可能会返回null。 返回的IBinder通常用于一个复杂的接口described using aidl

    请注意,与其他应用程序组件不同,此处返回的IBinder接口调用可能不会发生在进程的主线程上 有关主线程的更多信息可以在Processes and Threads中找到。

    Parameters
    intent Intent: The Intent that was used to bind to this service, as given to Context.bindService. Note that any extras that were included with the Intent at that point will not be seen here.
    Returns
    IBinder Return an IBinder through which clients can call on to the service.

    onDeactivated

    Added in API level 19
    void onDeactivated (int reason)

    这种方法将在两种可能的情况下被调用:

  • The NFC link has been deactivated or lost
  • A different AID has been selected and was resolved to a different service component

    Parameters
    reason int: Either DEACTIVATION_LINK_LOSS or DEACTIVATION_DESELECTED
  • processCommandApdu

    Added in API level 19
    byte[] processCommandApdu (byte[] commandApdu, 
                    Bundle extras)

    当从远程设备接收到命令APDU时,将调用此方法。 响应APDU可以通过在此方法中返回字节数组直接提供。 请注意,一般来说,响应APDU必须尽可能快地发送,因为当调用此方法时,用户可能将他的设备通过NFC读取器。

    如果有多个服务在其元数据条目中注册了相同的AID,则只有在用户明确选择了服务时才会被调用,无论是默认还是仅用于下一次点击。

    此方法在您的应用程序的主线程上运行。 如果您无法立即返回响应APDU,请返回null并稍后使用sendResponseApdu(byte[])方法。

    Parameters
    commandApdu byte: The APDU that was received from the remote device
    extras Bundle: A bundle containing extra data. May be null.
    Returns
    byte[] a byte-array containing the response APDU, or null if no response APDU can be sent at this point.

    sendResponseApdu

    Added in API level 19
    void sendResponseApdu (byte[] responseApdu)

    将响应APDU发送回远程设备。

    注意:这个方法可以从任何线程调用并且不会被阻塞。

    Parameters
    responseApdu byte: A byte-array containing the reponse APDU.

    Hooray!