简体   繁体   English

通过USB的Android智能卡接口

[英]Android smart-card interface over USB

I need to read/write to a smart-card using a smart-card reader attached to an Android phone by USB. 我需要使用通过USB连接到Android手机的智能卡读卡器来读/写智能卡。 Is this possible with native APIs or do I have to install other libraries? 这可能是使用本机API还是我必须安装其他库?

Thank you 谢谢

Sadly there is no abstraction layer like PC/SC in the native Android system. 遗憾的是,原生Android系统中没有像PC/SC这样的抽象层。 But you can utilize Android USB library to talk directly to the USB smart card reader. 但您可以利用Android USB库直接与USB智能卡读卡器对话。

In java the communication takes place using package javax.smarcard which is not available for Android so take a look here for getting an idea as to how you can communicate or send/receive APDU (smartcard command). 在java中,通过使用不能用于Android的包javax.smarcard进行通信,因此请查看此处以了解如何进行通信或发送/接收APDU(智能卡命令)。

Using the USB Host API to connect : : 使用USB Host API连接::

//Allows you to enumerate and communicate with connected USB devices.
UsbManager mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
//Explicitly asking for permission
final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
PendingIntent mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
HashMap<String, UsbDevice> deviceList = mUsbManager.getDeviceList();

UsbDevice device = deviceList.get("//the device you want to work with");
if (device != null) {
    mUsbManager.requestPermission(device, mPermissionIntent);
}

And now you will need endpoints, simply send an APDU (smartcard command) over the bulk-out endpoint and expect to receive a response APDU over the bulk-in endpoint. 现在您将需要端点,只需在批量输出端点上发送APDU(智能卡命令),并期望通过批量输入端点接收响应APDU。

Code to get endpoints :: 获取端点的代码::

UsbEndpoint epOut = null, epIn = null;
UsbInterface usbInterface;

UsbDeviceConnection connection = mUsbManager.openDevice(device);

    for (int i = 0; i < device.getInterfaceCount(); i++) {
        usbInterface = device.getInterface(i);
        connection.claimInterface(usbInterface, true);

        for (int j = 0; j < usbInterface.getEndpointCount(); j++) {
            UsbEndpoint ep = usbInterface.getEndpoint(j);

            if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
                if (ep.getDirection() == UsbConstants.USB_DIR_OUT) {
                    // from host to device
                    epOut = ep;

                } else if (ep.getDirection() == UsbConstants.USB_DIR_IN) {
                    // from device to host
                    epIn = ep;
                }
            }
        }
    }

To send commands use this : 要发送命令,请使用:

public void write(UsbDeviceConnection connection, UsbEndpoint epOut, byte[] command) {
result = new StringBuilder();
connection.bulkTransfer(epOut, command, command.length, TIMEOUT);
//For Printing logs you can use result variable
for (byte bb : command) {
    result.append(String.format(" %02X ", bb));
}
}

And to read data or send binary read you can use this code: 要读取数据或发送二进制读取,您可以使用以下代码:

public int read(UsbDeviceConnection connection, UsbEndpoint epIn) {
result = new StringBuilder();
final byte[] buffer = new byte[epIn.getMaxPacketSize()];
int byteCount = 0;
byteCount = connection.bulkTransfer(epIn, buffer, buffer.length, TIMEOUT);
//For Printing logs you can use result variable
if (byteCount >= 0) {
    for (byte bb : buffer) {
        result.append(String.format(" %02X ", bb));
    }

    //Buffer received was : result.toString()
} else {
    //Something went wrong as count was : " + byteCount
}

return byteCount;
}

Now let's take an example of this command like the one here: 62000000000000000000 How you can send this is : 现在让我们举一个这样的命令的例子,如下所示: 62000000000000000000如何发送它是:

write(connection, epOut, "62000000000000000000");

Now after you have successfully sent the APDU command, you can read the response using : 现在,在成功发送APDU命令后,您可以使用以下命令读取响应:

read(connection, epIn);

And receive something like 并收到类似的东西

80 18000000 00 00 00 00 00 3BBF11008131FE45455041000000000000000000000000F1

Now the response received in the code here will be in the result variable of read() method.And likewise you can write your own commands for communicating. 现在,代码中收到的响应将在read()的结果变量中。同样,您可以编写自己的命令进行通信。

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

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