×
Namespaces

Variants
Actions
(Difference between revisions)

Connection state aware applications for Maemo 5 with Qt Mobility

From Nokia Developer Wiki
Jump to: navigation, search
divanov (Talk | contribs)
(Introduction)
divanov (Talk | contribs)
Line 28: Line 28:
  
 
# Input
 
# Input
HEADERS += netmanager.h
+
HEADERS += networkapplication.h netmanager.h
SOURCES += main.cpp netmanager.cpp
+
SOURCES += main.cpp networkapplication.cpp netmanager.cpp
 
</code>
 
</code>
  
 
A very basic main.cpp
 
A very basic main.cpp
 
<code cpp>
 
<code cpp>
#include <QApplication>
+
#include "networkapplication.h"
 
+
 
#include "netmanager.h"
 
#include "netmanager.h"
  
 
int main(int argc, char *argv[])
 
int main(int argc, char *argv[])
 
{
 
{
     QApplication a(argc, argv);
+
     NetworkApplication a(argc, argv);
  
 
     NetManager netManager;
 
     NetManager netManager;
Line 49: Line 48:
 
</code>
 
</code>
  
NetManager header file:
+
NetworkApplication header file:
 
<code cpp>
 
<code cpp>
#ifndef NET_MANAGER_H
+
#ifndef NETWORK_APPLICATION_H
#define NET_MANAGER_H
+
#define NETWORK_APPLICATION_H
  
#include <QNetworkAccessManager>
+
#include <QApplication>
#include <QNetworkReply>
+
#include <QLabel>
+
#include <QPushButton>
+
#include <QWidget>
+
 
#include <QNetworkConfigurationManager>
 
#include <QNetworkConfigurationManager>
 
#include <QNetworkSession>
 
#include <QNetworkSession>
 
using namespace QtMobility;
 
using namespace QtMobility;
  
class NetManager : public QWidget
+
class NetworkApplication : public QApplication
 
{
 
{
 
     Q_OBJECT
 
     Q_OBJECT
  
 
public:
 
public:
     NetManager(QWidget *parent=0);
+
     NetworkApplication(int &argc, char **argv);
  
 
private slots:
 
private slots:
 
     void started();
 
     void started();
 
     void onlineStateChanged(bool isOnline);
 
     void onlineStateChanged(bool isOnline);
    void clicked(bool checked = false);
 
    void finished(QNetworkReply* reply);
 
  
 
private:
 
private:
    QPushButton *button;
 
    QLabel *label;
 
    QNetworkAccessManager *nam;
 
 
     QNetworkConfigurationManager *configManager;
 
     QNetworkConfigurationManager *configManager;
 
     QNetworkSession *session;
 
     QNetworkSession *session;
 
};
 
};
  
#endif //NET_MANAGER_H
+
#endif //NETWORK_APPLICATION_H
 
</code>
 
</code>
  
Implementation of NetManager
 
 
<code cpp>
 
<code cpp>
#include <QDebug>
 
#include <QVBoxLayout>
 
 
#include <QMessageBox>
 
#include <QMessageBox>
#include <QCoreApplication>
 
 
#include <QTimer>
 
#include <QTimer>
 
#include <QNetworkConfiguration>
 
#include <QNetworkConfiguration>
  
#include "netmanager.h"
+
#include "networkapplication.h"
  
NetManager::NetManager(QWidget *parent)
+
NetworkApplication::NetworkApplication(int &argc, char **argv) :
     : QWidget(parent), nam(0), session(0)
+
     QApplication(argc, argv), session(0)
 
{
 
{
    QVBoxLayout *layout = new QVBoxLayout;
 
    button = new QPushButton("Get page");
 
    connect(button, SIGNAL(clicked(bool)), this, SLOT(clicked(bool)));
 
    layout->addWidget(button);
 
    label = new QLabel("");
 
    layout->addWidget(label);
 
    setLayout(layout);
 
 
 
     configManager = new QNetworkConfigurationManager(this);
 
     configManager = new QNetworkConfigurationManager(this);
 
     QTimer::singleShot(0, this, SLOT(started()));
 
     QTimer::singleShot(0, this, SLOT(started()));
Line 117: Line 95:
  
 
<code cpp>
 
<code cpp>
void NetManager::started()
+
void NetworkApplication::started()
 
{
 
{
 
     QCoreApplication::processEvents();
 
     QCoreApplication::processEvents();
Line 132: Line 110:
 
{
 
{
 
     if (!isOnline) {
 
     if (!isOnline) {
         QMessageBox::StandardButton reply = QMessageBox::question(this,
+
         QMessageBox::StandardButton reply = QMessageBox::question(0,
 
             "Connection",
 
             "Connection",
 
             "This application requires connection to the Internet. "
 
             "This application requires connection to the Internet. "
Line 156: Line 134:
 
In case connection is not available user is proposed to quit application or choose a valid connection.
 
In case connection is not available user is proposed to quit application or choose a valid connection.
  
The following code is used to initiate network request and process a network reply.
+
NetManager header file:
 
<code cpp>
 
<code cpp>
 +
#ifndef NET_MANAGER_H
 +
#define NET_MANAGER_H
 +
 +
#include <QNetworkAccessManager>
 +
#include <QNetworkReply>
 +
#include <QLabel>
 +
#include <QPushButton>
 +
 +
class NetManager : public QWidget
 +
{
 +
    Q_OBJECT
 +
 +
public:
 +
    NetManager(QWidget *parent=0);
 +
 +
private slots:
 +
    void clicked(bool checked = false);
 +
    void finished(QNetworkReply* reply);
 +
 +
private:
 +
    QPushButton *button;
 +
    QLabel *label;
 +
    QNetworkAccessManager *nam;
 +
};
 +
 +
#endif //NET_MANAGER_H
 +
</code>
 +
 +
Implementation of NetManager, which is used to initiate network request and process a network reply.
 +
<code cpp>
 +
#include <QDebug>
 +
#include <QVBoxLayout>
 +
 +
#include "netmanager.h"
 +
 +
NetManager::NetManager(QWidget *parent)
 +
    : QWidget(parent), nam(0)
 +
{
 +
    QVBoxLayout *layout = new QVBoxLayout;
 +
    button = new QPushButton("Get page");
 +
    connect(button, SIGNAL(clicked(bool)), this, SLOT(clicked(bool)));
 +
    layout->addWidget(button);
 +
    label = new QLabel("");
 +
    layout->addWidget(label);
 +
    setLayout(layout);
 +
}
 +
 
void NetManager::clicked(bool checked)
 
void NetManager::clicked(bool checked)
 
{
 
{

Revision as of 14:33, 13 July 2010


Introduction

Currently, at the moment Maemo 5 Select connection dialog appears on every attempt to connect to the network. User decisions are not remembered thus application easily may become unusable. There are bugs filed to Qt on this issues http://bugreports.qt.nokia.com/browse/QTBUG-10343 http://bugreports.qt.nokia.com/browse/QTBUG-10503

Before Qt 4.7 is released Qt applications have to workaround this bug.

Solution

One of the possible solutions is to use Qt Mobility Bearer Management. It's available in PR 1.2 release.

Project file should enable mobility

TEMPLATE = app
TARGET =
DEPENDPATH += .
INCLUDEPATH += .
 
QT += network
 
CONFIG += mobility
MOBILITY = bearer
 
# Input
HEADERS += networkapplication.h netmanager.h
SOURCES += main.cpp networkapplication.cpp netmanager.cpp

A very basic main.cpp

#include "networkapplication.h"
#include "netmanager.h"
 
int main(int argc, char *argv[])
{
NetworkApplication a(argc, argv);
 
NetManager netManager;
netManager.show();
 
return a.exec();
}

NetworkApplication header file:

#ifndef NETWORK_APPLICATION_H
#define NETWORK_APPLICATION_H
 
#include <QApplication>
#include <QNetworkConfigurationManager>
#include <QNetworkSession>
using namespace QtMobility;
 
class NetworkApplication : public QApplication
{
Q_OBJECT
 
public:
NetworkApplication(int &argc, char **argv);
 
private slots:
void started();
void onlineStateChanged(bool isOnline);
 
private:
QNetworkConfigurationManager *configManager;
QNetworkSession *session;
};
 
#endif //NETWORK_APPLICATION_H
#include <QMessageBox>
#include <QTimer>
#include <QNetworkConfiguration>
 
#include "networkapplication.h"
 
NetworkApplication::NetworkApplication(int &argc, char **argv) :
QApplication(argc, argv), session(0)
{
configManager = new QNetworkConfigurationManager(this);
QTimer::singleShot(0, this, SLOT(started()));
}

QTimer::singleShot is used to make sure that slot started() is invoked when event loop is running.

void NetworkApplication::started()
{
QCoreApplication::processEvents();
onlineStateChanged(configManager->isOnline());
connect(configManager, SIGNAL(onlineStateChanged(bool)),
this, SLOT(onlineStateChanged(bool)));
}

We have to wait until all events are processed, to make sure that QNetworkConfiguationManager is properly initialised, then we test for connection.

void NetManager::onlineStateChanged(bool isOnline)
{
if (!isOnline) {
QMessageBox::StandardButton reply = QMessageBox::question(0,
"Connection",
"This application requires connection to the Internet. "
"Do you want to connect or quit an application?",
QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
if (reply == QMessageBox::No)
QCoreApplication::quit();
else {
if(session) {
delete session;
session = 0;
}
QNetworkConfiguration config = configManager->defaultConfiguration();
session = new QNetworkSession(config, this);
session->open();
session->waitForOpened(-1);
onlineStateChanged(configManager->isOnline());
}
}
}

In case connection is not available user is proposed to quit application or choose a valid connection.

NetManager header file:

#ifndef NET_MANAGER_H
#define NET_MANAGER_H
 
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QLabel>
#include <QPushButton>
 
class NetManager : public QWidget
{
Q_OBJECT
 
public:
NetManager(QWidget *parent=0);
 
private slots:
void clicked(bool checked = false);
void finished(QNetworkReply* reply);
 
private:
QPushButton *button;
QLabel *label;
QNetworkAccessManager *nam;
};
 
#endif //NET_MANAGER_H

Implementation of NetManager, which is used to initiate network request and process a network reply.

#include <QDebug>
#include <QVBoxLayout>
 
#include "netmanager.h"
 
NetManager::NetManager(QWidget *parent)
: QWidget(parent), nam(0)
{
QVBoxLayout *layout = new QVBoxLayout;
button = new QPushButton("Get page");
connect(button, SIGNAL(clicked(bool)), this, SLOT(clicked(bool)));
layout->addWidget(button);
label = new QLabel("");
layout->addWidget(label);
setLayout(layout);
}
 
void NetManager::clicked(bool checked)
{
Q_UNUSED(checked);
 
if(!nam) {
nam = new QNetworkAccessManager(this);
connect(nam, SIGNAL(finished(QNetworkReply*)),
this, SLOT(finished(QNetworkReply*)));
}
nam->get(QNetworkRequest(QUrl("http://tycho.usno.navy.mil/cgi-bin/timer.pl")));
}
 
void NetManager::finished(QNetworkReply *reply)
{
if (reply->error() == QNetworkReply::NoError) {
label->setText(reply->readAll());
} else {
label->setText(reply->errorString());
}
 
reply->deleteLater();
}
173 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×