Android实时监测USB状态、QT实时监测USB状态

主要是通过系统发广播来获取USB连接的状态,代码很简单

package com.test.socket.usb;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import android.widget.Toast;

public class USBReceiver extends BroadcastReceiver {
    private static final String TAG = "PiCalib usb";
    private final Activity ctx;
    private final String action;
    public static boolean mUsbConnectStatus = false;

    public USBReceiver(Activity mainActivity, String action) {
        this.ctx = mainActivity;
        this.action = action;
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        // 这里可以拿到插入的USB设备对象
        UsbDevice usbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
//registerReceiver()
        if (this.action.equals(intent.getAction())) {
            mUsbConnectStatus = intent.getExtras().getBoolean("connected");
            Toast.makeText(ctx,mUsbConnectStatus+",",Toast.LENGTH_SHORT).show();
        }
    }
}


private final static String ACTION = "android.hardware.usb.action.USB_STATE";
//注册广播!!!注意要activity退出的时候要反注册,我这里偷懒就不写了
    private void registerReceiver() {
        IntentFilter filter = new IntentFilter();
        filter.addAction(ACTION);
        registerReceiver(new USBReceiver(this,ACTION), filter);
        //这里就能返回实时状态
        boolean mUsbConnectstatus = USBReceiver.mUsbConnectStatus;
    }

这里有个小问题,我一直理解的是android.hardware.usb.action.USB_STATE这一条广播是在状态切换的时候才会发送广播,当然状态切换一定会发广播,但是在下列场景下,广播依然会发出来:

1、在APP启动前,USB没有连接,APP启动后,注册动态广播,仍然没有连接USB线,这个广播还是会发送一次USB的状态,此时它是false
2、在APP启动前,USB已经连接,APP启动后,注册动态广播,连接USB线,这个广播依然会发送一次USB的状态,此时它是true

就是说不论有没有切换USB的状态,APP启动,注册了动态广播,它一定会发一条广播给app,也就是说你的APP确实是会拿到状态,我猜测是注册动态广播的时候,系统会给你的APP补发一条广播信息,仅仅是猜测,待后续我去验证

接下来是QT程序中监测USB拔插状态

1、头文件引用

#include <QWidget>
#include <windows.h>
#include <QAbstractNativeEventFilter>
#include <dbt.h>

class ClassA: public QWidget
{
    Q_OBJECT
public:
    explicit ClassA(QWidget *parent = nullptr);
    ~ClassA();    
protected:
    bool nativeEvent(const QByteArray &eventType, void *message, long *result);
};    

2、cpp文件实现

ClassA::ClassA(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::TabFirmwareDownload)
{
    qDebug()<<"ClassA::ClassA+++";
    ui->setupUi(this);
    RegisterHIVDeviceNotification();
    qDebug()<<"TabFirmwareDownload::TabFirmwareDownload ---";
}
//注册消息
bool ClassA::RegisterHIVDeviceNotification()
{
    HDEVNOTIFY hDeviceNotify;
    /*
     *这里注册的设备是  Human Interface Devices (HID) 类
     *GUID_DEVINTERFACE_HID = {4D1E55B2-F16F-11CF-88CB-001111000030}
    */
    GUID  guid_hiv = {0x4D1E55B2, 0xF16F, 0x11CF, 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30};
    DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
    HWND hWnd = (HWND)(this->winId()); //获取当前窗口句柄
    ZeroMemory(&NotificationFilter, sizeof(NotificationFilter));
    NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
    NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
    NotificationFilter.dbcc_classguid = guid_hiv;
    hDeviceNotify = RegisterDeviceNotification (hWnd, &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE);

    qDebug() << "hDeviceNotify: "<<hDeviceNotify ;
    if (NULL == hDeviceNotify)
        return false;
    else
        return true; //注册消息成功
}
bool ClassA::nativeEvent(const QByteArray &eventType, void *message, long *result)
{
    Q_UNUSED(eventType);
    Q_UNUSED(result);
    MSG* msg = reinterpret_cast<MSG*>(message);
//    qDebug() << "msg: "<<msg ;
    int msgType = msg->message;
    if(msgType == WM_DEVICECHANGE){
        switch(msg->wParam){
        case DBT_DEVICEARRIVAL:
            qDebug() << "插入 " ;
            break;
        case DBT_DEVICEREMOVECOMPLETE:
            qDebug() << "拔出 " ;
            break;

        }
    }
    return false;
}

这样就能在运行这个类后,usb拔插实时返回状态了,但是有一个问题,如果你的USB线先连接,再运行程序,这里是无法返回状态的!!!就得想其他办法了,例如程序运行,直接去尝试打开设备节点,

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值