diff --git a/Documentation/index.html b/Documentation/index.html index f9a67ea..9c6baa2 100644 --- a/Documentation/index.html +++ b/Documentation/index.html @@ -620,40 +620,24 @@

Sharing

UserMessagingPlatform

Under the Google EU User Consent Policy, you must make certain disclosures to your users in the European Economic Area (EEA) along with the UK and obtain their consent to use cookies or other local storage, where legally required, and to use personal data (such as AdID) to serve ads. This policy reflects the requirements of the EU ePrivacy Directive and the General Data Protection Regulation (GDPR).

This tool support the use of the UMP SDK but for a clear explanation about how to use this SDK and how to configure the consent form you have to read the official guide here. At first you must to request the consent form that can be or not be available for the zone your current user is:

+
QtAndroidUserMessagingPlatform.loadAndShowConsentFormIfRequired(underAgeOfConsent)
+

Param underAgeOfConsent is a boolean value to inform if the user is under age.

+

This function will generate two possibile events. One informing about failure with the error message string and the other informing about the form has been closed by the user. The two params inform, the first, if the form has been processed corrently or some error has occurred and, the second, if is required to show an option allowing the user to change the initial selection by showing again the form.

Connections {
     target: QtAndroidUserMessagingPlatform
-    function onConsentFormRequestResult(eventId)
+    function onConsentFormRequestFailure(errorMessage)
     {
-        switch(eventId)
-        {
-            case QtAndroidUserMessagingPlatform.CONSENT_FORM_INFO_UPDATE_FAILURE:
-                ....
-                break;
-            case QtAndroidUserMessagingPlatform.CONSENT_FORM_NOT_AVAILABLE:
-                ....
-                break;
-            case QtAndroidUserMessagingPlatform.CONSENT_FORM_LOAD_SUCCESS:
-                ....
-                break;
-            case QtAndroidUserMessagingPlatform.CONSENT_FORM_LOAD_FAILURE:
-                ....
-                break;
-        }
-}
-		
-QtAndroidUserMessagingPlatform.requestConsentForm()
- -

Once request process finish the signal consentFormRequestResult() is emitted with the results. Any event different from CONSENT_FORM_LOAD_SUCCESS means the form is not available for various reasons. Once obtained the form is necessary to check if it must be showed to the user. You can get such information as follow:

-
QtAndroidUserMessagingPlatform.consentStatus()
-

Possible returned values are:

-
QtAndroidUserMessagingPlatform.CONSENT_FORM_STATUS_UNKNOWN
-QtAndroidUserMessagingPlatform.CONSENT_FORM_STATUS_REQUIRED
-QtAndroidUserMessagingPlatform.CONSENT_FORM_STATUS_NOT_REQUIRED
-QtAndroidUserMessagingPlatform.CONSENT_FORM_STATUS_OBTAINED
-

If the status is different from CONSENT_FORM_STATUS_REQUIRED you don't need to show the form. On the contrary, in case of form required or if the user want to change his preferences you can show the form using the call:

-
QtAndroidUserMessagingPlatform.showConsentForm()
-

The event consentFormClosed() will inform you when the user closed the form and your app is ready to go. After the user accepted the form some data will be saved in the device and the form will not be required anymore. However if you want to reset these data for restart from scratch you can use the call:

-
QtAndroidUserMessagingPlatform.resetConsentInformation()
+ } + function onConsentFormDismissed(consentGathered, privacyOptionsRequired) + { + } +} +

To show the form again just call the function:

+
QtAndroidUserMessagingPlatform.showPrivacyOptionsForm()
+

To know if it will be possible to show ads it should be used this function (but, at least right now, it seems always return true also if the user negate consent to show ads):

+
QtAndroidUserMessagingPlatform.showPrivacyOptionsForm()
+

If you want to reset these data for restart from scratch you can use the call:

+
QtAndroidUserMessagingPlatform.canRequestAds()

This will clean all saved data.

diff --git a/QtAndroidTools/QAndroidUserMessagingPlatform.cpp b/QtAndroidTools/QAndroidUserMessagingPlatform.cpp index 7eb49da..8024eb4 100644 --- a/QtAndroidTools/QAndroidUserMessagingPlatform.cpp +++ b/QtAndroidTools/QAndroidUserMessagingPlatform.cpp @@ -36,8 +36,8 @@ QAndroidUserMessagingPlatform::QAndroidUserMessagingPlatform(QObject *parent) : if(m_javaUserMessagingPlatform.isValid()) { const JNINativeMethod jniMethod[] = { - {"consentFormRequestResult", "(I)V", reinterpret_cast(&QAndroidUserMessagingPlatform::deviceConsentFormRequestResult)}, - {"consentFormClosed", "()V", reinterpret_cast(&QAndroidUserMessagingPlatform::deviceConsentFormClosed)}, + {"consentFormRequestFailure", "(Ljava/lang/String;)V", reinterpret_cast(&QAndroidUserMessagingPlatform::deviceConsentFormRequestFailure)}, + {"consentFormDismissed", "(ZZ)V", reinterpret_cast(&QAndroidUserMessagingPlatform::deviceConsentFormDismissed)}, }; QJniEnvironment jniEnv; jclass objectClass; @@ -61,50 +61,52 @@ QAndroidUserMessagingPlatform* QAndroidUserMessagingPlatform::instance() return m_pInstance; } -void QAndroidUserMessagingPlatform::deviceConsentFormRequestResult(JNIEnv *env, jobject thiz, int eventId) +void QAndroidUserMessagingPlatform::deviceConsentFormRequestFailure(JNIEnv *env, jobject thiz, jstring errorMessage) { Q_UNUSED(env) Q_UNUSED(thiz) if(m_pInstance != nullptr) { - Q_EMIT m_pInstance->consentFormRequestResult(eventId); + QJniEnvironment jniEnv; + Q_EMIT m_pInstance->consentFormRequestFailure(QString(jniEnv->GetStringUTFChars(errorMessage, NULL))); } } -void QAndroidUserMessagingPlatform::deviceConsentFormClosed(JNIEnv *env, jobject thiz) +void QAndroidUserMessagingPlatform::deviceConsentFormDismissed(JNIEnv *env, jobject thiz, jboolean consentGathered, jboolean privacyOptionsRequired) { Q_UNUSED(env) Q_UNUSED(thiz) if(m_pInstance != nullptr) { - Q_EMIT m_pInstance->consentFormClosed(); + Q_EMIT m_pInstance->consentFormDismissed(consentGathered, privacyOptionsRequired); } } -void QAndroidUserMessagingPlatform::requestConsentForm() +void QAndroidUserMessagingPlatform::loadAndShowConsentFormIfRequired(bool underAgeOfConsent) { if(m_javaUserMessagingPlatform.isValid()) { - m_javaUserMessagingPlatform.callMethod("requestConsentForm"); + m_javaUserMessagingPlatform.callMethod("loadAndShowConsentFormIfRequired", + "(Z)V", + underAgeOfConsent); } } -int QAndroidUserMessagingPlatform::consentStatus() +void QAndroidUserMessagingPlatform::showPrivacyOptionsForm() { if(m_javaUserMessagingPlatform.isValid()) { - return m_javaUserMessagingPlatform.callMethod("consentStatus"); + m_javaUserMessagingPlatform.callMethod("showPrivacyOptionsForm"); } - return CONSENT_FORM_STATUS_UNKNOWN; } -bool QAndroidUserMessagingPlatform::showConsentForm() +bool QAndroidUserMessagingPlatform::canRequestAds() { if(m_javaUserMessagingPlatform.isValid()) { - return m_javaUserMessagingPlatform.callMethod("showConsentForm"); + return m_javaUserMessagingPlatform.callMethod("canRequestAds"); } return false; } diff --git a/QtAndroidTools/QAndroidUserMessagingPlatform.h b/QtAndroidTools/QAndroidUserMessagingPlatform.h index fd9466e..0443912 100644 --- a/QtAndroidTools/QAndroidUserMessagingPlatform.h +++ b/QtAndroidTools/QAndroidUserMessagingPlatform.h @@ -38,39 +38,22 @@ class QAndroidUserMessagingPlatform : public QObject public: QAndroidUserMessagingPlatform(QObject *parent); - enum CONSENT_STATUS - { - CONSENT_FORM_STATUS_UNKNOWN = 0, - CONSENT_FORM_STATUS_REQUIRED = 1, - CONSENT_FORM_STATUS_NOT_REQUIRED = 2, - CONSENT_FORM_STATUS_OBTAINED = 3, - }; - Q_ENUM(CONSENT_STATUS) - enum REQUEST_RESULT - { - CONSENT_FORM_INFO_UPDATE_FAILURE = 0, - CONSENT_FORM_NOT_AVAILABLE = 1, - CONSENT_FORM_LOAD_SUCCESS = 2, - CONSENT_FORM_LOAD_FAILURE = 3 - }; - Q_ENUM(REQUEST_RESULT) - static QAndroidUserMessagingPlatform* create(QQmlEngine *engine, QJSEngine *scriptEngine); static QAndroidUserMessagingPlatform* instance(); - Q_INVOKABLE void requestConsentForm(); - Q_INVOKABLE int consentStatus(); - Q_INVOKABLE bool showConsentForm(); + Q_INVOKABLE void loadAndShowConsentFormIfRequired(bool underAgeOfConsent); + Q_INVOKABLE void showPrivacyOptionsForm(); + Q_INVOKABLE bool canRequestAds(); Q_INVOKABLE void resetConsentInformation(); Q_SIGNALS: - void consentFormRequestResult(int eventId); - void consentFormClosed(); + void consentFormRequestFailure(const QString &errorMessage); + void consentFormDismissed(bool consentGathered, bool privacyOptionsRequired); private: const QJniObject m_javaUserMessagingPlatform; static QAndroidUserMessagingPlatform *m_pInstance; - static void deviceConsentFormRequestResult(JNIEnv *env, jobject thiz, int eventId); - static void deviceConsentFormClosed(JNIEnv *env, jobject thiz); + static void deviceConsentFormRequestFailure(JNIEnv *env, jobject thiz, jstring errorMessage); + static void deviceConsentFormDismissed(JNIEnv *env, jobject thiz, jboolean consentGathered, jboolean privacyOptionsRequired); }; diff --git a/QtAndroidTools/src/com/falsinsoft/qtandroidtools/AndroidUserMessagingPlatform.java b/QtAndroidTools/src/com/falsinsoft/qtandroidtools/AndroidUserMessagingPlatform.java index df30c4a..2e72abe 100644 --- a/QtAndroidTools/src/com/falsinsoft/qtandroidtools/AndroidUserMessagingPlatform.java +++ b/QtAndroidTools/src/com/falsinsoft/qtandroidtools/AndroidUserMessagingPlatform.java @@ -31,6 +31,7 @@ import androidx.annotation.Nullable; import com.google.android.ump.ConsentForm; import com.google.android.ump.ConsentInformation; +import com.google.android.ump.ConsentInformation.PrivacyOptionsRequirementStatus; import com.google.android.ump.ConsentRequestParameters; import com.google.android.ump.FormError; import com.google.android.ump.UserMessagingPlatform; @@ -40,8 +41,6 @@ public class AndroidUserMessagingPlatform private final ConsentInformation mConsentInformation; private final ConsentListener mConsentListener; private final Activity mActivityInstance; - private int mConsentStatus = ConsentInformation.ConsentStatus.UNKNOWN; - private ConsentForm mConsentForm = null; public AndroidUserMessagingPlatform(Activity activityInstance) { @@ -50,123 +49,70 @@ public AndroidUserMessagingPlatform(Activity activityInstance) mActivityInstance = activityInstance; } - public boolean showConsentForm() + public void resetConsentInformation() { - if(mConsentForm != null) - { - mActivityInstance.runOnUiThread(new Runnable() - { - @Override - public void run() - { - mConsentForm.show(mActivityInstance, mConsentListener); - } - }); - - return true; - } - - return false; + mConsentInformation.reset(); } - public void resetConsentInformation() + public boolean canRequestAds() { - mConsentInformation.reset(); + return mConsentInformation.canRequestAds(); } - public void requestConsentForm() + public void loadAndShowConsentFormIfRequired(boolean underAgeOfConsent) { - final ConsentRequestParameters params = new ConsentRequestParameters.Builder().build(); + final ConsentRequestParameters params = new ConsentRequestParameters.Builder() + .setTagForUnderAgeOfConsent(underAgeOfConsent) + .build(); + mConsentInformation.requestConsentInfoUpdate(mActivityInstance, params, mConsentListener, mConsentListener); } - public int consentStatus() + public void showPrivacyOptionsForm() { - int status = CONSENT_FORM_STATUS_UNKNOWN; - - switch(mConsentStatus) + mActivityInstance.runOnUiThread(new Runnable() { - case ConsentInformation.ConsentStatus.REQUIRED: - status = CONSENT_FORM_STATUS_REQUIRED; - break; - case ConsentInformation.ConsentStatus.NOT_REQUIRED: - status = CONSENT_FORM_STATUS_NOT_REQUIRED; - break; - case ConsentInformation.ConsentStatus.OBTAINED: - status = CONSENT_FORM_STATUS_OBTAINED; - break; - case ConsentInformation.ConsentStatus.UNKNOWN: - status = CONSENT_FORM_STATUS_UNKNOWN; - break; - } - - return status; + @Override + public void run() + { + UserMessagingPlatform.showPrivacyOptionsForm(mActivityInstance, mConsentListener); + } + }); } private class ConsentListener implements ConsentInformation.OnConsentInfoUpdateSuccessListener, ConsentInformation.OnConsentInfoUpdateFailureListener, - UserMessagingPlatform.OnConsentFormLoadSuccessListener, - UserMessagingPlatform.OnConsentFormLoadFailureListener, ConsentForm.OnConsentFormDismissedListener { @Override public void onConsentInfoUpdateSuccess() { - if(mConsentInformation.isConsentFormAvailable()) + mActivityInstance.runOnUiThread(new Runnable() { - mActivityInstance.runOnUiThread(new Runnable() + @Override + public void run() { - @Override - public void run() - { - UserMessagingPlatform.loadConsentForm(mActivityInstance, mConsentListener, mConsentListener); - } - }); - } - else - { - consentFormRequestResult(CONSENT_FORM_NOT_AVAILABLE); - } + UserMessagingPlatform.loadAndShowConsentFormIfRequired(mActivityInstance, mConsentListener); + } + }); } @Override public void onConsentInfoUpdateFailure(FormError formError) { - consentFormRequestResult(CONSENT_FORM_INFO_UPDATE_FAILURE); - } - - @Override - public void onConsentFormLoadSuccess(ConsentForm consentForm) - { - mConsentStatus = mConsentInformation.getConsentStatus(); - mConsentForm = consentForm; - - consentFormRequestResult(CONSENT_FORM_LOAD_SUCCESS); - } - - @Override - public void onConsentFormLoadFailure(FormError formError) - { - consentFormRequestResult(CONSENT_FORM_LOAD_FAILURE); + consentFormRequestFailure(formError.getMessage()); } @Override public void onConsentFormDismissed(@Nullable FormError formError) { - consentFormClosed(); + final boolean privacyOptionsRequired = (mConsentInformation.getPrivacyOptionsRequirementStatus() == PrivacyOptionsRequirementStatus.REQUIRED) ? true : false; + final boolean consentGathered = (formError == null) ? true : false; + + consentFormDismissed(consentGathered, privacyOptionsRequired); } } - private static final int CONSENT_FORM_INFO_UPDATE_FAILURE = 0; - private static final int CONSENT_FORM_NOT_AVAILABLE = 1; - private static final int CONSENT_FORM_LOAD_SUCCESS = 2; - private static final int CONSENT_FORM_LOAD_FAILURE = 3; - - private static final int CONSENT_FORM_STATUS_UNKNOWN = 0; - private static final int CONSENT_FORM_STATUS_REQUIRED = 1; - private static final int CONSENT_FORM_STATUS_NOT_REQUIRED = 2; - private static final int CONSENT_FORM_STATUS_OBTAINED = 3; - - private static native void consentFormRequestResult(int eventId); - private static native void consentFormClosed(); + private static native void consentFormRequestFailure(String errorMessage); + private static native void consentFormDismissed(boolean consentGathered, boolean privacyOptionsRequired); } diff --git a/QtAndroidToolsDemo/tools/AndroidUserMessagingPlatform.qml b/QtAndroidToolsDemo/tools/AndroidUserMessagingPlatform.qml index c0e9ca9..b22d20e 100644 --- a/QtAndroidToolsDemo/tools/AndroidUserMessagingPlatform.qml +++ b/QtAndroidToolsDemo/tools/AndroidUserMessagingPlatform.qml @@ -8,26 +8,14 @@ Page { Connections { target: QtAndroidUserMessagingPlatform - function onConsentFormRequestResult(eventId) + function onConsentFormRequestFailure(errorMessage) { - switch(eventId) - { - case QtAndroidUserMessagingPlatform.CONSENT_FORM_INFO_UPDATE_FAILURE: - consentFormRequestResult.text = "CONSENT_FORM_INFO_UPDATE_FAILURE"; - break; - case QtAndroidUserMessagingPlatform.CONSENT_FORM_NOT_AVAILABLE: - consentFormRequestResult.text = "CONSENT_FORM_NOT_AVAILABLE"; - break; - case QtAndroidUserMessagingPlatform.CONSENT_FORM_LOAD_SUCCESS: - consentFormRequestResult.text = "CONSENT_FORM_LOAD_SUCCESS"; - break; - case QtAndroidUserMessagingPlatform.CONSENT_FORM_LOAD_FAILURE: - consentFormRequestResult.text = "CONSENT_FORM_LOAD_FAILURE"; - break; - } + consentFormRequestResult.text = "Error: " + errorMessage; } - function onConsentFormClosed() + function onConsentFormDismissed(consentGathered, privacyOptionsRequired) { + consentFormRequestResult.text = "Consent Gathered " + (consentGathered ? "OK" : "Failed"); + showPrivacyOptionsFormButton.visible = privacyOptionsRequired; } } @@ -44,51 +32,34 @@ Page { } Button { anchors.horizontalCenter: parent.horizontalCenter - text: "requestConsentForm" - onClicked: QtAndroidUserMessagingPlatform.requestConsentForm() + text: "loadAndShowConsentFormIfRequired" + onClicked: QtAndroidUserMessagingPlatform.loadAndShowConsentFormIfRequired(false) } - Label { - id: consentStatus - width: parent.width - horizontalAlignment: Text.AlignHCenter - font.pixelSize: 15 - text: "-----" - } Button { + id: showPrivacyOptionsFormButton + visible: false anchors.horizontalCenter: parent.horizontalCenter - text: "consentStatus" - onClicked: { - var status = QtAndroidUserMessagingPlatform.consentStatus(); - - switch(eventId) - { - case QtAndroidUserMessagingPlatform.CONSENT_FORM_STATUS_UNKNOWN: - consentStatus.text = "CONSENT_FORM_STATUS_UNKNOWN"; - break; - case QtAndroidUserMessagingPlatform.CONSENT_FORM_STATUS_REQUIRED: - consentStatus.text = "CONSENT_FORM_STATUS_REQUIRED"; - break; - case QtAndroidUserMessagingPlatform.CONSENT_FORM_STATUS_NOT_REQUIRED: - consentStatus.text = "CONSENT_FORM_STATUS_NOT_REQUIRED"; - break; - case QtAndroidUserMessagingPlatform.CONSENT_FORM_STATUS_OBTAINED: - consentStatus.text = "CONSENT_FORM_STATUS_OBTAINED"; - break; - } - } + text: "showPrivacyOptionsForm" + onClicked: QtAndroidUserMessagingPlatform.showPrivacyOptionsForm() } Button { anchors.horizontalCenter: parent.horizontalCenter - text: "showConsentForm" - onClicked: QtAndroidUserMessagingPlatform.showConsentForm() + text: "resetConsentInformation" + onClicked: QtAndroidUserMessagingPlatform.resetConsentInformation() + } + Label { + id: canRequestAds + width: parent.width + horizontalAlignment: Text.AlignHCenter + font.pixelSize: 15 + text: "-----" } - Button { anchors.horizontalCenter: parent.horizontalCenter - text: "resetConsentInformation" - onClicked: QtAndroidUserMessagingPlatform.resetConsentInformation() + text: "canRequestAds" + onClicked: canRequestAds.text = QtAndroidUserMessagingPlatform.canRequestAds() ? "Yes" : "No" } } }