See: Description
Interface | Description |
---|---|
AudioJackReader.OnAuthCompleteListener |
Interface definition for a callback to be invoked when the reader
authentication is complete.
|
AudioJackReader.OnCustomIdAvailableListener |
Interface definition for a callback to be invoked when the reader sends
the custom ID.
|
AudioJackReader.OnDeviceIdAvailableListener |
Interface definition for a callback to be invoked when the reader sends
the device ID.
|
AudioJackReader.OnDukptOptionAvailableListener |
Interface definition for a callback to be invoked when the reader sends
the DUKPT option.
|
AudioJackReader.OnFirmwareVersionAvailableListener |
Interface definition for a callback to be invoked when the reader sends
the firmware version.
|
AudioJackReader.OnPiccAtrAvailableListener |
Interface definition for a callback to be invoked when the reader sends
the ATR from PICC.
|
AudioJackReader.OnPiccResponseApduAvailableListener |
Interface definition for a callback to be invoked when the reader sends
the response APDU from PICC.
|
AudioJackReader.OnRawDataAvailableListener |
Interface definition for a callback to be invoked when the reader sends
the raw data.
|
AudioJackReader.OnResetCompleteListener |
Interface definition for a callback to be invoked when the reader reset
is complete.
|
AudioJackReader.OnResultAvailableListener |
Interface definition for a callback to be invoked when the reader sends
the result.
|
AudioJackReader.OnStatusAvailableListener |
Interface definition for a callback to be invoked when the reader sends
the status.
|
AudioJackReader.OnTrackDataAvailableListener |
Interface definition for a callback to be invoked when the reader sends
the track data.
|
AudioJackReader.OnTrackDataNotificationListener |
Interface definition for a callback to be invoked when the reader
notifies the track data.
|
AudioJackReader.OnTrackDataOptionAvailableListener |
Interface definition for a callback to be invoked when the reader sends
the track data option.
|
Class | Description |
---|---|
AesTrackData |
The
AesTrackData class represents the track data after swiping a
card from the reader using AES mode. |
AudioJackReader |
The
AudioJackReader class represents ACS audio jack readers. |
CRC16 |
The
CRC16 class is used to compute a CRC16 checksum from data
provided as input value. |
DukptReceiver |
The
DukptReceiver class generates the future keys according to
ANSI X9.24-1:2009. |
DukptTrackData |
The
DukptTrackData class represents the track data after swiping
a card from the reader using DUKPT mode. |
Result |
The
Result class represents the execution result after
performing the operation from the reader. |
Status |
The
Status class represents the status about the reader. |
Track1Data |
The
Track1Data class is used to decode the track 1 data into
fields specified by ISO/IEC 7813. |
Track2Data |
The
Track2Data class is used to decode the track 2 data into
fields specified by ISO/IEC 7813. |
TrackData |
The
TrackData class represents the track data after swiping a
card from the reader. |
Exception | Description |
---|---|
CardTimeoutException |
Thrown when the card operation timed out.
|
CommunicationErrorException |
Thrown when there is an error occurred in the communication.
|
CommunicationTimeoutException |
Thrown when there is timeout in the communication.
|
InvalidDeviceStateException |
Thrown when the state of reader is invalid.
|
ProtocolMismatchException |
Thrown when the requested protocols are incompatible with the protocol
currently in use with the card.
|
ReaderException |
ReaderException is the superclass of those exceptions that can
be thrown during normal operation of the reader. |
ReaderNotStartedException |
Thrown when the reader is not started.
|
RemovedCardException |
Thrown when a program attempts to access a card which is removed.
|
RequestQueueFullException |
Thrown when the request queue is full.
|
UnresponsiveCardException |
Thrown when a program attempts to access a card which is not responding to a
reset.
|
UnsupportedCardException |
Thrown when a program attempts to access a card which is not supported.
|
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="..."> ... <uses-permission android:name="android.permission.RECORD_AUDIO" /> ... </manifest>To create and initialize a
AudioJackReader
object, get
an instance of
AudioManager
by calling
Context.getSystemService()
method.
... public class MainActivity extends Activity { ... private AudioManager mAudioManager; private AudioJackReader mReader; ... @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); mReader = new AudioJackReader(mAudioManager); ... } ... } ...
For Android 6.0 or later, you must request RECORD_AUDIO
permission
at run-time in order to use the reader.
To start an instance of the AudioJackReader
object,
use the start()
method. If
your application does not stop the reader properly, it will make other
applications cannot use the audio channels. To stop the instance of the
AudioJackReader
object, use the
stop()
method. The following
activity implements the required lifecycle methods.
... public class MainActivity extends Activity { ... @Override protected void onResume() { super.onResume(); /* Request record audio permission. */ if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) { if (!mPermissionDenied) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, REQUEST_RECORD_AUDIO); } else { finish(); } } else { mReader.start(); } } @Override protected void onPause() { super.onPause(); mReader.stop(); } ... } ...
The result will be returned from onRequestPermissionsResult()
.
After the permission was granted, the app can use the reader.
@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (requestCode == REQUEST_RECORD_AUDIO) { if ((grantResults.length > 0) && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) { mReader.start(); } else { mPermissionDenied = true; } } else { super.onRequestPermissionsResult(requestCode, permissions, grantResults); } }
The sleep mode of reader is enabled by default. To use the reader, your
application should call reset()
method. If you register a callback using
setOnResetCompleteListener()
method, it will receive a notification after the
operation is completed.
... /* Reset the reader. */ mReader.reset(); ... /* Set the reset complete callback. */ mReader.setOnResetCompleteListener( new AudioJackReader.OnResetCompleteListener() { @Override public void onResetComplete(AudioJackReader reader) { /* TODO: Add your code here to process the notification. */ ... } }); ...
You can enable the sleep mode by calling
sleep()
method. If you
register a callback using
setOnResultAvailableListener()
method, it will receive a notification after the
operation is completed.
... /* Enable the sleep mode. */ mReader.sleep(); ... /* Set the result callback. */ mReader.setOnResultAvailableListener( new AudioJackReader.OnResultAvailableListener() { @Override public void onResultAvailable(AudioJackReader reader, Result result) { /* TODO: Add your code here to process the notification. */ ... } }); ...
You can set the sleep timeout by calling
setSleepTimeout()
method. If you register a callback using
setOnResultAvailableListener()
method, it will receive a notification after the
operation is completed.
... /* Set the sleep timeout to 10 seconds. */ mReader.setSleepTimeout(10); ... /* Set the result callback. */ mReader.setOnResultAvailableListener( new AudioJackReader.OnResultAvailableListener() { @Override public void onResultAvailable(AudioJackReader reader, Result result) { /* TODO: Add your code here to process the notification. */ ... } }); ...
To get the firmware version, you need to register a callback using
setOnFirmwareVersionAvailableListener()
method and send a request using
getFirmwareVersion()
method.
... /* Get the firmware version. */ mReader.getFirmwareVersion(); ... /* Set the firmware version callback. */ mReader.setOnFirmwareVersionAvailableListener( new AudioJackReader.OnFirmwareVersionAvailableListener() { @Override public void onFirmwareVersionAvailable(AudioJackReader reader, String firmwareVersion) { /* TODO: Add your code here to process the firmware version. */ ... } }); ...
To get the status, you need to register a callback using
setOnStatusAvailableListener()
method and send a request using
getStatus()
method.
... /* Get the status. */ mReader.getStatus(); ... /* Set the status callback. */ mReader.setOnStatusAvailableListener( new AudioJackReader.OnStatusAvailableListener() { @Override public void onStatusAvailable(AudioJackReader reader, Status status) { /* TODO: Add your code here to process the status. */ ... } }); ...
When you swipe a card, the reader notifies a track data and sends it through an
audio channel to your Android device. To receive the notification and the track
data, you need to register a callback using
setOnTrackDataNotificationListener()
and
setOnTrackDataAvailableListener()
method. You can check the track error using
TrackData.getTrack1ErrorCode()
and
TrackData.getTrack2ErrorCode()
methods. Note that
the received TrackData
object will be the instance of
AesTrackData
or
DukptTrackData
according to the settings. You must
check the type of instance before accessing the object.
You can get the track data using
AesTrackData.getTrackData()
,
DukptTrackData.getTrack1Data()
and
DukptTrackData.getTrack2Data()
methods. Note that the
track data of AesTrackData
object is encrypted by AES
while the track data of DukptTrackData
object is
encrypted by Triple DES. You must decrypt it before accessing the original track
data.
After decrypting the track data of AesTrackData
object, you can use Track1Data.fromByteArray(byte[])
and Track2Data.fromByteArray(byte[])
methods to decode
the track data into fields. For the track data or masked track data of
DukptTrackData
object, you can use
Track1Data.fromString(String)
and
Track2Data.fromString(String)
methods.
... /* Set the track data notification callback. */ mReader.setOnTrackDataNotificationListener( new AudioJackReader.OnTrackDataNotificationListener() { @Override public void onTrackDataNotification(AudioJackReader reader) { /* TODO: Add your code here to process the notification. */ ... } }); ... /* Set the track data callback. */ mReader.setOnTrackDataAvailableListener( new AudioJackReader.OnTrackDataAvailableListener() { @Override public void onTrackDataAvailable(AudioJackReader reader, TrackData trackData) { /* TODO: Add your code here to process the track data. */ if ((trackData.getTrack1ErrorCode() != TrackData.TRACK_ERROR_SUCCESS) || (trackData.getTrack2ErrorCode() != TrackData.TRACK_ERROR_SUCCESS)) { /* Show the track error. */ ... return; } if (trackData instanceof AesTrackData) { AesTrackData aesTrackData = (AesTrackData) trackData; ... } else if (trackData instanceof DukptTrackData) { DukptTrackData dukptTrackData = (DukptTrackData) trackData; ... } ... } }); ...
If you want to access a raw data of a response, you can register a callback
using setOnRawDataAvailableListener()
method. Note that the raw data is not verified
by CRC16 checksum.
... /* Set the raw data callback. */ mReader.setOnRawDataAvailableListener( new AudioJackReader.OnRawDataAvailableListener() { @Override public void onRawDataAvailable(AudioJackReader reader, byte[] rawData) { /* TODO: Add your code here to process the raw data. */ ... } }); ...
If your reader came with the ICC interface, you can operate the card using the following methods:
Before transmitting the APDU, you need to reset the card using
power()
method.
The ATR string will be returned if the card is operated normally. Otherwise, it
will throw ReaderException
to indicate the error.
After resetting the card, the card state is changed to
CARD_NEGOTIABLE
or
CARD_SPECIFIC
. You
cannot transmit the APDU if the card state is not equal to
CARD_SPECIFIC
. To select
the protocol, invoke
setProtocol()
method with the preferred protocols.
After selecting the protocol, you can transmit the command APDU using
transmit()
method.
... int slotNum = 0; int action = AudioJackReader.CARD_WARM_RESET; int timeout = 10 * 1000; /* 10 seconds. */ byte[] atr = null; int preferredProtocols = AudioJackReader.PROTOCOL_T0 | AudioJackReader.PROTOCOL_T1; int activeProtocol = 0; byte[] commandApdu = { 0x00, (byte) 0x84, 0x00, 0x00, 0x08 }; byte[] responseApdu = null; ... try { /* Reset the card. */ atr = mReader.power(slotNum, action, timeout); if (atr != null) { /* Set the protocol. */ activeProtocol = mReader.setProtocol(slotNum, preferredProtocols, timeout); /* Transmit the APDU. */ responseApdu = mReader.transmit(slotNum, commandApdu, timeout); } } catch (ReaderException e) { e.printStackTrace(); } ...
You can transmit the control command to the reader using
control()
method if the reader supports a set of escape commands.
... int controlCode = AudioJackReader.IOCTL_CCID_ESCAPE; byte[] controlCommand = { (byte) 0xE0, 0x00, 0x00, 0x18, 0x00 }; byte[] controlResponse = null; ... try { /* Transmit the control command. */ controlResponse = mReader.control(slotNum, controlCode, controlCommand, timeout); } catch (ReaderException e) { e.printStackTrace(); } ...
If your reader came with the PICC interface, you can operate the card using the following methods:
Before transmitting the APDU, you need to power on the card using
piccPowerOn()
method. If you register a callback using
setOnPiccAtrAvailableListener()
method, you can receive the ATR string from the
card.
To transmit the APDU, you can use
piccTransmit()
method. If you register a callback using
setOnPiccResponseApduAvailableListener()
method, you can receive the response
APDU from the card.
After using the card, you can power off the card using
piccPowerOff()
method.
If you register a callback using
setOnResultAvailableListener()
method, it will receive a notification after the
operation is completed.
... int timeout = 1; /* 1 second. */ int cardType = PICC_CARD_TYPE_ISO14443_TYPE_A | PICC_CARD_TYPE_ISO14443_TYPE_B | PICC_CARD_TYPE_FELICA_212KBPS | PICC_CARD_TYPE_FELICA_424KBPS | PICC_CARD_TYPE_AUTO_RATS; byte[] apdu = { 0x00, (byte) 0x84, 0x00, 0x00, 0x08 }; ... /* Power on the PICC. */ mReader.piccPowerOn(timeout, cardType); ... /* Transmit the APDU. */ mReader.piccTransmit(timeout, apdu); ... /* Power off the PICC. */ mReader.piccPowerOff(); ... /* Set the PICC ATR callback. */ mReader.setOnPiccAtrAvailableListener( new AudioJackReader.OnPiccAtrAvailableListener() { @Override public void onPiccAtrAvailable(AudioJackReader reader, byte[] atr) { /* TODO: Add your code here to process the ATR. */ ... } }); /* Set the PICC response APDU callback. */ mReader.setOnPiccResponseApduAvailableListener( new AudioJackReader.OnPiccResponseApduAvailableListener() { @Override public void onPiccResponseApduAvailable(AudioJackReader reader, byte[] responseApdu) { /* TODO: Add your code here to process the response APDU. */ ... } }); /* Set the result callback. */ mReader.setOnResultAvailableListener( new AudioJackReader.OnResultAvailableListener() { @Override public void onResultAvailable(AudioJackReader reader, Result result) { /* TODO: Add your code here to process the notification. */ ... } }); ...
Copyright © 2013-2018, Advanced Card Systems Ltd. All rights reserved.