Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I prevent an Android device from going to sleep from Qt application

Tags:

c++

android

qt

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?

like image 315
jpo38 Avatar asked Dec 09 '15 13:12

jpo38


People also ask

How do I prevent an Android device from going to sleep programmatically?

Using android:keepScreenOn="true" is equivalent to using FLAG_KEEP_SCREEN_ON . You can use whichever approach is best for your app. The advantage of setting the flag programmatically in your activity is that it gives you the option of programmatically clearing the flag later and thereby allowing the screen to turn off.

How to keep screen awake Android?

From the settings page navigate to > About Tablet > Software Information. Then tap the "Build Number" 7 times to enable developer mode. Developers mode is where you'll find the Stay Awake option, toggle to enable.


2 Answers

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.

like image 59
jpo38 Avatar answered Nov 14 '22 23:11

jpo38


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);
    }
}

Source here

I suggest you to read this question for educational purpose.

like image 27
S.M.Mousavi Avatar answered Nov 14 '22 22:11

S.M.Mousavi