Connection state aware applications for Maemo 5 with Qt Mobility
hamishwillee
(Talk | contribs) m (Text replace - "<code cpp>" to "<code cpp-qt>") |
|||
| (15 intermediate revisions by 2 users not shown) | |||
| Line 1: | Line 1: | ||
| − | [[ | + | {{ArticleMetaData <!-- v1.2 --> |
| − | + | |sourcecode= <!-- Link to example source code e.g. [[Media:The Code Example ZIP.zip]] --> | |
| + | |installfile= <!-- Link to installation file (e.g. [[Media:The Installation File.sis]]) --> | ||
| + | |devices= <!-- Devices tested against - e.g. ''devices=Nokia 6131 NFC, Nokia C7-00'') --> | ||
| + | |sdk= <!-- SDK(s) built and tested against (e.g. [http://linktosdkdownload/ Qt SDK 1.1.4]) --> | ||
| + | |platform= <!-- Compatible platforms - e.g. Symbian^1 and later, Qt 4.6 and later --> | ||
| + | |devicecompatability= <!-- Compatible devices e.g.: All* (must have internal GPS) --> | ||
| + | |dependencies= <!-- Any other/external dependencies e.g.: Google Maps Api v1.0 --> | ||
| + | |signing= <!-- Signing requirements - empty or one of: Self-Signed, DevCert, Manufacturer --> | ||
| + | |capabilities= <!-- Capabilities required by the article/code example (e.g. Location, NetworkServices. --> | ||
| + | |keywords= <!-- APIs, classes and methods (e.g. QSystemScreenSaver, QList, CBase --> | ||
| + | |language= <!-- Language category code for non-English topics - e.g. Lang-Chinese --> | ||
| + | |translated-by= <!-- [[User:XXXX]] --> | ||
| + | |translated-from-title= <!-- Title only --> | ||
| + | |translated-from-id= <!-- Id of translated revision --> | ||
| + | |review-by= <!-- After re-review: [[User:username]] --> | ||
| + | |review-timestamp= <!-- After re-review: YYYYMMDD --> | ||
| + | |update-by= <!-- After significant update: [[User:username]]--> | ||
| + | |update-timestamp= <!-- After significant update: YYYYMMDD --> | ||
| + | |creationdate= 20100712 | ||
| + | |author= [[User:Divanov]] | ||
| + | }} | ||
| + | [[Category:Maemo]][[Category:Qt Mobility]] | ||
| + | {{Abstract|This article provides workarounds to the issue that Maemo 5 displays the connection dialog on every attempt to connect to the network. Qt 4.7 should fix these issues, but the code given may still be useful for developers that want to track network connection state changes.}} | ||
== Introduction == | == Introduction == | ||
Currently, at the moment Maemo 5 Select connection dialog appears on every attempt to connect to the network. | 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 | 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-10343 QTBUG-10343] |
| − | http://bugreports.qt.nokia.com/browse/QTBUG-10503 | + | [http://bugreports.qt.nokia.com/browse/QTBUG-10503 QTBUG-10503] |
Before Qt 4.7 is released Qt applications have to workaround this bug. | Before Qt 4.7 is released Qt applications have to workaround this bug. | ||
| Line 32: | Line 54: | ||
MOBILITY = bearer | MOBILITY = bearer | ||
| − | CONFIG += link_pkgconfig | + | unix:!symbian { |
| − | PKGCONFIG += gq-gconf | + | CONFIG += link_pkgconfig |
| + | PKGCONFIG += gq-gconf | ||
| + | } | ||
# Input | # Input | ||
| Line 41: | Line 65: | ||
A very basic main.cpp | A very basic main.cpp | ||
| − | <code cpp> | + | <code cpp-qt> |
#include "networkapplication.h" | #include "networkapplication.h" | ||
#include "netmanager.h" | #include "netmanager.h" | ||
| Line 57: | Line 81: | ||
NetworkApplication header file: | NetworkApplication header file: | ||
| − | <code cpp> | + | <code cpp-qt> |
#ifndef NETWORK_APPLICATION_H | #ifndef NETWORK_APPLICATION_H | ||
#define NETWORK_APPLICATION_H | #define NETWORK_APPLICATION_H | ||
| Line 64: | Line 88: | ||
#include <QNetworkConfigurationManager> | #include <QNetworkConfigurationManager> | ||
#include <QNetworkSession> | #include <QNetworkSession> | ||
| + | #ifdef Q_WS_MAEMO_5 | ||
| + | #include <GConfItem> | ||
| + | #endif | ||
using namespace QtMobility; | using namespace QtMobility; | ||
| Line 75: | Line 102: | ||
private slots: | private slots: | ||
void started(); | void started(); | ||
| − | |||
void onlineStateChanged(bool isOnline); | void onlineStateChanged(bool isOnline); | ||
| + | #ifdef Q_WS_MAEMO_5 | ||
| + | void valueChanged(); | ||
| + | #endif | ||
private: | private: | ||
QNetworkConfigurationManager *configManager; | QNetworkConfigurationManager *configManager; | ||
QNetworkSession *session; | QNetworkSession *session; | ||
| + | #ifdef Q_WS_MAEMO_5 | ||
GConfItem *autoConnect; | GConfItem *autoConnect; | ||
bool autoConnectValue; | bool autoConnectValue; | ||
| + | #endif | ||
}; | }; | ||
| Line 88: | Line 119: | ||
</code> | </code> | ||
| − | <code cpp> | + | <code cpp-qt> |
#include <QMessageBox> | #include <QMessageBox> | ||
#include <QTimer> | #include <QTimer> | ||
| Line 98: | Line 129: | ||
QApplication(argc, argv), session(0) | QApplication(argc, argv), session(0) | ||
{ | { | ||
| + | #ifdef Q_WS_MAEMO_5 | ||
autoConnect = new GConfItem("/system/osso/connectivity/network_type/auto_connect", | autoConnect = new GConfItem("/system/osso/connectivity/network_type/auto_connect", | ||
this); | this); | ||
valueChanged(); | valueChanged(); | ||
connect(autoConnect, SIGNAL(valueChanged()), this, SLOT(valueChanged())); | connect(autoConnect, SIGNAL(valueChanged()), this, SLOT(valueChanged())); | ||
| + | #endif | ||
configManager = new QNetworkConfigurationManager(this); | configManager = new QNetworkConfigurationManager(this); | ||
QTimer::singleShot(0, this, SLOT(started())); | QTimer::singleShot(0, this, SLOT(started())); | ||
| Line 109: | Line 142: | ||
QTimer::singleShot is used to make sure that slot ''started()'' is invoked when event loop is already running. | QTimer::singleShot is used to make sure that slot ''started()'' is invoked when event loop is already running. | ||
| − | <code cpp> | + | <code cpp-qt> |
| + | #ifdef Q_WS_MAEMO_5 | ||
void NetworkApplication::valueChanged() | void NetworkApplication::valueChanged() | ||
{ | { | ||
| − | |||
autoConnectValue = !(autoConnect->value().toString().isEmpty()); | autoConnectValue = !(autoConnect->value().toString().isEmpty()); | ||
} | } | ||
| + | #endif | ||
</code> | </code> | ||
valueChanged slot is used in monitoring Internet Connection settings, when it changes to/from "Always ask". | valueChanged slot is used in monitoring Internet Connection settings, when it changes to/from "Always ask". | ||
| − | <code cpp> | + | <code cpp-qt> |
void NetworkApplication::started() | void NetworkApplication::started() | ||
{ | { | ||
| Line 131: | Line 165: | ||
We have to wait until all events are processed, to make sure that QNetworkConfiguationManager is properly initialised, then we test for connection. | We have to wait until all events are processed, to make sure that QNetworkConfiguationManager is properly initialised, then we test for connection. | ||
| − | <code cpp> | + | <code cpp-qt> |
void NetworkApplication::onlineStateChanged(bool isOnline) | void NetworkApplication::onlineStateChanged(bool isOnline) | ||
{ | { | ||
if (!isOnline) { | if (!isOnline) { | ||
QMessageBox::StandardButton reply; | QMessageBox::StandardButton reply; | ||
| + | #ifdef Q_WS_MAEMO_5 | ||
if (autoConnectValue) | if (autoConnectValue) | ||
reply = QMessageBox::Yes; | reply = QMessageBox::Yes; | ||
else | else | ||
| + | #endif | ||
reply = QMessageBox::question(0, | reply = QMessageBox::question(0, | ||
"Connection", | "Connection", | ||
| Line 155: | Line 191: | ||
session->open(); | session->open(); | ||
session->waitForOpened(-1); | session->waitForOpened(-1); | ||
| − | onlineStateChanged(configManager->isOnline()); | + | if(!autoConnectValue) |
| + | onlineStateChanged(configManager->isOnline()); | ||
} | } | ||
} | } | ||
| Line 164: | Line 201: | ||
NetManager header file: | NetManager header file: | ||
| − | <code cpp> | + | <code cpp-qt> |
#ifndef NET_MANAGER_H | #ifndef NET_MANAGER_H | ||
#define NET_MANAGER_H | #define NET_MANAGER_H | ||
| Line 194: | Line 231: | ||
Implementation of NetManager, which is used to initiate network request and process a network reply. | Implementation of NetManager, which is used to initiate network request and process a network reply. | ||
| − | <code cpp> | + | <code cpp-qt> |
#include <QDebug> | #include <QDebug> | ||
#include <QVBoxLayout> | #include <QVBoxLayout> | ||
| Line 235: | Line 272: | ||
} | } | ||
</code> | </code> | ||
| + | |||
| + | == Package == | ||
| + | |||
| + | There is a [http://repository.maemo.org/extras-devel/pool/fremantle/free/source/b/bearer-qt-sample/ bearer-qt-sample] package available in extas-devel repository. | ||
| + | |||
| + | bearer-qt-sample.install file: | ||
| + | <code> | ||
| + | [install] | ||
| + | catalogues = extras-devel | ||
| + | package = bearer-qt-sample | ||
| + | |||
| + | [extras-devel] | ||
| + | name = Extras-Devel | ||
| + | uri = http://repository.maemo.org/extras-devel/ | ||
| + | dist = fremantle | ||
| + | components = free non-free | ||
| + | </code> [[Category:Code Snippet]][[Category:How To]][[Category:MeeGo Harmattan]] [[Category:Symbian]] | ||
Revision as of 04:23, 11 October 2012
Article Metadata
This article provides workarounds to the issue that Maemo 5 displays the connection dialog on every attempt to connect to the network. Qt 4.7 should fix these issues, but the code given may still be useful for developers that want to track network connection state changes.
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 QTBUG-10343 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. You can install it with a commands
sudo gainroot apt-get update apt-get install libqtm-bearer
in XTerminal on N900 and inside scratchbox (skip sudo command there). Nokia Qt SDK contains it ready for use.
Project file should enable mobility
TEMPLATE = app
TARGET =
DEPENDPATH += .
INCLUDEPATH += .
QT += network
CONFIG += mobility
MOBILITY = bearer
unix:!symbian {
CONFIG += link_pkgconfig
PKGCONFIG += gq-gconf
}
# 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>
#ifdef Q_WS_MAEMO_5
#include <GConfItem>
#endif
using namespace QtMobility;
class NetworkApplication : public QApplication
{
Q_OBJECT
public:
NetworkApplication(int &argc, char **argv);
private slots:
void started();
void onlineStateChanged(bool isOnline);
#ifdef Q_WS_MAEMO_5
void valueChanged();
#endif
private:
QNetworkConfigurationManager *configManager;
QNetworkSession *session;
#ifdef Q_WS_MAEMO_5
GConfItem *autoConnect;
bool autoConnectValue;
#endif
};
#endif //NETWORK_APPLICATION_H
#include <QMessageBox>
#include <QTimer>
#include <QNetworkConfiguration>
#include "networkapplication.h"
NetworkApplication::NetworkApplication(int &argc, char **argv) :
QApplication(argc, argv), session(0)
{
#ifdef Q_WS_MAEMO_5
autoConnect = new GConfItem("/system/osso/connectivity/network_type/auto_connect",
this);
valueChanged();
connect(autoConnect, SIGNAL(valueChanged()), this, SLOT(valueChanged()));
#endif
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 already running.
#ifdef Q_WS_MAEMO_5
void NetworkApplication::valueChanged()
{
autoConnectValue = !(autoConnect->value().toString().isEmpty());
}
#endif
valueChanged slot is used in monitoring Internet Connection settings, when it changes to/from "Always ask".
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 NetworkApplication::onlineStateChanged(bool isOnline)
{
if (!isOnline) {
QMessageBox::StandardButton reply;
#ifdef Q_WS_MAEMO_5
if (autoConnectValue)
reply = QMessageBox::Yes;
else
#endif
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);
if(!autoConnectValue)
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();
}
Package
There is a bearer-qt-sample package available in extas-devel repository.
bearer-qt-sample.install file:
[install]
catalogues = extras-devel
package = bearer-qt-sample
[extras-devel]
name = Extras-Devel
uri = http://repository.maemo.org/extras-devel/
dist = fremantle
components = free non-free

