Android: added ApplicationState capability.

The application state is tied to the QtActivity lifecycle.
Mapping of states between Android and Qt is as follows:
 onResume --> ApplicationActive
 onPause  --> ApplicationInactive
 onStop   --> ApplicationSuspended

Change-Id: Iefef08d6c7a7fde28fba1f4886882458cda6a0c0
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com>
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@digia.com>
This commit is contained in:
Yoann Lopes 2013-08-27 17:49:40 +02:00 committed by The Qt Project
parent fd871694e7
commit e94c221655
8 changed files with 64 additions and 0 deletions

View File

@ -160,6 +160,12 @@ public class QtActivityDelegate
private final int ImhEmailCharactersOnly = 0x200000; private final int ImhEmailCharactersOnly = 0x200000;
private final int ImhUrlCharactersOnly = 0x400000; private final int ImhUrlCharactersOnly = 0x400000;
// application state
private final int ApplicationSuspended = 0x0;
private final int ApplicationHidden = 0x1;
private final int ApplicationInactive = 0x2;
private final int ApplicationActive = 0x4;
public void resetSoftwareKeyboard() public void resetSoftwareKeyboard()
{ {
if (m_imm == null) if (m_imm == null)
@ -621,6 +627,11 @@ public class QtActivityDelegate
m_surface.applicationStarted(true); m_surface.applicationStarted(true);
} }
public void onPause()
{
QtNative.updateApplicationState(ApplicationInactive);
}
public void onResume() public void onResume()
{ {
// fire all lostActions // fire all lostActions
@ -631,12 +642,18 @@ public class QtActivityDelegate
m_activity.runOnUiThread(itr.next()); m_activity.runOnUiThread(itr.next());
if (m_started) { if (m_started) {
QtNative.updateApplicationState(ApplicationActive);
QtNative.clearLostActions(); QtNative.clearLostActions();
QtNative.updateWindow(); QtNative.updateWindow();
} }
} }
} }
public void onStop()
{
QtNative.updateApplicationState(ApplicationSuspended);
}
public Object onRetainNonConfigurationInstance() public Object onRetainNonConfigurationInstance()
{ {
try { try {

View File

@ -582,6 +582,9 @@ public class QtNative
public static native void updateWindow(); public static native void updateWindow();
// window methods // window methods
// application methods
public static native void updateApplicationState(int state);
// menu methods // menu methods
public static native boolean onPrepareOptionsMenu(Menu menu); public static native boolean onPrepareOptionsMenu(Menu menu);
public static native boolean onOptionsItemSelected(int itemId, boolean checked); public static native boolean onOptionsItemSelected(int itemId, boolean checked);

View File

@ -89,6 +89,9 @@ static AAssetManager *m_assetManager = NULL;
static jobject m_resourcesObj; static jobject m_resourcesObj;
static jobject m_activityObject = NULL; static jobject m_activityObject = NULL;
static bool m_activityActive = true; // defaults to true because when the platform plugin is
// initialized, QtActivity::onResume() has already been called
static jclass m_bitmapClass = 0; static jclass m_bitmapClass = 0;
static jmethodID m_createBitmapMethodID = 0; static jmethodID m_createBitmapMethodID = 0;
static jobject m_ARGB_8888_BitmapConfigValue = 0; static jobject m_ARGB_8888_BitmapConfigValue = 0;
@ -320,6 +323,12 @@ namespace QtAndroid
return m_activityObject; return m_activityObject;
} }
void setApplicationActive()
{
if (m_activityActive)
QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationActive);
}
jobject createBitmap(QImage img, JNIEnv *env) jobject createBitmap(QImage img, JNIEnv *env)
{ {
if (img.format() != QImage::Format_ARGB32 && img.format() != QImage::Format_RGB16) if (img.format() != QImage::Format_ARGB32 && img.format() != QImage::Format_RGB16)
@ -652,6 +661,16 @@ static void updateWindow(JNIEnv */*env*/, jobject /*thiz*/)
#endif #endif
} }
static void updateApplicationState(JNIEnv */*env*/, jobject /*thiz*/, jint state)
{
m_activityActive = (state == Qt::ApplicationActive);
if (!m_androidPlatformIntegration)
return;
QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationState(state));
}
static void handleOrientationChanged(JNIEnv */*env*/, jobject /*thiz*/, jint newOrientation) static void handleOrientationChanged(JNIEnv */*env*/, jobject /*thiz*/, jint newOrientation)
{ {
if (m_androidPlatformIntegration == 0) if (m_androidPlatformIntegration == 0)
@ -678,6 +697,7 @@ static JNINativeMethod methods[] = {
{"lockSurface", "()V", (void *)lockSurface}, {"lockSurface", "()V", (void *)lockSurface},
{"unlockSurface", "()V", (void *)unlockSurface}, {"unlockSurface", "()V", (void *)unlockSurface},
{"updateWindow", "()V", (void *)updateWindow}, {"updateWindow", "()V", (void *)updateWindow},
{"updateApplicationState", "(I)V", (void *)updateApplicationState},
{"handleOrientationChanged", "(I)V", (void *)handleOrientationChanged} {"handleOrientationChanged", "(I)V", (void *)handleOrientationChanged}
}; };

View File

@ -88,6 +88,8 @@ namespace QtAndroid
jclass applicationClass(); jclass applicationClass();
jobject activity(); jobject activity();
void setApplicationActive();
jobject createBitmap(QImage img, JNIEnv *env = 0); jobject createBitmap(QImage img, JNIEnv *env = 0);
jobject createBitmapDrawable(jobject bitmap, JNIEnv *env = 0); jobject createBitmapDrawable(jobject bitmap, JNIEnv *env = 0);

View File

@ -121,6 +121,12 @@ void QAndroidOpenGLPlatformWindow::raise()
void QAndroidOpenGLPlatformWindow::setVisible(bool visible) void QAndroidOpenGLPlatformWindow::setVisible(bool visible)
{ {
QEglFSWindow::setVisible(visible); QEglFSWindow::setVisible(visible);
// The Android Activity is activated before Qt is initialized, causing the application state to
// never be set to 'active'. We explicitly set this state when the first window becomes visible.
if (visible)
QtAndroid::setApplicationActive();
QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry())); // Expose event QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry())); // Expose event
QWindowSystemInterface::flushWindowSystemEvents(); QWindowSystemInterface::flushWindowSystemEvents();
} }

View File

@ -121,6 +121,7 @@ bool QAndroidPlatformIntegration::hasCapability(Capability cap) const
{ {
switch (cap) { switch (cap) {
case ThreadedPixmaps: return true; case ThreadedPixmaps: return true;
case ApplicationState: return true;
case NonFullScreenWindows: return false; case NonFullScreenWindows: return false;
case NativeWidgets: return false; case NativeWidgets: return false;
default: default:

View File

@ -41,6 +41,9 @@
#include "qandroidplatformwindow.h" #include "qandroidplatformwindow.h"
#include "androidjnimain.h"
#include <qpa/qwindowsysteminterface.h>
QAndroidPlatformWindow::QAndroidPlatformWindow(QWindow *window) : QFbWindow(window) QAndroidPlatformWindow::QAndroidPlatformWindow(QWindow *window) : QFbWindow(window)
{ {
} }
@ -54,3 +57,13 @@ void QAndroidPlatformWindow::propagateSizeHints()
{ {
//shut up warning from default implementation //shut up warning from default implementation
} }
void QAndroidPlatformWindow::setVisible(bool visible)
{
QFbWindow::setVisible(visible);
// The Android Activity is activated before Qt is initialized, causing the application state to
// never be set to 'active'. We explicitly set this state when the first window becomes visible.
if (visible)
QtAndroid::setApplicationActive();
}

View File

@ -52,6 +52,8 @@ public:
void propagateSizeHints(); void propagateSizeHints();
void setVisible(bool visible);
public slots: public slots:
void setGeometry(const QRect &rect); void setGeometry(const QRect &rect);