我正在Android上部署一个Qt应用程序。它连接BLE设备,接收和记录通知。
当安卓设备进入待机状态时,我的应用程序停止接收BLE通知(我不再接收QLowEnergyService::characteristicChanged信号),当我退出待机模式时,通知将再次收到。
我找到了这个帖子:如何防止Android设备以编程方式进入睡眠状态?,多亏了QAndroidJniObject,我才能在我的应用程序中实现锁(参见如何防止Android设备从Qt应用程序进入睡眠状态?)。
然而:
SCREEN_DIM_WAKE_LOCK,屏幕将不会进入待机状态,我将继续接收通知。PARTIAL_WAKE_LOCK,屏幕将进入备用状态,但是我将不会收到通知(就好像实际上没有创建任何锁一样)。我对SCREEN_DIM_WAKE_LOCK不满意,因为:
但是,仅让CPU保持活力( PARTIAL_WAKE_LOCK应该做的事情)是不够的。
知道如何关闭这个屏幕并继续接收我的BLE通知吗?还有其他锁定系统吗?只要通过QAndroidJniObject将java代码移植到Qt中,就可以接受java代码和答案。
发布于 2018-09-02 19:04:12
我猜您正在获取PARTIAL_WAKE_LOCK okay,但是当屏幕关闭时,您的应用程序进入“后台运行”,默认情况下,Qt生成的AndroidManifest.xml将禁用后台运行。
打开"AndroidManifest.xml“文件并切换到"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“,就像我在上面的片段中所做的那样。
当应用程序在后台运行时,可能不允许对屏幕进行任何更改,否则会发生意外的崩溃。对于我的应用程序,我只显示了一个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);
}https://stackoverflow.com/questions/51985915
复制相似问题