Introduction
Quite often, with the implementation of any logic in the application, there is a need to trigger some function after a certain period of time. The most obvious example of this need is the timer application. For example,
cooktimer or
Saildoro .
As mentioned in one of the
previous articles, you can use the standard
Timer
element or its C ++ equivalent,
QTimer
, to add a timer to an application on Sailfish OS. However, by default, the operation of these timers is suspended for long periods of time due to the fact that the device can go into "sleep". The developers of the two applications mentioned above have just encountered this problem.
This article presents a standard for the system, but unfortunately an undocumented way to handle this behavior of Sailfish OS.
starting point
As a starting point, an “abstract” application for Sailfish OS will be considered, in which some functionality needs to be triggered after a long period of time. At the same time, the timer operation is described not in the QML code, but in a class in C ++:
Header class TimerWrapper : public QObject { Q_OBJECT public:
Source #include "timerwrapper.h" TimerWrapper::TimerWrapper(QObject *parent) : QObject(parent) { _timer = new QTimer(this);
An object of this class must be registered in QML:
main.cpp #ifdef QT_QML_DEBUG #include <QtQuick> #endif #include <QGuiApplication> #include <QQmlContext> #include <QQuickView> #include <QScopedPointer> #include <sailfishapp.h> #include "timerwrapper.h" int main(int argc, char *argv[]) { // QScopedPointer<QGuiApplication> application(SailfishApp::application(argc, argv)); // QScopedPointer<QQuickView> view(SailfishApp::createView()); // QScopedPointer<TimerWrapper> timer(new TimerWrapper(view.data())); // view->rootContext()->setContextProperty("timer", timer.data()); // QML- view->setSource(SailfishApp::pathTo("qml/harbour-application.qml")); // view->show(); // return application->exec(); }
With this approach, as mentioned in the introduction, there can be a suspension of the timer operation over long time intervals.
Decision
The first option to prevent the timer from falling asleep
was proposed in the developer mailing list and
caught on in the cooktimer application. Here it is proposed to start an additional timer, which calls the D-Bus method
req_display_cancel_blanking_pause
once a minute to prevent the device from falling asleep. It is obvious that such an implementation is not optimal and cumbersome. First, when using this approach, the device battery discharges faster. Secondly, a minor code appears in the project that can be avoided.
And you can avoid the use of secondary code because Sailfish OS already provides two possible solutions to the problem posed: the
ScreenBlank
and
KeepAlive
elements.
Using the first approach involves a constantly active screen. This is a working but straightforward approach that actively consumes the device’s battery. Thus, it can be used, but in a limited circle of situations.
import QtQuick 2.0
In turn, the use of the
KeepAlive
element is a more democratic approach. It consumes less battery power, as it does not keep the device screen constantly on, and at the same time, either does not allow the device to go into a deep sleep, or “wakes” it at a certain point in time, thanks to which the timer will continue to work and long periods of time.
import QtQuick 2.0
It is worth noting that, in principle, the work of all three of these methods is a regular appeal to the system methods of D-Bus, which was discussed in a
previous article.
Conclusion
As part of this short note, three possible ways to prevent the device from deep falling asleep are described. It can be concluded that for background tasks (for example, a timer) it is optimal to use the
KeepAlive
element, and if there is a need to constantly display information to the user, then
ScreenBlank
.