(续) 最近喜欢闲逛github,去上面看看关于Qt方面的一些开源资料和项目,看到好多优秀的Qt开源项目,特别在最新的移动开发方面的项目,比如Qt for iOS,Qt for Android等。
今天来说下Qt for PC,这个pc desktop项目很有借鉴意义,至少人家都是开源出来,不像国内某某等躲躲藏藏,呵呵,吐槽下国内IT行业
下面我们说下这个开源项目的主要功能就是一个Android手机的pc管理文件管理工具,类似国内四分天下的手机助手,360,腾讯 百度91 豌豆荚等手机助手,不过功能肯定没有他们"强大" ,呵呵 你懂的,那四家使用Android调试工具 adb都是自己将源码修改后使用的,功能更加强大,在此不再表述。
今天来说下Qt for PC,这个pc desktop项目很有借鉴意义,至少人家都是开源出来,不像国内某某等躲躲藏藏,呵呵,吐槽下国内IT行业
下面我们说下这个开源项目的主要功能就是一个Android手机的pc管理文件管理工具,类似国内四分天下的手机助手,360,腾讯 百度91 豌豆荚等手机助手,不过功能肯定没有他们"强大" ,呵呵 你懂的,那四家使用Android调试工具 adb都是自己将源码修改后使用的,功能更加强大,在此不再表述。
作者原话 Android File Manager using Android Debug Bridge and based on Qt http://qtadb.wordpress.com 这个链接需要翻才可以查阅,翻得懂就好
我们看下入口main函数
#include <QtGui/QApplication> #include "./classes/application.h" #include "./dialogs/mainwindow.h" //////////////////////////////////////// #include <QtDebug> #include <QFile> #include <QTextStream> void myMessageHandler(QtMsgType type, const char *msg) { QStringList args = qApp->arguments(); QString txt; switch (type) { case QtDebugMsg: txt = QString("Debug: %1").arg(msg); break; case QtWarningMsg: txt = QString("Warning: %1").arg(msg); break; case QtCriticalMsg: txt = QString("Critical: %1").arg(msg); break; case QtFatalMsg: txt = QString("Fatal: %1").arg(msg); abort(); } if (args.contains("--debug")) { QFile outFile("debug.log"); outFile.open(QIODevice::WriteOnly | QIODevice::Append); QTextStream ts(&outFile); txt.remove(QChar( 0xa ),Qt::CaseInsensitive); txt.remove(QChar( 0xd ),Qt::CaseInsensitive); ts << txt << endl; } } int main(int argc, char *argv[]) { QCoreApplication::setOrganizationName("Bracia"); QCoreApplication::setApplicationName("QtADB"); QCoreApplication::setApplicationVersion("0.8.1"); QCoreApplication::setOrganizationDomain("http://qtadb.com"); Application a(argc, argv); qInstallMsgHandler(myMessageHandler); a.loadTranslations(":/lang"); a.loadTranslations(qApp->applicationDirPath()); a.setQuitOnLastWindowClosed(true); qDebug()<<"app version: "<<QCoreApplication::applicationVersion(); #ifdef Q_WS_WIN switch(QSysInfo::windowsVersion()) { case QSysInfo::WV_XP:qDebug()<<"system: Windows XP "<<QProcessEnvironment::systemEnvironment().value("PROCESSOR_ARCHITECTURE"); break; case QSysInfo::WV_VISTA:qDebug()<<"system: Windows Vista "<<QProcessEnvironment::systemEnvironment().value("PROCESSOR_ARCHITECTURE"); break; case QSysInfo::WV_WINDOWS7:qDebug()<<"system: Windows 7 "<<QProcessEnvironment::systemEnvironment().value("PROCESSOR_ARCHITECTURE"); break; default: qDebug()<<"system: "<<QSysInfo::windowsVersion()<<" "<<QProcessEnvironment::systemEnvironment().value("PROCESSOR_ARCHITECTURE"); } #endif // qDebug()<<"system: "<<QSysInfo::windowsVersion(); // qDebug()<<"bits: "<<QSysInfo::WordSize; QSettings settings; QString sdk; sdk = settings.value("sdkPath").toString(); QString locale = QLocale::system().name().left(2); QString lang = settings.value("Language", locale).toString(); bool langSet = false; if (!Application::availableLanguagesRes().contains(lang)) lang = "en"; foreach (QString avail, Application::availableLanguagesRes()) { if (avail == lang) { langSet = true; Application::setLanguage(lang, "res"); } } foreach (QString avail, Application::availableLanguagesDir()) { if ((avail == lang) && (langSet == false)) { Application::setLanguage(lang, "dir"); } } bool sdkOk = false; do{ QString tmp; if (sdk.isEmpty()) { QDir checkSDK(QDir::currentPath()); QFileInfoList list=checkSDK.entryInfoList(); while(list.length()>0) { tmp = list.takeFirst().fileName(); if (tmp.contains("adb")) { sdk = QDir::currentPath(); sdk.append("/"); sdkOk=true; break; } } } if (sdk.isEmpty()) { sdk=QFileDialog::getExistingDirectory(NULL,QObject::tr("Choose path to dir with adb and aapt binaries"),"/"); if (!sdk.isEmpty()) sdk.append("/"); } if (!sdk.isEmpty()) { QDir checkSDK(sdk); QFileInfoList list=checkSDK.entryInfoList(); while(list.length()>0) { tmp = list.takeFirst().fileName(); if (tmp.contains("adb")) { sdkOk=true; break; } } } if (!sdkOk) { sdk.clear(); QMessageBox *msgBox = new QMessageBox(QMessageBox::Critical, QObject::tr("error"), QObject::tr("there is no adb binary in here!")); QPushButton *choosePathMsg = msgBox->addButton(QObject::tr("Choose path"), QMessageBox::AcceptRole); QPushButton *closeMsg = msgBox->addButton(QObject::tr("Close"), QMessageBox::RejectRole); msgBox->exec(); if (msgBox->clickedButton() == choosePathMsg) { continue; } else { break; } delete closeMsg; delete choosePathMsg; delete msgBox; } else break; }while(true); if (sdkOk){ settings.setValue("sdkPath", sdk); QProcess proces; // adbd cannot run as root in production builds proces.setProcessChannelMode(QProcess::MergedChannels); proces.start("\"" + sdk + "\"adb version"); proces.waitForFinished(-1); QString tmp = proces.readAll(); qDebug()<<"adb version - "<<tmp; if (proces.exitCode() != 0) { qDebug()<<"adb error - "<<proces.errorString(); QMessageBox *msgBox = new QMessageBox(QMessageBox::Critical, QObject::tr("error"), QObject::tr("It seems that adb is not working properly"), QMessageBox::Ok); msgBox->exec(); delete msgBox; return 1; } // adbd cannot run as root in production builds proces.setProcessChannelMode(QProcess::MergedChannels); proces.start("\"" + sdk + "\"adb root"); proces.waitForFinished(-1); tmp = proces.readAll(); qDebug()<<"adb root - "<<tmp; if (tmp.contains("adbd cannot run as root in production builds") && !settings.value("disableProductionBuildsMessage",false).toBool()) { QMessageBox *msgBox2 = new QMessageBox(QMessageBox::Critical, QObject::tr("error"), QObject::tr("adbd cannot run as root in production builds so You can't do anything with /system partition. Run anyway?\n(press save to run QtADB and disable this message)"), QMessageBox::Yes | QMessageBox::No | QMessageBox::Save); int button = msgBox2->exec(); if ( button == QMessageBox::No) { delete msgBox2; return 0; } if ( button == QMessageBox::Save) { settings.setValue("disableProductionBuildsMessage",true); } } QStringList args = qApp->arguments(); if (args.count() > 1) { if (args.at(1).endsWith(".apk")) { App *app = NULL; app = FileWidget::getAppInfo(args.at(1)); appInfo *appInfoDialog = new appInfo(app); return appInfoDialog->exec(); } if (args.at(1) == "-install") { QList<App> appList; App *app = NULL; for (int i = 2; i < args.count(); i++) { if (args.at(i).endsWith(".apk")) { QString fileName = args.at(i); app = FileWidget::getAppInfo(fileName); if (app != NULL) appList.append(*app); } } appDialog *appDialogInstall = new appDialog(appList, appDialog::Install, appDialog::None); return appDialogInstall->exec(); } else if (args.at(1) == "-logcat") { LogcatDialog *logcat = new LogcatDialog; return logcat->exec(); } } MainWindow w; w.show(); return a.exec(); } else{ return 0; } }简单说下该文件中所作的一些事情
myMessageHandler(QtMsgType type, const char *msg)是负责记录项目的调试日志
保存到一个log文件里面
main函数里面设置了应用名称等,再者检测了windows平台的版本,然后再读取了一些注册表信息,想找到用户是否安装了Android的sdk开发包,如果用户安装了Android SDk,则必然有Android调试工具adb,对于adb是否存在做了很多检测功能
另外还做了文件关联的功能,使用main函数的传参,进行apk的安装功能,对此需要对Adb这个工具做详细的了解,才能懂得这个项目意义所在
另外这个项目也是C++与QML混编的一个典型案例,有兴趣的Qter可以好好研究下,如果对现在的adb有不满,可以自行修改和编译adb源码
说到这里就奉上开源代码 Qt Android 管理工具客户端
希望大家可以从中学到不少Qt方面的东西和Android方面的东西
稍微我会继续说叨github上面的Qt开源项目