2017-06-08 23 views

回答

0

可悲的是沒有像原生的Android系統PC/SC沒有抽象層。但是您可以使用Android USB library直接與USB智能卡讀卡器對話。

+0

其實我需要通過USB直接將讀卡器連接到手機,因爲我不會有電腦或其他任何東西,只需安卓手機和讀卡器即可。 –

+0

而且我還需要支持沒有NFC的手機 –

+0

請等待,因此您的意思是您想要將USB智能卡讀卡器連接到Android手機? – arminb

0

在java中,通信是使用包不可用於Android的包javax.smarcard進行的,因此需要look here瞭解如何通信或發送/接收APDU(智能卡命令)。

使用USB主機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); 
} 

那麼現在就需要終端,只需在批量出端點發送APDU(智能卡命令),並期望在收到響應APDU大容量端點。

代碼來獲得端點::

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; 
       } 
      } 
     } 
    } 

發送命令使用:

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)); 
} 
} 

並讀取數據或發送二進制讀取,你可以使用此代碼:

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; 
} 

現在讓我們來看看這個命令的例子:62000000000000000000如何發送這個命令是:

write(connection, epOut, "62000000000000000000"); 

現在您已成功發送的APDU命令後,您可以使用讀取響應:

read(connection, epIn); 

和接收像

80 18000000 00 00 00 00 00 3BBF11008131FE45455041000000000000000000000000F1 

現在的代碼在這裏獲得響應將在read()方法的結果變量中。同樣,您可以編寫自己的通信命令。