Android   发布时间:2022-04-28  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了Android上的低级USB API,NDK级别,可在Qt Android上使用大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我需要在 Android上与HID设备进行交互.问题是我正在使用Qt Android,而我没有使用Java UsbManager类.

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

发现了这个:

http://source.android.com/devices/reference/bt__hh_8h_source.html

这似乎是定义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<Integer,Integer> connectedDevices;

    public MyActivity()
    {
        m_instance = this;

        connectedDevices = new HashMap<Integer,Integer>();
    }

    @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,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<String,UsbDevice> deviceList = manager.getDeviceList();
        Iterator<UsbDevice> 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 <sys/ioctl.h>
#include <unistd.h>
#include <errno.h>

#include <QDebug>
#include <QElapsedTimer>

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',struct usbdevfs_ctrltransfer),&data);

    if (res<0)
    {
        qDebug() << "error: " << strerror(errno);
    }

    return res;
}

int Device::setFeature(unsigned char reportId,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,&data);

    if (res<0)
    {
        qDebug() << "error: " << strerror(errno);
    }

    return res;
}

问候,

努诺桑托斯

大佬总结

以上是大佬教程为你收集整理的Android上的低级USB API,NDK级别,可在Qt Android上使用全部内容,希望文章能够帮你解决Android上的低级USB API,NDK级别,可在Qt Android上使用所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。