Commit 4a81d3bb authored by Eskil Abrahamsen Blomfeldt's avatar Eskil Abrahamsen Blomfeldt Committed by The Qt Project
Browse files

Add API for starting intents


We need an API for this, because otherwise it would be
impossible to start intents and get results from them
without having access to the application's activities.
For third-party libraries etc., this is required.

When we define a public Java API, we will implement a similar
API there, so that applications can also start intents from
Java code without worrying about collisions with third-party
add-ons.

[ChangeLog][Intents] Introduced API to launch intents.

Change-Id: Ic3bbfbbaced3278c2ee970e74cba2997d5d867c4
Reviewed-by: default avatarChristian Stromme <christian.stromme@digia.com>
parent 7657bc4b
No related merge requests found
Showing with 362 additions and 2 deletions
SOURCES += \ SOURCES += \
$$PWD/qandroidfunctions.cpp $$PWD/qandroidfunctions.cpp \
$$PWD/qandroidactivityresultreceiver.cpp
HEADERS += \ HEADERS += \
$$PWD/qandroidfunctions.h $$PWD/qandroidfunctions.h \
\ No newline at end of file $$PWD/qandroidactivityresultreceiver.h \
$$PWD/qandroidactivityresultreceiver_p.h
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qandroidactivityresultreceiver.h"
#include "qandroidactivityresultreceiver_p.h"
#include "qandroidfunctions.h"
#include <QtCore/private/qjnihelpers_p.h>
#include <QtCore/qmutex.h>
QT_BEGIN_NAMESPACE
// Get a unique activity request code.
static int uniqueActivityRequestCode()
{
static QMutex mutex;
static int requestCode = 0x1000; // Reserve all request codes under 0x1000 for Qt.
QMutexLocker locker(&mutex);
if (requestCode == 0xf3ee) // Special case for MINISTRO_INSTALL_REQUEST_CODE
requestCode++;
if (requestCode == INT_MAX)
qWarning("Unique activity request code has wrapped. Unexpected behavior may occur.");
return requestCode++;
}
int QAndroidActivityResultReceiverPrivate::globalRequestCode(int localRequestCode) const
{
if (!localToGlobalRequestCode.contains(localRequestCode)) {
int globalRequestCode = uniqueActivityRequestCode();
localToGlobalRequestCode[localRequestCode] = globalRequestCode;
globalToLocalRequestCode[globalRequestCode] = localRequestCode;
}
return localToGlobalRequestCode.value(localRequestCode);
}
bool QAndroidActivityResultReceiverPrivate::handleActivityResult(jint requestCode, jint resultCode, jobject data)
{
if (globalToLocalRequestCode.contains(requestCode)) {
q->handleActivityResult(globalToLocalRequestCode.value(requestCode), resultCode, QAndroidJniObject(data));
return true;
}
return false;
}
/*!
\class QAndroidActivityResultReceiver
\since 5.3
\brief Interface used for callbacks from onActivityResult() in the main Android activity.
Create a subclass of this class to be notified of the results when using the
\c QtAndroid::startActivity() and \c QtAndroid::startIntentSender() APIs.
*/
/*!
\internal
*/
QAndroidActivityResultReceiver::QAndroidActivityResultReceiver()
: d(new QAndroidActivityResultReceiverPrivate)
{
d->q = this;
QtAndroidPrivate::registerActivityResultListener(d.data());
}
/*!
\internal
*/
QAndroidActivityResultReceiver::~QAndroidActivityResultReceiver()
{
QtAndroidPrivate::unregisterActivityResultListener(d.data());
}
/*!
\fn void QAndroidActivityResultReceiver::handleActivityResult(int receiverRequestCode, int resultCode, const QAndroidJniObject &data) = 0;
Reimplement this function to get activity results after starting an activity using either QtAndroid::startActivity() or
QtAndroid::startIntentSender(). The \a receiverRequestCode is the request code unique to this receiver which was originally
passed to the startActivity() or startIntentSender() functions. The \a resultCode is the result returned by the activity,
and \a data is either null or a Java object of the class android.content.Intent. Both the last to arguments are identical to the
arguments passed to onActivityResult().
*/
QT_END_NAMESPACE
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QANDROIDACTIVITYRESULTRECEIVER_H
#define QANDROIDACTIVITYRESULTRECEIVER_H
#include "qandroidextrasglobal.h"
#include "qandroidjniobject.h"
QT_BEGIN_NAMESPACE
class QAndroidActivityResultReceiverPrivate;
class Q_ANDROIDEXTRAS_EXPORT QAndroidActivityResultReceiver
{
public:
QAndroidActivityResultReceiver();
virtual ~QAndroidActivityResultReceiver();
virtual void handleActivityResult(int receiverRequestCode, int resultCode, const QAndroidJniObject &data) = 0;
private:
friend class QAndroidActivityResultReceiverPrivate;
Q_DISABLE_COPY(QAndroidActivityResultReceiver)
QScopedPointer<QAndroidActivityResultReceiverPrivate> d;
};
QT_END_NAMESPACE
#endif // QANDROIDACTIVITYRESULTRECEIVER_H
/****************************************************************************
**
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QANDROIDACTIVITYRESULTRECEIVER_P_H
#define QANDROIDACTIVITYRESULTRECEIVER_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <QtCore/qhash.h>
#include <QtCore/private/qjnihelpers_p.h>
#include "qandroidactivityresultreceiver.h"
QT_BEGIN_NAMESPACE
class QAndroidActivityResultReceiverPrivate: public QtAndroidPrivate::ActivityResultListener
{
public:
QAndroidActivityResultReceiver *q;
mutable QHash<int, int> localToGlobalRequestCode;
mutable QHash<int, int> globalToLocalRequestCode;
int globalRequestCode(int localRequestCode) const;
bool handleActivityResult(jint requestCode, jint resultCode, jobject data);
static QAndroidActivityResultReceiverPrivate *get(QAndroidActivityResultReceiver *publicObject)
{
return publicObject->d.data();
}
};
QT_END_NAMESPACE
#endif // QANDROIDACTIVITYRESULTRECEIVER_P_H
...@@ -40,6 +40,8 @@ ...@@ -40,6 +40,8 @@
****************************************************************************/ ****************************************************************************/
#include "qandroidfunctions.h" #include "qandroidfunctions.h"
#include "qandroidactivityresultreceiver.h"
#include "qandroidactivityresultreceiver_p.h"
#include <QtCore/private/qjnihelpers_p.h> #include <QtCore/private/qjnihelpers_p.h>
...@@ -77,4 +79,80 @@ int QtAndroid::androidSdkVersion() ...@@ -77,4 +79,80 @@ int QtAndroid::androidSdkVersion()
return QtAndroidPrivate::androidSdkVersion(); return QtAndroidPrivate::androidSdkVersion();
} }
/*!
\since 5.3
Starts the activity given by \a intent and provides the result asynchronously through the
\a resultReceiver if this is non-null.
If \a resultReceiver is null, then the \c startActivity() method in the \c androidActivity()
will be called. Otherwise \c startActivityForResult() will be called.
The \a receiverRequestCode is a request code unique to the \a resultReceiver, and will be
returned along with the result, making it possible to use the same receiver for more than
one intent.
The \a optionsBundle provides additional options for the activity.
*/
void QtAndroid::startActivity(const QAndroidJniObject &intent,
int receiverRequestCode,
QAndroidActivityResultReceiver *resultReceiver)
{
QAndroidJniObject activity = androidActivity();
if (resultReceiver != 0) {
QAndroidActivityResultReceiverPrivate *resultReceiverD = QAndroidActivityResultReceiverPrivate::get(resultReceiver);
activity.callMethod<void>("startActivityForResult",
"(Landroid/content/Intent;I)V",
intent.object<jobject>(),
resultReceiverD->globalRequestCode(receiverRequestCode));
} else {
activity.callMethod<void>("startActivity",
"(Landroid/content/Intent;)V",
intent.object<jobject>());
}
}
/*!
\since 5.3
Starts the activity given by \a intentSender and provides the result asynchronously through the
\a resultReceiver if this is non-null.
If \a resultReceiver is null, then the \c startIntentSender() method in the \c androidActivity()
will be called. Otherwise \c startIntentSenderForResult() will be called.
The \a receiverRequestCode is a request code unique to the \a resultReceiver, and will be
returned along with the result, making it possible to use the same receiver for more than
one intent.
The \a optionsBundle provides additional options for the activity.
*/
void QtAndroid::startIntentSender(const QAndroidJniObject &intentSender,
int receiverRequestCode,
QAndroidActivityResultReceiver *resultReceiver)
{
QAndroidJniObject activity = androidActivity();
if (resultReceiver != 0) {
QAndroidActivityResultReceiverPrivate *resultReceiverD = QAndroidActivityResultReceiverPrivate::get(resultReceiver);
activity.callMethod<void>("startIntentSenderForResult",
"(Landroid/content/IntentSender;ILandroid/content/Intent;III)V",
intentSender.object<jobject>(),
resultReceiverD->globalRequestCode(receiverRequestCode),
0, // fillInIntent
0, // flagsMask
0, // flagsValues
0); // extraFlags
} else {
activity.callMethod<void>("startIntentSender",
"(Landroid/content/Intent;Landroid/content/Intent;III)V",
intentSender.object<jobject>(),
0, // fillInIntent
0, // flagsMask
0, // flagsValues
0); // extraFlags
}
}
QT_END_NAMESPACE QT_END_NAMESPACE
...@@ -51,10 +51,19 @@ ...@@ -51,10 +51,19 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QAndroidActivityResultReceiver;
namespace QtAndroid namespace QtAndroid
{ {
Q_ANDROIDEXTRAS_EXPORT QAndroidJniObject androidActivity(); Q_ANDROIDEXTRAS_EXPORT QAndroidJniObject androidActivity();
Q_ANDROIDEXTRAS_EXPORT int androidSdkVersion(); Q_ANDROIDEXTRAS_EXPORT int androidSdkVersion();
Q_ANDROIDEXTRAS_EXPORT void startIntentSender(const QAndroidJniObject &intentSender,
int receiverRequestCode,
QAndroidActivityResultReceiver *resultReceiver = 0);
Q_ANDROIDEXTRAS_EXPORT void startActivity(const QAndroidJniObject &intent,
int receiverRequestCode,
QAndroidActivityResultReceiver *resultReceiver = 0);
} }
QT_END_NAMESPACE QT_END_NAMESPACE
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment