Android: Add enablers for listening to activity results
When you launch an activity through an intent, data can be provided back from the activity when it has finished using onActivityResult() in the activity which launched it. This is okay for applications, since they can easily create their own activities, but does not work for libraries that need to use intents. There is no listener API for activity results which allow external classes to eavesdrop. In order to support launching intents from third-party or add-on libraries, we provide a low-level way to hook into the activity result event. The corresponding public API will be added to QtAndroidExtras. Change-Id: I89417f485e2c0e69028dcccc7c155788346a7417 Reviewed-by: Christian Stromme <christian.stromme@digia.com>
This commit is contained in:
parent
c9cdbcb12f
commit
8d721b3c56
@ -44,6 +44,7 @@ package org.qtproject.qt5.android;
|
|||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.PackageManager.NameNotFoundException;
|
import android.content.pm.PackageManager.NameNotFoundException;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
@ -86,6 +87,7 @@ public class QtActivityDelegate
|
|||||||
private Method m_super_onKeyDown = null;
|
private Method m_super_onKeyDown = null;
|
||||||
private Method m_super_onKeyUp = null;
|
private Method m_super_onKeyUp = null;
|
||||||
private Method m_super_onConfigurationChanged = null;
|
private Method m_super_onConfigurationChanged = null;
|
||||||
|
private Method m_super_onActivityResult = null;
|
||||||
|
|
||||||
private static final String NATIVE_LIBRARIES_KEY = "native.libraries";
|
private static final String NATIVE_LIBRARIES_KEY = "native.libraries";
|
||||||
private static final String BUNDLED_LIBRARIES_KEY = "bundled.libraries";
|
private static final String BUNDLED_LIBRARIES_KEY = "bundled.libraries";
|
||||||
@ -410,6 +412,7 @@ public class QtActivityDelegate
|
|||||||
m_super_onKeyDown = m_activity.getClass().getMethod("super_onKeyDown", Integer.TYPE, KeyEvent.class);
|
m_super_onKeyDown = m_activity.getClass().getMethod("super_onKeyDown", Integer.TYPE, KeyEvent.class);
|
||||||
m_super_onKeyUp = m_activity.getClass().getMethod("super_onKeyUp", Integer.TYPE, KeyEvent.class);
|
m_super_onKeyUp = m_activity.getClass().getMethod("super_onKeyUp", Integer.TYPE, KeyEvent.class);
|
||||||
m_super_onConfigurationChanged = m_activity.getClass().getMethod("super_onConfigurationChanged", Configuration.class);
|
m_super_onConfigurationChanged = m_activity.getClass().getMethod("super_onConfigurationChanged", Configuration.class);
|
||||||
|
m_super_onActivityResult = m_activity.getClass().getMethod("super_onActivityResult", Integer.TYPE, Integer.TYPE, Intent.class);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return false;
|
return false;
|
||||||
@ -720,6 +723,18 @@ public class QtActivityDelegate
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onActivityResult(int requestCode, int resultCode, Intent data)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
m_super_onActivityResult.invoke(m_activity, requestCode, resultCode, data);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
QtNative.onActivityResult(requestCode, resultCode, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void onStop()
|
public void onStop()
|
||||||
{
|
{
|
||||||
QtNative.updateApplicationState(ApplicationSuspended);
|
QtNative.updateApplicationState(ApplicationSuspended);
|
||||||
|
@ -598,4 +598,7 @@ public class QtNative
|
|||||||
public static native boolean onContextItemSelected(int itemId, boolean checked);
|
public static native boolean onContextItemSelected(int itemId, boolean checked);
|
||||||
public static native void onContextMenuClosed(Menu menu);
|
public static native void onContextMenuClosed(Menu menu);
|
||||||
// menu methods
|
// menu methods
|
||||||
|
|
||||||
|
// activity methods
|
||||||
|
public static native void onActivityResult(int requestCode, int resultCode, Intent data);
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,8 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "qjnihelpers_p.h"
|
#include "qjnihelpers_p.h"
|
||||||
|
#include "qmutex.h"
|
||||||
|
#include "qlist.h"
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
@ -48,6 +50,39 @@ static jobject g_jActivity = Q_NULLPTR;
|
|||||||
static jobject g_jClassLoader = Q_NULLPTR;
|
static jobject g_jClassLoader = Q_NULLPTR;
|
||||||
static jint g_androidSdkVersion = 0;
|
static jint g_androidSdkVersion = 0;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
class ActivityResultListeners
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QMutex mutex;
|
||||||
|
QList<QtAndroidPrivate::ActivityResultListener *> listeners;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_GLOBAL_STATIC(ActivityResultListeners, g_activityResultListeners)
|
||||||
|
|
||||||
|
void QtAndroidPrivate::registerActivityResultListener(ActivityResultListener *listener)
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&g_activityResultListeners()->mutex);
|
||||||
|
g_activityResultListeners()->listeners.append(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtAndroidPrivate::unregisterActivityResultListener(ActivityResultListener *listener)
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&g_activityResultListeners()->mutex);
|
||||||
|
g_activityResultListeners()->listeners.removeAll(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtAndroidPrivate::handleActivityResult(jint requestCode, jint resultCode, jobject data)
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&g_activityResultListeners()->mutex);
|
||||||
|
const QList<QtAndroidPrivate::ActivityResultListener *> &listeners = g_activityResultListeners()->listeners;
|
||||||
|
for (int i=0; i<listeners.size(); ++i) {
|
||||||
|
if (listeners.at(i)->handleActivityResult(requestCode, resultCode, data))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static inline bool exceptionCheck(JNIEnv *env)
|
static inline bool exceptionCheck(JNIEnv *env)
|
||||||
{
|
{
|
||||||
if (env->ExceptionCheck()) {
|
if (env->ExceptionCheck()) {
|
||||||
|
@ -60,11 +60,22 @@ QT_BEGIN_NAMESPACE
|
|||||||
|
|
||||||
namespace QtAndroidPrivate
|
namespace QtAndroidPrivate
|
||||||
{
|
{
|
||||||
|
class Q_CORE_EXPORT ActivityResultListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~ActivityResultListener() {}
|
||||||
|
virtual bool handleActivityResult(jint requestCode, jint resultCode, jobject data) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
Q_CORE_EXPORT jobject activity();
|
Q_CORE_EXPORT jobject activity();
|
||||||
Q_CORE_EXPORT JavaVM *javaVM();
|
Q_CORE_EXPORT JavaVM *javaVM();
|
||||||
Q_CORE_EXPORT jint initJNI(JavaVM *vm, JNIEnv *env);
|
Q_CORE_EXPORT jint initJNI(JavaVM *vm, JNIEnv *env);
|
||||||
jobject classLoader();
|
jobject classLoader();
|
||||||
Q_CORE_EXPORT jint androidSdkVersion();
|
Q_CORE_EXPORT jint androidSdkVersion();
|
||||||
|
|
||||||
|
Q_CORE_EXPORT void handleActivityResult(jint requestCode, jint resultCode, jobject data);
|
||||||
|
Q_CORE_EXPORT void registerActivityResultListener(ActivityResultListener *listener);
|
||||||
|
Q_CORE_EXPORT void unregisterActivityResultListener(ActivityResultListener *listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -71,6 +71,7 @@
|
|||||||
#include <android/asset_manager_jni.h>
|
#include <android/asset_manager_jni.h>
|
||||||
#include "qandroidassetsfileenginehandler.h"
|
#include "qandroidassetsfileenginehandler.h"
|
||||||
#include <android/api-level.h>
|
#include <android/api-level.h>
|
||||||
|
#include <QtCore/private/qjnihelpers_p.h>
|
||||||
|
|
||||||
#include <qpa/qwindowsysteminterface.h>
|
#include <qpa/qwindowsysteminterface.h>
|
||||||
|
|
||||||
@ -621,6 +622,14 @@ static void handleOrientationChanged(JNIEnv */*env*/, jobject /*thiz*/, jint new
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void onActivityResult(JNIEnv */*env*/, jclass /*cls*/,
|
||||||
|
jint requestCode,
|
||||||
|
jint resultCode,
|
||||||
|
jobject data)
|
||||||
|
{
|
||||||
|
QtAndroidPrivate::handleActivityResult(requestCode, resultCode, data);
|
||||||
|
}
|
||||||
|
|
||||||
static JNINativeMethod methods[] = {
|
static JNINativeMethod methods[] = {
|
||||||
{"startQtAndroidPlugin", "()Z", (void *)startQtAndroidPlugin},
|
{"startQtAndroidPlugin", "()Z", (void *)startQtAndroidPlugin},
|
||||||
{"startQtApplication", "(Ljava/lang/String;Ljava/lang/String;)V", (void *)startQtApplication},
|
{"startQtApplication", "(Ljava/lang/String;Ljava/lang/String;)V", (void *)startQtApplication},
|
||||||
@ -630,7 +639,8 @@ static JNINativeMethod methods[] = {
|
|||||||
{"setSurface", "(ILjava/lang/Object;II)V", (void *)setSurface},
|
{"setSurface", "(ILjava/lang/Object;II)V", (void *)setSurface},
|
||||||
{"updateWindow", "()V", (void *)updateWindow},
|
{"updateWindow", "()V", (void *)updateWindow},
|
||||||
{"updateApplicationState", "(I)V", (void *)updateApplicationState},
|
{"updateApplicationState", "(I)V", (void *)updateApplicationState},
|
||||||
{"handleOrientationChanged", "(II)V", (void *)handleOrientationChanged}
|
{"handleOrientationChanged", "(II)V", (void *)handleOrientationChanged},
|
||||||
|
{"onActivityResult", "(IILandroid/content/Intent;)V", (void *)onActivityResult}
|
||||||
};
|
};
|
||||||
|
|
||||||
#define FIND_AND_CHECK_CLASS(CLASS_NAME) \
|
#define FIND_AND_CHECK_CLASS(CLASS_NAME) \
|
||||||
|
Loading…
Reference in New Issue
Block a user