Я новичок в разработке с помощью ACR или NFC Reader, особенно для Android. И недавно мне нужно использовать ACR35, и у меня есть SDK и пример от this acs official website. И в качестве примера он отлично работает. И теперь мне нужно создать действие, которое всегда будет готово проверить, не используется ли nfc-карта. Но проблема в том, что я не знаю, как определить, когда nfc-карта прослушивается, и я не знаю, что делать дальше, и я не могу найти выход из примера, поскольку он обнаруживает карту nfc, когда я касаюсь «передать», он не делает это автоматически. Пожалуйста, дайте мне пример кода. Спасибо за ваш ответ.Как использовать ACR35 NFC Reader в Android
ответ
Сначала вы вызываете команду Reset для активации устройства. Когда устройство засыпает (через 4 секунды по умолчанию) * трюк заключается в том, чтобы сохранить его в живых.
Вы можете добиться этого, перезапустив новую команду PowerOn каждый раз, когда предыдущий тайм-аут PowerOn. Что-то вроде этого
void powerOn() {
if (!mReader.piccPowerOn(mPiccTimeout, mPiccCardType)) {
powerOn();
} else {
askNfcForItsId();
}
Не забудьте позвонить POWERON после прочтения НКА в противном случае он заснет после 1-го НКА карты.
* таймаут сброса может быть установлен между 4 и 20 секунд
Немного поздно, но это может помочь кому-то. Я нашел следующий проект на git-хабе. Он показывает, как читать идентификатор тега от acr35 here .
Я использую acr35 в течение некоторого времени, чтобы прочитать идентификатор тега. По моему опыту, это устройство с ошибкой на Android. Я тестировал около 10 устройств и работал только на 3 ...
Я читал оттуда каждую секунду. Он возвращает результаты с последней карты, даже если ее больше нет. Следовательно; Я должен сбросить его дважды за каждое успешное чтение, и потребуется около 6 секунд, чтобы снова включить устройство в состояние чтения ... Также будьте очень осторожны при многопоточности.
Моя реализация на основе данного проекта - добавил простой замок, чтобы остановить запрашивая карту после преуспевающим чтения + полный сброс устройства, filternig же UUID, который читался в очень короткое время после того, как он был прочитан ранее:
ACR3x класс
import com.acs.audiojack.AudioJackReader;
import android.media.AudioManager;
import sk.tido.util.ByteHex;
import java.util.Date;
/**
* This class allows control of the ACR35 reader sleep state and PICC commands
*/
public class Acr3x {
private Acr3xTransmitter transmitter;
private AudioManager mAudioManager;
private AudioJackReader mReader;
private boolean firstReset = true; /** Is this the first reset of the reader? */
/** APDU command for reading a card's UID */
private final byte[] apdu = { (byte) 0xFF, (byte) 0xCA, (byte) 0x00, (byte) 0x00, (byte) 0x00 };
/** Timeout for APDU response (in <b>seconds</b>) */
private final int timeout = 1;
private int acr3xCardType = AudioJackReader.PICC_CARD_TYPE_ISO14443_TYPE_A
| AudioJackReader.PICC_CARD_TYPE_ISO14443_TYPE_B
| AudioJackReader.PICC_CARD_TYPE_FELICA_212KBPS
| AudioJackReader.PICC_CARD_TYPE_FELICA_424KBPS
| AudioJackReader.PICC_CARD_TYPE_AUTO_RATS;
private int acr3xStartAudioLevel = 0;
private Object locking = new Object();
private String lastUuid = "";
private Date lastUuidDate = new Date();
public Acr3x(AudioManager mAudioManager){
this.mAudioManager = mAudioManager;
}
public void start(final Acr3xNotifListener listener){
Runnable r = new Runnable(){
@Override
public void run() {
if(mReader == null){
mReader = new AudioJackReader(mAudioManager);
}
System.out.println("ACR35 reader start");
acr3xStartAudioLevel = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
System.out.println("acr3x start audio stream level: " + acr3xStartAudioLevel);
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC,
mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC), 0);
System.out.println("acr3x set audio stream level: " + mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC));
mReader.start();
mReader.setSleepTimeout(30);
mReader.setOnFirmwareVersionAvailableListener(new AudioJackReader.OnFirmwareVersionAvailableListener() {
@Override
public void onFirmwareVersionAvailable(AudioJackReader reader,
String firmwareVersion) {
System.out.println("acr3x firmware version: " + firmwareVersion);
if(listener != null){
listener.onFirmwareVersionAvailable(firmwareVersion);
}
Acr3x.this.read(listener);
}
});
mReader.reset(new AudioJackReader.OnResetCompleteListener(){
@Override
public void onResetComplete(AudioJackReader arg0) {
mReader.getFirmwareVersion();
}
});
}
};
Thread t = new Thread(r, "Acr3xInitThread");
t.start();
}
/**
* Sets the ACR35 reader to continuously poll for the presence of a card. If a card is found,
* the UID will be returned to the Apache Cordova application
*
* @param callbackContext: the callback context provided by Cordova
* @param cardType: the integer representing card type
*/
public void read(final Acr3xNotifListener callbackContext){
System.out.println("acr3x setting up for reading...");
firstReset = true;
/* Set the PICC response APDU callback */
mReader.setOnPiccResponseApduAvailableListener
(new AudioJackReader.OnPiccResponseApduAvailableListener() {
@Override
public void onPiccResponseApduAvailable(AudioJackReader reader,
byte[] responseApdu) {
/* Update the connection status of the transmitter */
transmitter.updateStatus(true);
/* Print out the UID */
String uuid = ByteHex.bytesToHex(responseApdu);
if(uuid.equalsIgnoreCase("0x9000")){
return;
}
if(uuid.endsWith("9000")){
uuid = uuid.substring(0, uuid.length() - 4);
}
if(uuid.equals(lastUuid)){ // na odfiltrovanie opakujucich sa uuid z citacky z predchadzajuceho citania
if(new Date().getTime() - lastUuidDate.getTime() < 3000){
return;
}
}
lastUuid = uuid;
lastUuidDate = new Date();
synchronized(locking){
System.out.println("acr3x uuid: " + uuid);
if(callbackContext != null){
callbackContext.onUUIDAavailable(uuid);
}
System.out.println("acr3x restarting reader");
transmitter.kill();
try {
locking.wait(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
read(callbackContext);
}
});
/* Set the reset complete callback */
mReader.setOnResetCompleteListener(new AudioJackReader.OnResetCompleteListener() {
@Override
public void onResetComplete(AudioJackReader reader) {
System.out.println("acr3x reset complete");
/* If this is the first reset, the ACR35 reader must be turned off and back on again
to work reliably... */
Thread t = null;
if(firstReset){ //firstReset
t = new Thread(new Runnable() {
public void run() {
try{
/* Set the reader asleep */
mReader.sleep();
/* Wait one second */
Thread.sleep(500);
/* Reset the reader */
mReader.reset();
firstReset = false;
} catch (InterruptedException e) {
e.printStackTrace();
// TODO: add exception handling
}
}
});
} else {
/* Create a new transmitter for the UID read command */
transmitter = new Acr3xTransmitter(mReader, mAudioManager, timeout,
apdu, acr3xCardType, locking);
t = new Thread(transmitter);
}
t.start();
}
});
mReader.start();
mReader.reset();
System.out.println("acr3x setup complete");
}
public void stop(){
if(transmitter != null){
transmitter.kill();
}
System.out.println("acr3x restoring audio level: " + acr3xStartAudioLevel);
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC,acr3xStartAudioLevel, 0);
System.out.println("acr3x set audio stream level: " + mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC));
if(mReader != null){
mReader.stop();
}
}
}
класс передатчик
import com.acs.audiojack.AudioJackReader;
import android.media.AudioManager;
/**
* This class sets up an independent thread for card polling, and is linked to the
* <code>setOnPiccResponseApduAvailableListener</code> callback function
*/
public class Acr3xTransmitter implements Runnable {
private AudioJackReader mReader;
private AudioManager mAudioManager;
//private CallbackContext mContext;
private boolean killMe = false; /** Stop the polling thread? */
private int itersWithoutResponse = 0; /** The number of iterations that have passed with no
response from the reader */
private boolean readerConnected = true; /** Is the reader currently connected? */
private int cardType;
private int timeout;
private byte[] apdu;
private Object locking;
/**
* @param mReader: AudioJack reader service
* @param mAudioManager: system audio service
* @param mContext: context for plugin results
* @param timeout: time in <b>seconds</b> to wait for commands to complete
* @param apdu: byte array containing the command to be sent
* @param cardType: the integer representing card type
*/
public Acr3xTransmitter(AudioJackReader mReader, AudioManager mAudioManager,
int timeout, byte[] apdu, int cardType, Object locking){
this.mReader = mReader;
this.mAudioManager = mAudioManager;
this.timeout = timeout;
this.apdu = apdu;
this.cardType = cardType;
this.locking = locking;
}
/**
* Stops the polling thread
*/
public void kill(){
killMe = true;
}
/**
* Updates the connection status of the reader (links to APDU response callback)
*/
public void updateStatus(boolean status){
readerConnected = status;
}
/**
* Sends the APDU command for reading a card UID every second
*/
@Override
public void run() {
try {
/* Wait one second for stability */
Thread.sleep(1000);
while (!killMe) {
synchronized(locking){
if(killMe){
continue;
}
/* If the reader is not connected, increment no. of iterations without response */
if(!readerConnected){
itersWithoutResponse++;
}
/* Else, reset the number of iterations without a response */
else{
itersWithoutResponse = 0;
}
/* Reset the connection state */
readerConnected = false;
if(itersWithoutResponse == 4) {
/* Communicate to the Cordova application that the reader is disconnected */
System.out.println("acr3x disconnected");
/* Kill this thread */
kill();
} else if(!mAudioManager.isWiredHeadsetOn()) {
System.out.println("acr3x not connected");
/* Kill this thread */
kill();
} else{
System.out.println("acr3x reading...");
/* Power on the PICC */
mReader.piccPowerOn(timeout, cardType);
/* Transmit the APDU */
mReader.piccTransmit(timeout, apdu);
}
}
/* Repeat every second */
Thread.sleep(1000);
}
/* Power off the PICC */
mReader.piccPowerOff();
/* Set the reader asleep */
mReader.sleep();
/* Stop the reader service */
mReader.stop();
synchronized(locking){
locking.notifyAll();
}
} catch (InterruptedException e) {
e.printStackTrace();
// TODO: add exception handling
}
}
}
интерфейса слушателя:
public interface Acr3xNotifListener {
public void onUUIDAavailable(String uuid);
public void onFirmwareVersionAvailable(String firmwareVersion);
}
- 1. Android NFC reader для FeliCa
- 2. NFC reader команды sniffer
- 3. NFC reader writer
- 4. Как использовать считыватель NFC?
- 5. Чтение данных в телефоне NFC с помощью NFC-Reader
- 6. Как однозначно идентифицировать NFC-Reader от других читателей NFC?
- 7. NFC Reader: ACR122U-A9 не содержит теги
- 8. Отключить стандартный Windows Phone NFC Reader
- 9. Использование NFC Reader с Adobe AIR
- 10. Интерфейс NFC reader acr122u с веб-приложениями
- 11. Доступ к режиму эмуляции карт на USB-NFC-Reader
- 12. Открыть приложение для Android на NFC и использовать тег NFC
- 13. Как использовать ado.net reader?
- 14. NFC Reader не может прочитать данные эмуляции зашифрованных карт
- 15. Android-программа для взаимодействия с Square Reader
- 16. Получить фиксированный ID чипа NFC в Android
- 17. Libgdx и Android NFC
- 18. Как получить UID телефона Android в NFC
- 19. Android Reader RSS
- 20. NFC на Android-приложении
- 21. NFC теги и данные NFC-формата Android
- 22. android nfc mime types
- 23. Android NFC Sharing
- 24. Как эмулировать nfc-тэг на телефоне android
- 25. Android Reader с нуля
- 26. Как использовать Buffered Reader в Java
- 27. Как интегрировать Foxit PDF Reader в Android?
- 28. Получение телефона Android, обнаруженного устройством чтения/записи NFC (Basic NFC)
- 29. Android NFC Метки
- 30. Двойной идентификатор NFC NFC
Добро пожаловать на переполнение стека! Хотя ссылка, которую вы предоставили, может ответить на вопрос, лучше всего поместить основные части вашего решения прямо в ответ, если страница в ссылке исчезнет в будущем. – Kmeixner
Я добавил к реализации. – smory
спас мой день. @smory tyvm! – TGIO