qt android 地图api,Android上的低级USB API,NDK级别,可在Qt Android上使用

我需要在Android上与HID设备进行交互.问题是我正在使用Qt Android,而我没有使用Java UsbManager类.

是否有任何C lib我可以链接以便与Android上的HID设备进行通信而无需使用Java API?

我发现了这个:

这似乎是定义HID通信的标头,但我找不到关联的lib.有任何想法吗?

提前致谢

解决方法:

我找到了一种方法.在我的情况下,我正在为一个设备开发一个控制面板,我需要它在每个设备上工作而不需要设备生根.

基本上我正在使用UsbManager来查找和获取设备.然后我打开设备并从UsbDeviceConnection调用getFileDescriptor()方法.然后我将此int传递给本机代码端.从那里我可以使用任何类型的请求轻松地从设备获取数据,而无需将数据从本机代码传递到Java,反之亦然,通过JNI,这是缓慢而缓慢的死亡工作.

最棘手的部分实际上是进行需要特殊格式的ioctl调用.

这些代码的一部分已经在libusb源代码中得到了很好的例证,因为它是它们实现对linux内核的libsub调用的方式.

如果有人知道更好的解决方案,请告诉我.

USBManager挂钩的Android活动代码:

public class MyActivity extends QtActivity

{

private static MyActivity m_instance;

private UsbAccessory accessory;

private String TAG = "TAG";

private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";

private PendingIntent mPermissionIntent;

private UsbManager manager;

private UsbDeviceConnection connection;

private HashMap connectedDevices;

public MyActivity()

{

m_instance = this;

connectedDevices = new HashMap();

}

@Override

public void onCreate(Bundle savedInstanceState)

{

super.onCreate(savedInstanceState);

manager = (UsbManager) getSystemService(Context.USB_SERVICE);

registerReceiver(usbManagerBroadcastReceiver, new IntentFilter(UsbManager.ACTION_USB_DEVICE_ATTACHED));

registerReceiver(usbManagerBroadcastReceiver, new IntentFilter(UsbManager.ACTION_USB_DEVICE_DETACHED));

registerReceiver(usbManagerBroadcastReceiver, new IntentFilter(ACTION_USB_PERMISSION));

mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);

final Handler handler = new Handler();

handler.postDelayed(new Runnable()

{

@Override

public void run()

{

checkForDevices();

}

}, 1000);

}

@Override

public void onDestroy()

{

super.onDestroy();

}

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data)

{

super.onActivityResult(requestCode, resultCode, data);

}

private static native void notifyDeviceAttached(int fd);

private static native void notifyDeviceDetached(int fd);

private final BroadcastReceiver usbManagerBroadcastReceiver = new BroadcastReceiver()

{

public void onReceive(Context context, Intent intent)

{

try

{

String action = intent.getAction();

Log.d(TAG, "INTENT ACTION: " + action);

if (ACTION_USB_PERMISSION.equals(action))

{

Log.d(TAG, "onUsbPermission");

synchronized (this)

{

UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);

if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false))

{

if(device != null)

{

int fd = connectToDevice(device);

Log.d(TAG,"device file descriptor: " + fd);

notifyDeviceAttached(fd);

}

}

else

{

Log.d(TAG, "permission denied for device " + device);

}

}

}

if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action))

{

Log.d(TAG, "onDeviceConnected");

synchronized(this)

{

UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);

if (device != null)

{

manager.requestPermission(device, mPermissionIntent);

}

}

}

if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action))

{

Log.d(TAG, "onDeviceDisconnected");

synchronized(this)

{

UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);

int fd = connectedDevices.get(device.getDeviceId());

Log.d(TAG, "device: " + device.getDeviceId() + " disconnected. fd: " + fd);

notifyDeviceDetached(fd);

connectedDevices.remove(device.getDeviceId());

}

}

}

catch(Exception e)

{

Log.d(TAG, "Exception: " + e);

}

}

};

private int connectToDevice(UsbDevice device)

{

connection = manager.openDevice(device);

// if we make this, kernel driver will be disconnected

connection.claimInterface(device.getInterface(0), true);

Log.d(TAG, "inserting device with id: " + device.getDeviceId() + " and file descriptor: " + connection.getFileDescriptor());

connectedDevices.put(device.getDeviceId(), connection.getFileDescriptor());

return connection.getFileDescriptor();

}

private void checkForDevices()

{

HashMap deviceList = manager.getDeviceList();

Iterator deviceIterator = deviceList.values().iterator();

while(deviceIterator.hasNext())

{

UsbDevice device = deviceIterator.next();

if (device.getVendorId()==VID && device.getProductId()==PID)

{

Log.d(TAG, "Found a device: " + device);

manager.requestPermission(device, mPermissionIntent);

}

}

}

}

当连接或断开具有所希望的VID和PID的设备时,调用本机调用notifyDeviceAttached(int fd)和notifyDeviceDetached(int fd)将设备的文件描述符发送到本机端.在我的例子中,我实例化一个类型为Device的类.此时设备已经打开,您可以开始调用它.在Linux中,您可以像libusb一样进行ioctl调用.您可以在下面看到getFeature和setFeature的代码.如果您还需要其他任何东西,可以查看libusb源代码.

C本机端代码:

#include

#include

#include

#include

#include

static inline uint16_t cpu_to_le16(const uint16_t x)

{

union

{

uint8_t b8[2];

uint16_t b16;

} _tmp;

_tmp.b8[1] = (uint8_t) (x >> 8);

_tmp.b8[0] = (uint8_t) (x & 0xff);

return _tmp.b16;

}

struct usbdevfs_ctrltransfer

{

unsigned char bRequestType;

unsigned char bRequest;

unsigned short wValue;

unsigned short wIndex;

unsigned short wLength;

unsigned int timeout;

void *data;

};

Device::Device(int fileDescriptor, QObject *parent) :

fd(fileDescriptor)

{

}

int Device::getFeature(unsigned char reportId, unsigned char *buffer, int length)

{

struct usbdevfs_ctrltransfer data;

data.bRequestType = (0x01 << 5)|0x01|0x80;

data.bRequest = 0x01;

data.wValue = cpu_to_le16((3 << 8) | reportId);

data.wIndex = cpu_to_le16(0);

data.wLength = cpu_to_le16(length);

data.data = buffer;

data.timeout = 1000;

int res = ioctl(fd, _IOWR('U', 0, struct usbdevfs_ctrltransfer), &data);

if (res<0)

{

qDebug() << "error: " << strerror(errno);

}

return res;

}

int Device::setFeature(unsigned char reportId, unsigned char *buffer, int length)

{

struct usbdevfs_ctrltransfer data;

data.bRequestType = (0x01 << 5)|0x01|0x00;

data.bRequest = 0x09;

data.wValue = cpu_to_le16((3 << 8) | reportId);

data.wIndex = cpu_to_le16(0);

data.wLength = cpu_to_le16(length);

data.data = buffer;

data.timeout = 1000;

int res = ioctl(fd, _IOWR('U', 0, struct usbdevfs_ctrltransfer), &data);

if (res<0)

{

qDebug() << "error: " << strerror(errno);

}

return res;

}

问候,

努诺桑托斯

标签:android,android-ndk,qt,usb,hid

来源: https://codeday.me/bug/20190728/1563388.html

本文档是QT中文版本 内容详尽,下面是片段 信号 void activated ( int id ) 静态公有成员 QKeySequence shortcutKey ( const QString & str ) QString keyToString ( QKeySequence k ) (obsolete) QKeySequence stringToKey ( const QString & s ) (obsolete) 保护成员 virtual bool eventFilter ( QObject * o, QEvent * e ) -------------------------------------------------------------------------------- 详细描述 QAccel类用来处理键盘的加速键和快捷键。 键盘加速键是在某个组合键按下的时候出发一个动作,加速键可以处理窗口部件和它子部件里所有的键盘动作所以它不会被键盘焦点所影响。 在大多数情况下,你不需要直接使用这个类。使用QAction类建立的具有加速键的动作可以同时在菜单和工具栏里使用。如果你的兴趣只是在菜单里使用QMenuData::insertItem()或者QMenuData::setAccel()建立只作用在菜单里的加速键。那么许多窗口部件可以自动的生成加速键,比如QButton、QGroupBox、QLabel(使用QLabel::setBuddy())、QMenuBar和QTabBar。实例: QPushButton p( "&Exit", parent ); // 自动使用快捷键ALT+Key_E QPopupMenu *fileMenu = new fileMenu( parent ); fileMenu->insertItem( "Undo", parent, SLOT(undo()), CTRL+Key_Z ); QAccel包括一个加速键的列表,这个列表里的项目可以使用insertItem()、removeItem()、clear()、key()和findKey()。 每一个加速键项目是由一个标示符和 QKeySequence组成。一个单独的键组是由一个键盘码组合上改变符形成的(SHIFT,CTRL,ALT 或者 UNICODE_ACCEL)。例如,CTRL + Key_p可以作为文本打印的快捷键。这个键的键盘码在qnamespace.h里列出。还有,使用UNICODE_ACCEL可以使字符以统一码(unicode)的形式表现出来。例如 UNICODE_ACCEL + 'A' 所给出的加速键和Key_A是一样的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值