MyTetra Share
Делитесь знаниями!
Как заставить не выключаться экран в Qt/QML приложениях под Android
Время создания: 09.03.2018 14:21
Текстовые метки: qt, qml, android, андроид, экран, выключение, энергосбережение, power management
Раздел: Компьютер - Программирование - Язык C++ (Си++) - Библиотека Qt - QML
Запись: xintrea/mytetra_syncro/master/base/1520594509adnozss8d6/text.html на raw.github.com

Есть довольно простая задача: для некоторых видов Android-приложений необходимо сделать так, чтобы экран был все время включен. Вокруг этого вопроса много непонятностей, зависящих от версии Qt, версии Android, фазы луны. Но есть одно более-менее работающее решение.


Решение описано здесь:


https://stackoverflow.com/questions/34179653/how-do-i-prevent-an-android-device-from-going-to-sleep-from-qt-application


Решение заключается в том, что необходимо заблокировать объект PowerManager.WakeLock. Только тогда экран приложения не будет гаснуть. Никакие другие настройки не помогут этого надежно добиться.


Кратко, что нужно сделать:


1. Создать шаблон настройки Android-приложения в Qt


2. В файле android/AndroidManifest.xml в элементе activity добавить атрибут android:keepScreenOn (это придется сделать вне QtCreator, так как в QtCreator 4.4.1 такая настройка не предусмотрена):


android:keepScreenOn="true"


3. Открыть в QtCreator файл android/AndroidManifest.xml в дереве проекта в разделе "Другие файлы" (откроется форма настройки). В разделе "Разрешения" в выпадающем списке надо добавить разрешение:


android.permission.WAKE_LOCK


В результате чего в файле AndroidManifest.xml появится элемент uses-permission внутри элемента manifest:


<uses-permission android:name="android.permission.WAKE_LOCK"/>


Если эту строку прописать просто в AndroidManifest.xml, то она будет удалена после любого редактирования AndroidManifest.xml в QtCreator. Поэтому данную настройку надо делать имеенно в QtCreator.


4. Нужно сделать класс KeepAwakeHelper, исходник кторого дан на StackOwerflow. Исходник этот, видимо, собирается под Windows, а чтобы он собирался и в Linux он должен быть таким:


Файл KeepAwakeHelper.h


#ifndef KEEPAWAKEHELPER_H

#define KEEPAWAKEHELPER_H


#include <QAndroidJniObject>


class KeepAwakeHelper

{

public:

KeepAwakeHelper();

virtual ~KeepAwakeHelper();


private:

QAndroidJniObject m_wakeLock;

};


#endif // KEEPAWAKEHELPER_H


Файл KeepAwakeHelper.cpp


#include <QDebug>

#include "KeepAwakeHelper.h"


KeepAwakeHelper::KeepAwakeHelper()

{

QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;");

if ( activity.isValid() )

{

QAndroidJniObject serviceName = QAndroidJniObject::getStaticObjectField<jstring>("android/content/Context","POWER_SERVICE");

if ( serviceName.isValid() )

{

QAndroidJniObject powerMgr = activity.callObjectMethod("getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;",serviceName.object<jobject>());

if ( powerMgr.isValid() )

{

jint levelAndFlags = QAndroidJniObject::getStaticField<jint>("android/os/PowerManager","SCREEN_DIM_WAKE_LOCK");


QAndroidJniObject tag = QAndroidJniObject::fromString( "My Tag" );


m_wakeLock = powerMgr.callObjectMethod("newWakeLock", "(ILjava/lang/String;)Landroid/os/PowerManager$WakeLock;", levelAndFlags,tag.object<jstring>());

}

}

}


if ( m_wakeLock.isValid() )

{

m_wakeLock.callMethod<void>("acquire", "()V");

qDebug() << "Locked device, can't go to standby anymore";

}

else

{

Q_ASSERT(false);

}

}



KeepAwakeHelper::~KeepAwakeHelper()

{

if ( m_wakeLock.isValid() )

{

m_wakeLock.callMethod<void>("release", "()V");

qDebug() << "Unlocked device, can now go to standby";

}

}


5. Для сборки нужно в *.pro файл добавить опцию:


QT += androidextras


6. Использовать данный объект можно просто путем его создания. То есть, его можно создать как поле какого-нибудь класса, который существует все время работы программы.


class Core : public QObject

{

...

protected:


KeepAwakeHelper helper;

}


Больше ничего делать с этим обхектом не нужно. Причем, нет ограничений на момент создания объекта: он может создаваться и до загрузки QML-движка, например как свойство переопределенного класса объекта приложения.


7. Очистить проект, запустить qmake, собрать проект.



Возможные проблемы


При использовании этого кода экран будет оставаться включенным, но будет понижаться яркость после прошествия некоторого времени. Для борьбы с этим можно попробовать изменить значение levelAndFlags. Возможные значения энергосбережения:


  • SCREEN_DIM_WAKE_LOCK - отключать подсветку клавиш мобильной клавиатуры (для устройств с клавиатурой) и снижать яркость экрана
  • SCREEN_BRIGHT_WAKE_LOCK - отключать подсветку клавиш мобильной клавиатуры, но не снижать яркость экрана
  • FULL_WAKE_LOCK - не отключать подсветку клавиатуры, не снижать яркость экрана




Так же в этом разделе:
 
MyTetra Share v.0.59
Яндекс индекс цитирования