Russian Qt Forum
Ноябрь 23, 2024, 01:02 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Qt Android NFC  (Прочитано 9934 раз)
iLya84a
Гость
« : Июль 03, 2014, 13:11 »

Сделал QML-приложение для чтения тэгов Mifare Classic 1K.
USB-считыватель - ACR122T USB Token NFC Reader
Пришлось решить массу интересных вопросов:
  • низкоуровневая работа со считывателем
  • защита приложения от сворачивания
  • работа с нативной клавиатурой
С удовольствием отвечу на вопросы.

« Последнее редактирование: Июль 03, 2014, 13:16 от iLya84a » Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #1 : Июль 03, 2014, 14:39 »

Цитировать
низкоуровневая работа со считывателем

Вот здесь можно поподробнее? Каким образом делали это? Улыбающийся
Записан

ArchLinux x86_64 / Win10 64 bit
iLya84a
Гость
« Ответ #2 : Июль 04, 2014, 09:18 »

Цитировать
низкоуровневая работа со считывателем

Вот здесь можно поподробнее? Каким образом делали это? Улыбающийся
Я использовал ACR122T USB Token NFC Reader. С другими моделями, думаю, всё аналогично.
0. Идем на страницу, выбираем закладку Downloads.
1. Скачиваем ACS-Unified-LIB-Android-111-P.zip
2. Внутри находим справку \ACS-Unified-LIB-Android-111-P\acssmc\doc\index.html
3. После нескольких таблиц на этой странице видим заголовок Package com.acs.smartcard Description. Здесь начинается то, что нам нужно:
  • Opening Reader
  • Closing Reader
  • Resetting Card
  • Setting Protocol
  • Transmitting APDU
4. В этом же архиве находится готовый тестовый проект \ACS-Unified-LIB-Android-111-P\ReaderTest. Мне он здорово помог разобраться во всех базовых операциях из пункта 3.
5. Теперь нам нужно разобраться с APDU командами. Для этого скачиваем API Driver Manual of ACR122T NFC Contactless Smart Card Reader.
6. Мне нужно было считывать данные из памяти карт Mifare Classic 1K. Для этого мне пригодились пункты:
  • 5.1 Load Authentication Keys
  • 5.2 Authentication
  • 5.3 Read Binary Blocks
Вот и всё!
Код привести, к сожалению, не могу - проект коммерческий. Но еще подробнее, если где-то возникнут сложности, расскажу.
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #3 : Июль 06, 2014, 12:46 »

Эмм.. так код с "низкоуровневой" работой с ридером был на JAVA?
Записан

ArchLinux x86_64 / Win10 64 bit
iLya84a
Гость
« Ответ #4 : Июль 07, 2014, 09:38 »

Эмм.. так код с "низкоуровневой" работой с ридером был на JAVA?
Согласен, слова "низкоуровневый" и JAVA в одном предложении выглядят странно  Улыбающийся
Но вот пример команды аутентификации из пункта 5.2:
Код:
int slotNum = 0;
byte block = 0x3E;
byte[] command = { (byte)0xFF, (byte)0x86, 0x00, 0x00, 0x05, 0x01, 0x00, block , 0x60, 0x00 };
byte[] response = new byte[2];
reader.transmit(slotNum, command, command.length, response, response.length);
Тут без листания мануала никак не обойтись  Улыбающийся
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #5 : Июль 07, 2014, 09:44 »

Это да, поэтому числовые константы и заменяют текстовыми. Улыбающийся
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #6 : Июль 07, 2014, 10:31 »

Цитировать
Согласен, слова "низкоуровневый" и JAVA в одном предложении выглядят странно 

Не, я не про то. Я про то, что раз приложение написано на Qt, значит использовался C++, поэтому: каким образом использовались JAVA классы с C++ коде? Оборачивались враппером через JNI и дергались из C++?
Записан

ArchLinux x86_64 / Win10 64 bit
iLya84a
Гость
« Ответ #7 : Июль 07, 2014, 11:38 »

каким образом использовались JAVA классы с C++ коде? Оборачивались враппером через JNI и дергались из C++?
Да. Немного подергать JAVA со стороны C++ мне тоже пришлось. В этом случае всё просто.
Я немного распишу как "испускать" сигналы со стороны JAVA, и обрабатывать их в QML.
Для работы со считывателем мне потребовались 3 сигнала:
Код:
class NfcReader : public QObject
{
    Q_OBJECT

public:
    ...
    static NfcReader *getInstance() { return s_instance; }
    ...
signals:
    void tagDetected(); // Поднесли карту к считывателю
    void tagReaded(int number); // Номер шкафчика прочитан
    void tagDisconnected(); // Карту убрали
};
Нам нужно описать нативные методы:
Код:
void tagDetected(JNIEnv */*env*/, jobject /*thiz*/)
{
    NfcReader::getInstance()->tagDetected();
}

void tagReaded(JNIEnv */*env*/, jobject /*thiz*/, int number)
{
    NfcReader::getInstance()->tagReaded(number);
}

void tagDisconnected(JNIEnv */*env*/, jobject /*thiz*/)
{
    NfcReader::getInstance()->tagDisconnected();
}

static JNINativeMethod methods[] = {
    {"tagDetected", "()V", (void *)tagDetected},
    {"tagReaded", "(I)V", (void *)tagReaded},
    {"tagDisconnected", "()V", (void *)tagDisconnected}
};
И зарегистрировать их:
Код:
// This method is called immediately after the module is load
JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void */*reserved*/)
{
    JNIEnv *env;
    if (vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6) != JNI_OK) {
        qCritical() << "Can't get the enviroument";
        return -1;
    }
    ...
    // Register our native methods
    if (env->RegisterNatives(s_classID, methods, sizeof(methods) / sizeof(methods[0])) < 0) {
        qCritical() << "RegisterNatives failed";
        return -1;
    }
}
На JAVA-стороне эти методы описаны следующим образом:
Код:
    public static native void tagDetected();
    public static native void tagReaded(int number);
    public static native void tagDisconnected();
Вызываем эти методы в коде на JAVA - обрабатываем сигналы на стороне QML Улыбающийся
Записан
ilnile
Гость
« Ответ #8 : Сентябрь 04, 2014, 20:14 »

Подскажите, вы пишите что работали с методами на JAVA.

Не могли бы вы рассказать как это работает?
Вы добавляете в проект на QML/c++ классы на JAVA, а потом к ним обращаетесь?

И еще очень интересно как работать с нативной клавиатурой.
Сегодня весь день искал как из qml поймать event появления клавиатуру.
Буду вам очень признателен.
Записан
iLya84a
Гость
« Ответ #9 : Сентябрь 08, 2014, 09:43 »

ilnile, вот как это работает:
  • Создаю в проекте папку android-sources
  • В *.pro файле добавляю строку ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android-sources
  • В папку /android-sources/libs подкладываю необходимые *.jar файлы
  • В папку android-sources/src/org/qtproject/qt5/android/bindings кладу *.java файлы
  • Далее использую JNI. Об этом было подробнее в посте выше.
Deploying an Application on Android
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.058 секунд. Запросов: 23.