实现设备插拔监控【QtAdb 已正式可用,将开始功能添加与细节优化】

This commit is contained in:
Lappland 2022-08-17 23:14:50 +08:00
parent 33fd2a69e9
commit 169b175ec4
12 changed files with 378 additions and 36 deletions

View File

@ -1,4 +1,5 @@
QT += core gui
QT += serialport
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
@ -38,6 +39,7 @@ SOURCES += \
textexplainer.cpp \
threads/adbthread.cpp \
threads/thread_createpage.cpp \
usb_listener.cpp \
welcomepage.cpp
HEADERS += \
@ -70,6 +72,7 @@ HEADERS += \
textexplainer.h \
threads/adbthread.h \
threads/thread_createpage.h \
usb_listener.h \
welcomepage.h
FORMS += \

View File

@ -5,9 +5,8 @@ about::about(QWidget *parent) :
basePage(parent),
ui(new Ui::about)
{
ui->setupUi(this);
self_castrate();
ui->setupUi(this);
QGraphicsDropShadowEffect *shadowEffect_btn_website = new QGraphicsDropShadowEffect(this);
shadowEffect_btn_website->setOffset(0,0);
@ -58,6 +57,9 @@ about::about(QWidget *parent) :
ui->btn_money->hide();
ui->btn_money_3->hide();
ui->btn_money_4->hide();
this->setStyleSheet("QToolTip{border:1px solid #BDBDBD; background-color: #ffffff; color:rgba(117, 117, 117, 0.9);font-family: MiSans Medium; font-size:12px;border-radius:4px;}");
}
about::~about()

View File

@ -112,7 +112,7 @@ QPushButton:pressed{background-color:rgba(255,255,255,0.6);}</string>
</font>
</property>
<property name="text">
<string>测试版本beta-v0.5</string>
<string>测试版本beta-v0.6</string>
</property>
</widget>
</item>

View File

@ -15,14 +15,14 @@ void animationWidget::playLoadAnimation()
qDebug() << "wgtHeight = " << wgtHeight;
if(parent->width() <= 600)
{
animation->setEndValue(QRect(301, 117, 600,wgtHeight));
animation->setEndValue(QRect(301, 117 - 6, 600,wgtHeight));
}
else
{
animation->setEndValue(QRect(301, 117, parent->width(),wgtHeight));
animation->setEndValue(QRect(301, 117 - 6, parent->width(),wgtHeight));
}
//animation->setStartValue(QPoint(301 + 50,117));
animation->setStartValue(QRect(301 + 50, 117, parent->width()-50,wgtHeight));
animation->setStartValue(QRect(301 + 50, 117 - 6, parent->width()-50,wgtHeight));
animation->setEasingCurve(QEasingCurve::OutQuart);
@ -38,14 +38,14 @@ void animationWidget::playLoadAnimation(int h)
//qDebug() << "wgtHeight = " << wgtHeight;
if(parent->width() <= 600)
{
animation->setEndValue(QRect(301, 117, 600,h));
animation->setEndValue(QRect(301, 117 - 6, 600,h));
}
else
{
animation->setEndValue(QRect(301, 117, parent->width(),h));
animation->setEndValue(QRect(301, 117 - 6, parent->width(),h));
}
//animation->setStartValue(QPoint(301 + 50,117));
animation->setStartValue(QRect(301 + 50, 117, parent->width()-50,h));
animation->setStartValue(QRect(301 + 50, 117 - 6, parent->width()-50,h));
animation->setEasingCurve(QEasingCurve::OutQuart);

View File

@ -36,11 +36,22 @@ MainWindow::MainWindow(QWidget *parent)
addIndexItems(); //设置左侧目录
setStyles(); //设置样式
/*初始化对象*/
process = new adbProcess();
explainer = new textExplainer();
maker = new pageMaker();
listener = new usb_listener();
//connect(listener, SIGNAL(DevicePlugIn()),this,SLOT(DevicePlugIn()));
//connect(listener, SIGNAL(DevicePlugOut()),this,SLOT(DevicePlugOut()));
connect(listener, SIGNAL(DeviceChanged()),this,SLOT(refreshDevListLater()));
connect(this, SIGNAL(adbDeviceChanged()),this,SLOT(DeviceChanged()));
qApp->installNativeEventFilter(listener);
//listener->EmitMySignal();
this->setAttribute(Qt::WA_NativeWindow);
/*启动监听*/
/*启动ADB将延长页面创建时间在此期间显示启动界面显示了个勾八*/
process->run("adb server");
@ -75,9 +86,97 @@ void MainWindow::initEnvironmentPATH() //方法:设置环境变
void MainWindow::refreshDevList() //方法:刷新设备列表
{
ui->comboBox->clear();
//ui->comboBox->clear();
/*DEBUG*/
bool changed = false;
qDebug() << "******************一次调用*********************";
qDebug() << "refreshDevList devList is empty? " << devList.isEmpty() << QTime::currentTime();
qDebug() << "devList.size()" << devList.size();
for(int i = 0; i < devList.size();i++)
{
qDebug() << "devList[" << i << "] is :" << devList[i].addr;
}
/*DEBUG_END*/
qDebug() << "shit 0";
bool devList_is_empty = devList.isEmpty();
QList<device> tmpList;
/*给tmpList赋值*/
if(!devList_is_empty)
{
for(int i = 0; i < devList.size();i++)
{
qDebug() << "shit 3.1";
device dev;
dev.device_debug = devList[i].device_debug;
dev.device_product = devList[i].device_product;
dev.addr = devList[i].addr;
dev.model = devList[i].model;
dev.state = devList[i].state;
dev.transport_id = devList[i].transport_id;
tmpList.append(dev);
}
}
qDebug() << "tmpList.size()" << tmpList.size();
//ui->comboBox->clear();
devList.clear(); //清空设备列表
devList = explainer->getDevList_windows(process->run("adb devices -l")); //重新赋值
qDebug() << "devList after explain:" << devList.isEmpty();
/*
qDebug() << "shit 1";
for(int i = 0; i < tmpList.size();i++)
{
qDebug() << "shit 2";
qDebug() << "tmpList[" << i << "] is :" << devList[i].addr;
}
for(int i = 0; i < devList.size();i++)
{
qDebug() << "shit 3";
qDebug() << "devList new[" << i << "] is :" << devList[i].addr;
}
qDebug() << "shit finish";*/
/*判断列表内容是否变化,若变化则发送 adbDeviceChanged 信号*/
if(!devList_is_empty)
{
if(devList.size() == tmpList.size())
{
for(int i = 0; i < devList.size() && i < tmpList.size() ; i++)
{
if(devList[i].addr != tmpList[i].addr)
{
emit adbDeviceChanged();
changed = true;
break;
}
}
}
else
{
emit adbDeviceChanged();
changed = true;
}
}
else if(!devList.isEmpty() && tmpList.isEmpty())
{
emit adbDeviceChanged();
changed = true;
}
else if(devList.isEmpty() && !tmpList.isEmpty())
{
emit adbDeviceChanged();
changed = true;
}
else
{
qDebug() << "else:" << devList.isEmpty() << tmpList.isEmpty() << devList_is_empty;
}
QList<int> off; //未响应设备索引
@ -89,6 +188,7 @@ void MainWindow::refreshDevList() //方法:刷新设备列
{
QString devItem = devList[i].state + " " + explainer->get_words_after(devList[i].model, ":") + " " + devList[i].addr;
l.append(devItem);
qDebug() << "l[" << i << "] = " << l[i];
if(devList[i].state == "[未响应]")
{
off.append(i);
@ -99,7 +199,21 @@ void MainWindow::refreshDevList() //方法:刷新设备列
}
}
if(changed)
{
qDebug() <<"changed so clear";
ui->comboBox->clear();
ui->comboBox->addItems(l);
}
if(!liangYi)
{
qDebug() <<"liangYi so clear";
ui->comboBox->clear();
ui->comboBox->addItems(l);
}
liangYi = false;
for(int i = 0; i < off.count();i++)
{
@ -115,6 +229,10 @@ void MainWindow::refreshDevList() //方法:刷新设备列
{
current_device = 0;
}
liangYi = false;
qDebug() << "******************一次调用结束*********************";
}
void MainWindow::on_refreshButton_clicked() //槽:按下刷新按钮
@ -130,7 +248,6 @@ void MainWindow::on_refreshButton_clicked() //槽:按下刷新按钮
}*/
initBasePage(6);
qDebug() <<"8";
}
void MainWindow::setCurrentDevice(int index) //槽:改变所选设备
@ -540,3 +657,60 @@ void MainWindow::on_cmdBtn_clicked()
batProcess.start(batPath);
batProcess.waitForFinished();
}
void MainWindow::DevicePlugIn()
{
qDebug() << "DevicePlugIn";
}
void MainWindow::DevicePlugOut()
{
qDebug() << "DevicePlugout";
}
void MainWindow::DeviceChanged()
{
if(firstBoot == true)
{
firstBoot = false;
}
else
{
QMessageBox::StandardButton result=QMessageBox::warning(NULL, "检测到USB热插拔","您可能插入或拔出了一台ADB设备\n"
"将对设备列表进行刷新\n"
"(⚠️这会中断当前正在执行的任务)");
//msgBox->setStyleSheet("background-color:rgba(255,255,255,1);border:0px; border-radius:0px;");
//QMessageBox::StandardButton result=QMessageBox::warning(this, "Title","text");
//qDebug() << "result =" << result;
if(result)
{
//这里要delete adbprocess
on_refreshButton_clicked();
}
else
{
}
//qDebug() << "DeviceChanged";
}
}
void MainWindow::slot_refreshDevList()
{
//qDebug() << "slot_refreshDevList";
liangYi = true;
refreshDevList();
}
void MainWindow::refreshDevListLater()
{
//qDebug() << ">>>>>>>>>>>>>>>>>>>>>>refreshDevListLater";
QTimer *timer = new QTimer();
connect(timer, SIGNAL(timeout()), this, SLOT(slot_refreshDevList()));
timer->setSingleShot(true);
timer->start(1000);
//timer->deleteLater();
}

View File

@ -1,5 +1,9 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
/*
#define 布尔 bool
#define 为 =
#define 真 true*/
#include <QMainWindow>
#include <QDir>
@ -14,8 +18,8 @@
#include "indexlistitem.h"
#include "basepage.h"
#include "pagemaker.h"
#include "threads/thread_createpage.h"
#include "about.h"
#include "usb_listener.h"
#include <QCoreApplication>
#include <QStringList>
@ -33,6 +37,7 @@ class MainWindow : public QMainWindow
{
Q_OBJECT
signals:
void adbDeviceChanged();
public:
MainWindow(QWidget *parent = nullptr);
@ -49,7 +54,6 @@ public:
QLineEdit * le_port;
QLineEdit * le_code;
int current_device;
QList<device> devList;
indexListItem listItems[10];
@ -81,12 +85,28 @@ private:
void addIndexItems();
void setStyles();
bool taiChi = true;
bool taiChi = true; //界面锁定定时器
bool liangYi = false; //判断刷新按钮槽函数是被谁调用falseclick调用 true 自行connect
bool bagua = true; //忘了是干啥的了
//布尔 太极 为 真;
bool firstBoot = true;
QTimer *taiChiTimer;
QTimer *baguaTimer;
basePage * currentPage;
animationWidget * tmpPage;
about * WCMPage2;
usb_listener *listener;
public slots:
void DevicePlugIn();
void DevicePlugOut();
void DeviceChanged();
void slot_refreshDevList();
void refreshDevListLater();
};
#endif // MAINWINDOW_H

View File

@ -21,6 +21,7 @@ sp_installer::sp_installer(QWidget *parent) :
QGraphicsDropShadowEffect *shadowEffect_back_to_basePage = new QGraphicsDropShadowEffect(this);
QGraphicsDropShadowEffect *shadowEffect_refreshBtn = new QGraphicsDropShadowEffect(this);
QGraphicsDropShadowEffect *shadowEffect_selectBtn = new QGraphicsDropShadowEffect(this);
QGraphicsDropShadowEffect *shadowEffect_tips = new QGraphicsDropShadowEffect(this);
shadowEffect_runBtn->setOffset(0,0);
shadowEffect_runBtn->setColor(Qt::gray);
@ -42,11 +43,16 @@ sp_installer::sp_installer(QWidget *parent) :
shadowEffect_selectBtn->setColor(Qt::gray);
shadowEffect_selectBtn->setBlurRadius(5);
shadowEffect_tips->setOffset(0,0);
shadowEffect_tips->setColor(Qt::green);
shadowEffect_tips->setBlurRadius(5);
ui->back_to_basePage->setGraphicsEffect(shadowEffect_back_to_basePage);
ui->runBtn->setGraphicsEffect(shadowEffect_runBtn);
ui->showOutputBtn->setGraphicsEffect(shadowEffect_showOutputBtn);
ui->refreshBtn->setGraphicsEffect(shadowEffect_refreshBtn);
ui->selectBtn->setGraphicsEffect(shadowEffect_selectBtn);
ui->tips->setGraphicsEffect(shadowEffect_tips);
/*
QGraphicsDropShadowEffect *shadowEffect_widget = new QGraphicsDropShadowEffect();

View File

@ -203,6 +203,37 @@ QProgressBar:chunk{
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="tips">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>30</height>
</size>
</property>
<property name="font">
<font>
<family>MiSans Medium</family>
<pointsize>12</pointsize>
</font>
</property>
<property name="styleSheet">
<string notr="true">background-color:rgba(255,255,255,0.6);border-radius:4px;border:0px;</string>
</property>
<property name="text">
<string>执行时切勿插拔设备</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>

View File

@ -89,7 +89,7 @@ void sp_recovery::on_runBtn_clicked()
{
//qDebug() << "enter runBtn slot";
ui->progressBar->setVisible(true);
ui->output->setText("正在刷入,请在设备端查看进度");
ui->output->setText("正在刷入,请在设备端查看进度,切勿插拔设备");
QString command;
@ -110,21 +110,6 @@ void sp_recovery::on_runBtn_clicked()
this->setDisabled(true);
/*
pageListItemStruct *productModel = initStruct(devInfo);
productModel->item->setText_title("设备型号 | DeviceModel");
productModel->item->setPic(":/ico/image/ico/profile-line.svg");
productModel->thread->initThread("adb shell getprop ro.product.model", dev);
QEventLoop::connect(productModel->thread,SIGNAL(signal_output(QString)),productModel->item,SLOT(slot_setText_profile(QString)));
//QEventLoop::connect(devInfo,SIGNAL(animationEnd()),productModel->item,SLOT(slot_setStyles()));
productModel->thread->start();
devInfo->addItemsToList(productModel->item);
//qDebug() << "item is in thread" << productModel->item->thread();*/
//qDebug() << "command: " << command;
//qDebug() << "running";
//process->run_contains_empty(command, dev);
zipPath.clear();
labelDisplay.clear();

91
QtAdb/usb_listener.cpp Normal file
View File

@ -0,0 +1,91 @@
#include "usb_listener.h"
#include <QApplication>
#include <QDebug>
#include <typeinfo>
bool usb_listener::nativeEventFilter(const QByteArray &eventType, void *message, long long *result)
{
MSG* msg = reinterpret_cast<MSG*>(message);
//qDebug() << "msg = " << msg;
unsigned int msgType = msg->message;
//qDebug() << "msgType = " << msgType;
//qDebug() << WM_DEVICECHANGE;
if(msgType == WM_DEVICECHANGE) {
emit DeviceChangeCbk();
//qDebug() << "msgType = " << msgType;
//qDebug() << "WM_DEVICECHANGE = " << WM_DEVICECHANGE;
qDebug() << "wParam = " << msg->wParam;
//qDebug() << "lParam = " << msg->lParam;
//qDebug() << "WM_DEVICECHANGE = " << WM_DEVICECHANGE;
qDebug() << "DBT_DEVICEARRIVAL = " << DBT_DEVICEARRIVAL;
qDebug() << "DBT_DEVICEREMOVECOMPLETE = " << DBT_DEVICEREMOVECOMPLETE;
/*
PDEV_BROADCAST_HDR lpdb = PDEV_BROADCAST_HDR(msg->lParam);
qDebug() << "lpdb = " << msg->lParam;
PDEV_BROADCAST_DEVICEINTERFACE pDevInf = PDEV_BROADCAST_DEVICEINTERFACE(lpdb);
qDebug() << "pDevInf = " << pDevInf;
qDebug() << "pDevInf->dbcc_name = " << pDevInf->dbcc_name;
QString device_name = "插入设备(name)"+QString::fromWCharArray(pDevInf->dbcc_name,int(pDevInf->dbcc_size)).toUtf8();
qDebug() << device_name;*/
//bool dbg = msg->lParam == WM_DEVICECHANGE;
//qDebug() << "msg->lParam == WM_DEVICECHANGE = " <<dbg;*/
//qDebug() << "WM_DEVICECHANGE type = " << typeid(WM_DEVICECHANGE).name();
//qDebug() << "msg->lParam type = " << typeid(msg->lParam).name();
//if(msg->wParam == DBT_DEVICEARRIVAL)
emit DeviceChanged();
//if(msg->lParam == WM_DEVICECHANGE)
if(msg->wParam == DBT_DEVICEARRIVAL)
{
qDebug("usb in");
emit DevicePlugIn(); //触发信号
}
if(msg->wParam == DBT_DEVICEREMOVECOMPLETE)
{
qDebug("usb out");
emit DevicePlugOut(); //触发信号
}
}
return QWidget::nativeEvent(eventType, message, result);
}
void usb_listener::EmitMySignal()
{
emit DevicePlugIn();
}
/*
bool usb_listener::nativeEvent(const QByteArray &eventType, void *message, long long *result)
{
MSG* msg = reinterpret_cast<MSG*>(message);//第一层解算
qDebug() << "msg = " << msg;
UINT msgType = msg->message;
if(msgType==WM_DEVICECHANGE)
{
PDEV_BROADCAST_HDR lpdb = PDEV_BROADCAST_HDR(msg->lParam);//第二层解算
switch (msg->wParam) {
case DBT_DEVICEARRIVAL:
if(lpdb->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
{
PDEV_BROADCAST_DEVICEINTERFACE pDevInf = PDEV_BROADCAST_DEVICEINTERFACE(lpdb);
QString device_name = "插入设备(name)"+QString::fromWCharArray(pDevInf->dbcc_name,int(pDevInf->dbcc_size)).toUtf8();
qDebug()<< device_name;
}
break;
case DBT_DEVICEREMOVECOMPLETE:
if(lpdb->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
{
PDEV_BROADCAST_DEVICEINTERFACE pDevInf = PDEV_BROADCAST_DEVICEINTERFACE(lpdb);
QString device_name = "移除设备(name)"+QString::fromWCharArray(pDevInf->dbcc_name,int(pDevInf->dbcc_size)).toUtf8();
qDebug()<< device_name;
}
break;
}
}
return false;
}
*/

27
QtAdb/usb_listener.h Normal file
View File

@ -0,0 +1,27 @@
#ifndef USB_LISTENER_H
#define USB_LISTENER_H
#include <QWidget>
#include <windows.h>
#include <QAbstractNativeEventFilter>
#include <dbt.h>
class usb_listener:public QWidget, public QAbstractNativeEventFilter
{
Q_OBJECT
public:
void EmitMySignal();
protected:
bool nativeEventFilter(const QByteArray &eventType, void *message, long long *result);
//bool nativeEvent(const QByteArray &eventType, void *message, long long *result);
signals:
void DeviceChangeCbk();
void DeviceChanged();
void DevicePlugIn();
void DevicePlugOut();
};
#endif // USB_LISTENER_H

View File

@ -2,7 +2,9 @@
QtAdb 是一个基于 [Qt](https://www.qt.io/) 的 Android 工具集合。
> QtAdb 仍处于开发中,暂未正式发布,但您仍可以下载体验版本。
> ~~QtAdb 仍处于开发中,暂未正式发布,但您仍可以下载体验版本。~~
>
> QtAdb 已于 2022/8/17 发布第一个正式可用的版本 beta-v0.6 ,将进入功能添加与细节优化阶段。
## 🧑‍💻开发目的
@ -24,7 +26,7 @@ Android 系统的可玩性在 adb 的加成下变得更加的丰富,由此涌
- ~~不仅支持 adb 命令,还集成了一定数量的 **Fastboot** 命令,方便刷机等操作。~~*暂未实现*
- 提供命令模板,使用者可直接复制命令并自行执行。
- 支持多种状态显示及使用开机、Recovery、Fastboot 及 adb sideload.
- 支持多种状态显示及使用开机、Recovery、~~Fastboot~~及 adb sideload.
## 🛠️功能
@ -89,9 +91,10 @@ Android 系统的可玩性在 adb 的加成下变得更加的丰富,由此涌
- 跨平台
- 完善网站
- 文件管理(~~都连上电脑了,为什么不直接用电脑的文件管理~~
- 设备插拔检测
- ~~设备插拔检测~~
- 集成scrcpy
- 视觉反馈
- ~~视觉反馈~~
- ~~页面切换加载进度条~~
- ~~页面切换动画效果~~
- ~~安装应用进度条~~