Android:如何让屏幕进入待机状态并保持接收BLE通知

问题描述 投票:1回答:1

我正在Android上部署Qt应用程序。它连接BLE设备,接收和记录通知。

当Android设备进入待机状态时,我的应用程序停止接收BLE通知(我不再接收QLowEnergyService::characteristicChanged信号),当我退出待机状态时,再次收到通知。

我发现这篇文章:How do I prevent an Android device from going to sleep programmatically?,感谢QAndroidJniObject我可以在我的应用程序中实现锁定(请参阅How do I prevent an Android device from going to sleep from Qt application)。

然而:

  • 如果我使用SCREEN_DIM_WAKE_LOCK,屏幕将不会进入待机状态并继续接收我的通知。
  • 如果我使用PARTIAL_WAKE_LOCK,屏幕进入待机状态,但之后我将不会收到我的通知(好像没有实际创建任何锁定)

我对SCREEN_DIM_WAKE_LOCK不满意,因为:

  • 保持屏幕开启将清空电池
  • 我需要屏幕关闭,因为应用程序整晚都在睡床旁边运行(一夜之间获得用户生理测量)

但是,只保持CPU活着(PARTIAL_WAKE_LOCK应该做什么)是不够的。

我是如何关闭此屏幕并继续接收我的BLE通知的想法?还有其他锁定系统吗? java代码是可以接受的,并且只要它很轻,就可以通过QAndroidJniObject移植到Qt。

java android qt bluetooth-lowenergy
1个回答
1
投票

我的猜测是你正在获取PARTIAL_WAKE_LOCK,但是当屏幕关闭时,你的应用程序会进入“后台运行”,默认情况下,Qt生成的AndroidManifest.xml会禁用后台运行。

打开“AndroidManifest.xml”文件并切换到“XML Source”。向下滚动并找到此部分:

        <!-- Background running -->
        <!-- Warning: changing this value to true may cause unexpected crashes if the
                      application still try to draw after
                      "applicationStateChanged(Qt::ApplicationSuspended)"
                      signal is sent! -->
        <meta-data android:name="android.app.background_running" android:value="true"/>
        <!-- Background running -->

默认情况下,“android.app.background_running”设置为“false”,当屏幕关闭或用户切换到前台运行的不同应用程序时,应用程序执行将暂停。您需要将android.app.background_running设置为“true”,就像我在上面的代码片段中一样。

当您的应用程序在后台运行时,您可能不允许对屏幕进行任何更改,否则会发生意外崩溃。对于我的应用程序,我只显示了一个MainWindow,我似乎可以通过实现这样的applicationStateChanged()槽来避免这个问题:

class MainWindow : public QMainWindow
{
    (...)
    public slots:
        void applicationStateChanged(Qt::ApplicationState state);
}

void MainWindow::applicationStateChanged(Qt::ApplicationState state)
{
    if(state != Qt::ApplicationActive)
    {
        // Don't update GUI if we're not the active application
        ui->centralWidget->setVisible(false);
        qDebug() << "Hiding GUI because not active state: " << state;
    }
    else
    {
        ui->centralWidget->setVisible(true);
        qDebug() << "Showing GUI because active now.";
    }
}

只要用户关闭屏幕或切换到其他前台应用程序,就会自动调用此函数。

根据我的经验,即使进行了上述更改,您的应用程序仍然可以100%保证运行(您只需要更长一段时间)。 Android似乎有自己的想法,它决定有时会杀掉那些没有在前台运行的进程。也许在高端Android设备上的情况会好于我的情况(我拥有的每台Android设备都有不到1GB的内存)。

请勿将其用于生命支持或其他关键任务情况。


从jpo38编辑,因为主窗口可能是QDialog或者可能在某个时刻显示QDialog,禁止重绘这不是更好,而不是隐藏QMainWindow的中央小部件?:

bool Application::notify(QObject * receiver, QEvent * event) 
{
    if ( event && 
         event->type() == QEvent::Paint )
    {
        if ( applicationState() != Qt::ApplicationActive )
        {
            return false;
        }
    }
    return QApplication::notify(receiver,event);
}
© www.soinside.com 2019 - 2024. All rights reserved.