Reputation: 21514
I'm deploying a Qt application on Android and need to prevent the device from going to standby (else, my threads are interrupted and also my BLE connection gets lost).
I found that on SO: How do I prevent an Android device from going to sleep programmatically?
This Java code should be executed:
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "My Tag");
wl.acquire();
// screen and CPU will stay awake during this section
wl.release();
But how to implement that in my Qt application?
Upvotes: 6
Views: 3906
Reputation:
I used the solution of S.M. Mousavi but the app kept crashing. From the same source you have to add some more line of code. Here the complete solution for convenience:
In the .pro file add:
QT += androidextras
ANDROID_PERMISSIONS += android.permission.WAKE_LOCK
I am not sure that the line concerning the permission is really needed.
In your CCP file: add these two includes:
#include <QAndroidJniObject>
#include <QAndroidJniEnvironment>
And where you need:
QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;");
if (activity.isValid()) {
QAndroidJniObject window = activity.callObjectMethod("getWindow", "()Landroid/view/Window;");
if (window.isValid()) {
const int FLAG_KEEP_SCREEN_ON = 128;
window.callMethod<void>("addFlags", "(I)V", FLAG_KEEP_SCREEN_ON);
//Clear any possible pending exceptions.
QAndroidJniEnvironment env;
if (env->ExceptionCheck()){
env->ExceptionClear();
}
}
}
Upvotes: 1
Reputation: 5226
Another solution:
QAndroidJniObject activity = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/android/QtNative", "activity", "()Landroid/app/Activity;");
if (activity.isValid()) {
QAndroidJniObject window = activity.callObjectMethod("getWindow", "()Landroid/view/Window;");
if (window.isValid()) {
const int FLAG_KEEP_SCREEN_ON = 128;
window.callMethod<void>("addFlags", "(I)V", FLAG_KEEP_SCREEN_ON);
}
}
I suggest you to read this question for educational purpose.
Upvotes: 1
Reputation: 21514
QAndroidJniObject helps executing Java code from Qt. Writting it could be hard and it's hard to figure out what's wrong when it does not work....
Here is the solution (encapsulated in a helper class) to lock a PowerManager.WakeLock
object:
LockHelper.h:
#pragma once
#include <QAndroidJniObject>
class KeepAwakeHelper
{
public:
KeepAwakeHelper();
virtual ~KeepAwakeHelper();
private:
QAndroidJniObject m_wakeLock;
};
LockHelper.cpp:
#include "LockHelper.h"
#include <QAndroidJniObject>
#include <QDebug>
#include "jni.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
{
assert( false );
}
}
KeepAwakeHelper::~KeepAwakeHelper()
{
if ( m_wakeLock.isValid() )
{
m_wakeLock.callMethod<void>("release", "()V");
qDebug() << "Unlocked device, can now go to standby";
}
}
Then, simply do:
{
KeepAwakeHelper helper;
// screen and CPU will stay awake during this section
// lock will be released when helper object goes out of scope
}
Note: You need to be sure you have the WAKE_LOCK permission set in your manifest in order to use this code.
Upvotes: 9