Появилось время - опять мучаю планшет.
Удалось чуть продвинуться.
Во-первых, файлы с java классами из модуля qtserialport (
https://codereview.qt-project.org/#/c/84338/) надо включать в проект приложения, в противном случае они не подцепятся, при этом не будет ни единого ворнинга, а программа будет выдавать странные результаты на любой вызов из UsbDeviceJNI.java.
Далее, в файле qserialport_android.cpp строчка:
static char V_jniClassName[] {"org/qtproject/qtserialport/android/usbdevice/UsbDeviceJNI"};
категорически нуждается в операторе присваивания:
static char V_jniClassName[] = {"org/qtproject/qtserialport/android/usbdevice/UsbDeviceJNI"};
Ибо без него также не выдается ни единого ворнинга, но функции из UsbDeviceJNI.java вызываться по понятным причинам не будут.
Но далее самое интересное:
////////////////////////////////////////////////////////////////////////////////////////////////
//
// Constructor. Only used once to create the initial instance for the static functions.
//
////////////////////////////////////////////////////////////////////////////////////////////////
public UsbDeviceJNI()
{
m_instance = this;
m_openedDevices = new HashMap<Integer, UsbSerialDriver>();
m_userData = new HashMap<Integer, Integer>();
m_ioManager = new HashMap<Integer, UsbIoManager>();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Find all current devices that match the device filter described in the androidmanifest.xml and the
// device_filter.xml
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
private static boolean getCurrentDevices()
{
if (m_instance == null){
Log.i("getCD", "null");
return false;
}
if (m_manager == null)
m_manager = (UsbManager)m_instance.getSystemService(Context.USB_SERVICE);
if (m_devices != null)
m_devices.clear();
m_devices = UsbSerialProber.findAllDevices(m_manager);
return true;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// List all available devices that are not already open. It returns the serial port info
// in a : separated string array. Each string entry consists of the following:
//
// DeviceName:Company:ProductId:VendorId
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
public static String[] availableDevicesInfo()
{
// GET THE LIST OF CURRENT DEVICES
if (!getCurrentDevices())
return null;
// MAKE SURE WE HAVE ENTRIES
if (m_devices.size() <= 0)
return null;
if (m_openedDevices == null)
return null;
int countL = 0;
int iL;
// CHECK FOR ALREADY OPENED DEVICES AND DON"T INCLUDE THEM IN THE COUNT
for (iL=0; iL<m_devices.size(); iL++)
{
if (m_openedDevices.get(m_devices.get(iL).getDevice().getDeviceId()) != null)
{
countL++;
break;
}
}
if (m_devices.size() - countL <= 0)
return null;
String[] listL = new String[m_devices.size() - countL];
UsbSerialDriver driverL;
String tempL;
// GET THE DATA ON THE INDIVIDUAL DEVICES SKIPPING THE ONES THAT ARE ALREADY OPEN
countL = 0;
for (iL=0; iL<m_devices.size(); iL++)
{
driverL = m_devices.get(iL);
if (m_openedDevices.get(driverL.getDevice().getDeviceId()) == null)
{
UsbDevice deviceL = driverL.getDevice();
tempL = deviceL.getDeviceName() + ":";
if (driverL instanceof FtdiSerialDriver)
tempL = tempL + "FTDI:";
else if (driverL instanceof CdcAcmSerialDriver)
tempL = tempL + "Cdc Acm:";
else if (driverL instanceof Cp2102SerialDriver)
tempL = tempL + "Cp2102:";
else if (driverL instanceof ProlificSerialDriver)
tempL = tempL + "Prolific:";
else
tempL = tempL + "Unknown:";
tempL = tempL + Integer.toString(deviceL.getProductId()) + ":";
tempL = tempL + Integer.toString(deviceL.getVendorId()) + ":";
listL[countL] = tempL;
countL++;
}
}
return listL;
}
Метод QList<QSerialPortInfo> QSerialPortInfo::availablePortsByFiltersOfDevices() вызывает метод UsbDeviceJNI::availableDevicesInfo(), который объявлен как public static. Однако, во внутренностях этого метода выполняется проверка условия m_instance == null, чуть выше видно, что m_instance присваивается значение this в конструкторе. На кой хрен вообще делать такую проверку в статическом методе? В общем, потихоньку вспоминаю java.
Тем не менее некоторый прогресс на лицо, после добавления в манифест пары строк (по инструкции отсюда
https://github.com/mik3y/usb-serial-for-android/blob/master/README.md) при подключении FTDI преобразователя приложение предлагает открыть устройство. Вчера не сразу сообразил как правильно подцепить манифест к проекту (QtCreator -> Проекты -> Конфигурация установки), чтобы его при сборке не заменяло на дефолтный.
Был бы признателен за советы по отладке сего безобразия и моральную поддержку