代码之家  ›  专栏  ›  技术社区  ›  jpo38

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

  •  1
  • jpo38  · 技术社区  · 6 年前

    当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 ,屏幕进入待机状态,但随后我将不会收到通知(好像实际上没有创建任何锁)

    我不满意 因为:

    • 我需要关闭屏幕,因为应用程序整晚都在睡床旁运行(获取用户的生理测量值)

    部分尾迹锁

    知道如何关闭此屏幕并继续接收BLE通知吗?还有别的锁系统吗?java代码是可以接受的,只要它不足以移植到Qt QAndroidJniObject对象

    1 回复  |  直到 6 年前
        1
  •  1
  •   jpo38    6 年前

    我的猜测是,您可以获得部分唤醒锁,但是当屏幕关闭时,您的应用程序进入“后台运行”,默认情况下,Qt生成的AndroidManifest.xml将禁用后台运行。

            <!-- 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”,正如我在上面的代码片段中所做的那样。

    当应用程序在后台运行时,可能不允许对屏幕进行任何更改,否则会发生意外崩溃。对于我的应用程序,我只显示了一个主窗口,通过实现如下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.";
        }
    }
    

    每当用户关闭屏幕或切换到其他前台应用程序时,将自动调用此函数。

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


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