【问题标题】:Qt android screen lock java issueQt android屏幕锁定java问题
【发布时间】:2015-07-09 09:46:17
【问题描述】:

我有 Qt 应用程序,需要在应用程序运行时防止屏幕变暗。我在 main.cpp 的 main() 开头放置了以下代码:

#ifdef ANDROID
    // disable screen lock on android devices
    QAndroidJniObject activity = QtAndroid::androidActivity();
    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);
        }
    }
#endif

这几乎来自:How to keep the screen on in Qt for android?,除了我使用callMethod&lt;void&gt; 而不是callObjectMethod

问题是,当应用程序启动时,它会因巨大的 Java 日志而崩溃,我怀疑这是它的相关部分:

F/art     (26455): art/runtime/runtime.cc:289] Pending exception android.view.ViewRootImpl$CalledFromWrongThreadException thrown by 'unknown throw location'
F/art     (26455): art/runtime/runtime.cc:289] android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
F/art     (26455): art/runtime/runtime.cc:289]   at void android.view.ViewRootImpl.checkThread() (ViewRootImpl.java:6357)
F/art     (26455): art/runtime/runtime.cc:289]   at void android.view.ViewRootImpl.requestLayout() (ViewRootImpl.java:874)
F/art     (26455): art/runtime/runtime.cc:289]   at void android.view.View.requestLayout() (View.java:17476)
F/art     (26455): art/runtime/runtime.cc:289]   at void android.view.View.setLayoutParams(android.view.ViewGroup$LayoutParams) (View.java:11477)
F/art     (26455): art/runtime/runtime.cc:289]   at void android.view.WindowManagerGlobal.updateViewLayout(android.view.View, android.view.ViewGroup$LayoutParams) (WindowManagerGlobal.java:305)
F/art     (26455): art/runtime/runtime.cc:289]   at void android.view.WindowManagerImpl.updateViewLayout(android.view.View, android.view.ViewGroup$LayoutParams) (WindowManagerImpl.java:91)
F/art     (26455): art/runtime/runtime.cc:289]   at void android.app.Activity.onWindowAttributesChanged(android.view.WindowManager$LayoutParams) (Activity.java:2596)
F/art     (26455): art/runtime/runtime.cc:289]   at void org.qtproject.qt5.android.bindings.QtActivity.onWindowAttributesChanged(android.view.WindowManager$LayoutParams) (QtActivity.java:1385)
F/art     (26455): art/runtime/runtime.cc:289]   at void android.view.Window.dispatchWindowAttributesChanged(android.view.WindowManager$LayoutParams) (Window.java:836)
F/art     (26455): art/runtime/runtime.cc:289]   at void com.android.internal.policy.impl.PhoneWindow.dispatchWindowAttributesChanged(android.view.WindowManager$LayoutParams) (PhoneWindow.java:3993)
F/art     (26455): art/runtime/runtime.cc:289]   at void android.view.Window.setFlags(int, int) (Window.java:813)
F/art     (26455): art/runtime/runtime.cc:289]   at void android.view.Window.addFlags(int) (Window.java:771)

我向 AndroidManifest.xml 添加了适当的权限 (android.permission.WAKE_LOCK)。问题似乎是由于 addFlags() 在其主视图之外运行引起的?我用谷歌搜索了很多,找不到其他人有同样的问题。

谢谢, 伊万

【问题讨论】:

  • 忘了说我用的是Qt 5.4.0。

标签: android c++ qt java-native-interface qtandroidextras


【解决方案1】:
#if defined(Q_OS_ANDROID)
QAndroidJniObject activity = QtAndroid::androidActivity();
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);
    }
    QAndroidJniEnvironment env; if (env->ExceptionCheck()) { env->ExceptionClear(); } //Clear any possible pending exceptions.
}
#endif

here 获得,适用于我的 5.1 android 系统

【讨论】:

    【解决方案2】:

    我最终改用 Java 来做这个。

    这里是java代码:

    package org.qtproject.visualization;
    
    import org.qtproject.qt5.android.bindings.*;
    import android.os.Bundle;
    import android.view.WindowManager;
    
    public class ScreenOnActivity extends QtActivity
    {
        @Override
        public void onCreate(Bundle savedInstanceState)
        {
            getWindow().addFlags( WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON );
            super.onCreate(savedInstanceState);
        }
    }
    

    然后将其集成到应用程序的其余部分中。

    【讨论】:

      【解决方案3】:

      当部署在 Android 上时,Qt 实际上并不在主应用程序 (Java) 线程中运行。由于android.view.Window.addFlags必须从Java主线程调用,你很难回到这个线程让这段代码工作。

      最好使用WakeLock 来防止系统进入睡眠模式。 here is a post explaining how to do it.

      这将防止屏幕在应用程序运行时变暗。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-01-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-14
        • 1970-01-01
        相关资源
        最近更新 更多