From 7c4601473a6f1bafcf691fd5a120bc4e30ad1bf7 Mon Sep 17 00:00:00 2001 From: Lukasz Kozakiewicz Date: Wed, 8 May 2019 12:05:42 +0200 Subject: [PATCH] Android: fix PushNotifications that got broken by Android low level code rework. --- examples/Assets/google-services.json | 30 ++-- .../Builds/Android/app/CMakeLists.txt | 2 +- .../Builds/Android/app/build.gradle | 3 +- .../Android/app/src/main/AndroidManifest.xml | 2 +- .../app/src/main/assets/google-services.json | 30 ++-- .../src/main/assets/juce_icon_template.png | Bin 0 -> 18827 bytes examples/Utilities/PushNotificationsDemo.h | 100 ++++++++++++- .../Builds/Android/app/CMakeLists.txt | 2 +- .../Builds/Android/app/build.gradle | 3 +- .../Android/app/src/main/AndroidManifest.xml | 2 +- .../Builds/Android/app/CMakeLists.txt | 2 +- .../Builds/Android/app/build.gradle | 3 +- .../Android/app/src/main/AndroidManifest.xml | 2 +- .../Builds/Android/app/CMakeLists.txt | 2 +- .../Builds/Android/app/build.gradle | 3 +- .../Android/app/src/main/AndroidManifest.xml | 2 +- .../jucer_ProjectExport_Android.h | 71 +++++---- .../app/com/roli/juce/JuceActivity.java | 20 +++ .../misc/juce_PushNotifications.h | 8 +- .../juce/JuceFirebaseInstanceIdService.java | 16 ++ .../juce/JuceFirebaseMessagingService.java | 35 +++++ .../native/juce_android_PushNotifications.cpp | 141 ++++++++++++------ 22 files changed, 356 insertions(+), 123 deletions(-) create mode 100644 examples/DemoRunner/Builds/Android/app/src/main/assets/juce_icon_template.png create mode 100644 modules/juce_gui_basics/native/javaopt/app/com/roli/juce/JuceActivity.java create mode 100644 modules/juce_gui_extra/native/javaopt/app/com/roli/juce/JuceFirebaseInstanceIdService.java create mode 100644 modules/juce_gui_extra/native/javaopt/app/com/roli/juce/JuceFirebaseMessagingService.java diff --git a/examples/Assets/google-services.json b/examples/Assets/google-services.json index 9d83a3dca5..b4e3653198 100644 --- a/examples/Assets/google-services.json +++ b/examples/Assets/google-services.json @@ -1,39 +1,37 @@ { "project_info": { - "project_number": "3137221487", - "firebase_url": "https://pushnotificationsdemo-1c714.firebaseio.com", - "project_id": "pushnotificationsdemo-1c714", - "storage_bucket": "pushnotificationsdemo-1c714.appspot.com" + "project_number": "50526851168", + "firebase_url": "https://pushnotificationsdemorunner.firebaseio.com", + "project_id": "pushnotificationsdemorunner", + "storage_bucket": "pushnotificationsdemorunner.appspot.com" }, "client": [ { "client_info": { - "mobilesdk_app_id": "1:3137221487:android:8fdcd861a33b035c", + "mobilesdk_app_id": "1:50526851168:android:6fa3f0d4b79f1940", "android_client_info": { - "package_name": "com.juce.pushnotificationsdemo" + "package_name": "com.juce.demorunner" } }, "oauth_client": [ { - "client_id": "3137221487-uftk61ukltbi07dmejslgt0d6qnml0oo.apps.googleusercontent.com", + "client_id": "50526851168-vgn4rv0vimpc8kdm7ecmb3g95t1et0t5.apps.googleusercontent.com", "client_type": 3 } ], "api_key": [ { - "current_key": "AIzaSyDPpqphjiEEYI3sJGptrebN5Z52GkOG4Wo" + "current_key": "AIzaSyAMwLOFACFo7_SHm9iiVhoa0zCjFyMsgFc" } ], "services": { - "analytics_service": { - "status": 1 - }, "appinvite_service": { - "status": 1, - "other_platform_oauth_client": [] - }, - "ads_service": { - "status": 2 + "other_platform_oauth_client": [ + { + "client_id": "50526851168-vgn4rv0vimpc8kdm7ecmb3g95t1et0t5.apps.googleusercontent.com", + "client_type": 3 + } + ] } } } diff --git a/examples/DemoRunner/Builds/Android/app/CMakeLists.txt b/examples/DemoRunner/Builds/Android/app/CMakeLists.txt index 1c11cbe2a8..42078b2587 100644 --- a/examples/DemoRunner/Builds/Android/app/CMakeLists.txt +++ b/examples/DemoRunner/Builds/Android/app/CMakeLists.txt @@ -8,7 +8,7 @@ SET(BINARY_NAME "juce_jni") add_library("cpufeatures" STATIC "${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c") set_source_files_properties("${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c" PROPERTIES COMPILE_FLAGS "-Wno-sign-conversion -Wno-gnu-statement-expression") -add_definitions("-DJUCE_ANDROID=1" "-DJUCE_ANDROID_API_VERSION=23" "-DJUCE_PUSH_NOTIFICATIONS=1" "-DJUCE_ANDROID_GL_ES_VERSION_3_0=1" "-DJUCE_DEMO_RUNNER=1" "-DJUCE_UNIT_TESTS=1" "-DJUCER_ANDROIDSTUDIO_7F0E4A25=1" "-DJUCE_APP_VERSION=5.4.3" "-DJUCE_APP_VERSION_HEX=0x50403") +add_definitions("-DJUCE_ANDROID=1" "-DJUCE_ANDROID_API_VERSION=23" "-DJUCE_PUSH_NOTIFICATIONS=1" "-DJUCE_PUSH_NOTIFICATIONS_ACTIVITY=\"com/roli/juce/JuceActivity\"" "-DJUCE_ANDROID_GL_ES_VERSION_3_0=1" "-DJUCE_DEMO_RUNNER=1" "-DJUCE_UNIT_TESTS=1" "-DJUCER_ANDROIDSTUDIO_7F0E4A25=1" "-DJUCE_APP_VERSION=5.4.3" "-DJUCE_APP_VERSION_HEX=0x50403") include_directories( AFTER "../../../JuceLibraryCode" diff --git a/examples/DemoRunner/Builds/Android/app/build.gradle b/examples/DemoRunner/Builds/Android/app/build.gradle index 749b29c465..aff638682a 100644 --- a/examples/DemoRunner/Builds/Android/app/build.gradle +++ b/examples/DemoRunner/Builds/Android/app/build.gradle @@ -86,7 +86,8 @@ android { main.java.srcDirs += ["../../../../../modules/juce_core/native/javacore/init", "../../../../../modules/juce_core/native/javacore/app", - "../../../../../modules/juce_gui_basics/native/javacore/app"] + "../../../../../modules/juce_gui_basics/native/javacore/app", + "../../../../../modules/juce_gui_basics/native/javaopt/app"] main.res.srcDirs += [] diff --git a/examples/DemoRunner/Builds/Android/app/src/main/AndroidManifest.xml b/examples/DemoRunner/Builds/Android/app/src/main/AndroidManifest.xml index cd6917d0f3..69ec17232f 100644 --- a/examples/DemoRunner/Builds/Android/app/src/main/AndroidManifest.xml +++ b/examples/DemoRunner/Builds/Android/app/src/main/AndroidManifest.xml @@ -13,7 +13,7 @@ - diff --git a/examples/DemoRunner/Builds/Android/app/src/main/assets/google-services.json b/examples/DemoRunner/Builds/Android/app/src/main/assets/google-services.json index 9d83a3dca5..b4e3653198 100644 --- a/examples/DemoRunner/Builds/Android/app/src/main/assets/google-services.json +++ b/examples/DemoRunner/Builds/Android/app/src/main/assets/google-services.json @@ -1,39 +1,37 @@ { "project_info": { - "project_number": "3137221487", - "firebase_url": "https://pushnotificationsdemo-1c714.firebaseio.com", - "project_id": "pushnotificationsdemo-1c714", - "storage_bucket": "pushnotificationsdemo-1c714.appspot.com" + "project_number": "50526851168", + "firebase_url": "https://pushnotificationsdemorunner.firebaseio.com", + "project_id": "pushnotificationsdemorunner", + "storage_bucket": "pushnotificationsdemorunner.appspot.com" }, "client": [ { "client_info": { - "mobilesdk_app_id": "1:3137221487:android:8fdcd861a33b035c", + "mobilesdk_app_id": "1:50526851168:android:6fa3f0d4b79f1940", "android_client_info": { - "package_name": "com.juce.pushnotificationsdemo" + "package_name": "com.juce.demorunner" } }, "oauth_client": [ { - "client_id": "3137221487-uftk61ukltbi07dmejslgt0d6qnml0oo.apps.googleusercontent.com", + "client_id": "50526851168-vgn4rv0vimpc8kdm7ecmb3g95t1et0t5.apps.googleusercontent.com", "client_type": 3 } ], "api_key": [ { - "current_key": "AIzaSyDPpqphjiEEYI3sJGptrebN5Z52GkOG4Wo" + "current_key": "AIzaSyAMwLOFACFo7_SHm9iiVhoa0zCjFyMsgFc" } ], "services": { - "analytics_service": { - "status": 1 - }, "appinvite_service": { - "status": 1, - "other_platform_oauth_client": [] - }, - "ads_service": { - "status": 2 + "other_platform_oauth_client": [ + { + "client_id": "50526851168-vgn4rv0vimpc8kdm7ecmb3g95t1et0t5.apps.googleusercontent.com", + "client_type": 3 + } + ] } } } diff --git a/examples/DemoRunner/Builds/Android/app/src/main/assets/juce_icon_template.png b/examples/DemoRunner/Builds/Android/app/src/main/assets/juce_icon_template.png new file mode 100644 index 0000000000000000000000000000000000000000..e2964f1c3435da578d24b3940167d51b05d8914f GIT binary patch literal 18827 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 literal 0 HcmV?d00001 diff --git a/examples/Utilities/PushNotificationsDemo.h b/examples/Utilities/PushNotificationsDemo.h index 56065a998b..107ff5bf10 100644 --- a/examples/Utilities/PushNotificationsDemo.h +++ b/examples/Utilities/PushNotificationsDemo.h @@ -51,6 +51,74 @@ #include "../Assets/DemoUtilities.h" +/* + To finish the setup of this demo, do the following: + +1. Download google_services.json from your Firebase project. +2. Update "Remote Notifications Config File" path in Android exporter (this can be different for debug and release) + to point to that json file. +3. Add image and sound resources by adding the following to "Extra Android Raw Resources" in Projucer: + +../../Assets/Notifications/images/ic_stat_name.png +../../Assets/Notifications/images/ic_stat_name2.png +../../Assets/Notifications/images/ic_stat_name3.png +../../Assets/Notifications/images/ic_stat_name4.png +../../Assets/Notifications/images/ic_stat_name5.png +../../Assets/Notifications/images/ic_stat_name6.png +../../Assets/Notifications/images/ic_stat_name7.png +../../Assets/Notifications/images/ic_stat_name8.png +../../Assets/Notifications/images/ic_stat_name9.png +../../Assets/Notifications/images/ic_stat_name10.png +../../Assets/Notifications/sounds/demonstrative.mp3 +../../Assets/Notifications/sounds/isntit.mp3 +../../Assets/Notifications/sounds/jinglebellssms.mp3 +../../Assets/Notifications/sounds/served.mp3 +../../Assets/Notifications/sounds/solemn.mp3 + +4. Set "Remote Notifications" to enabled in Projucer Android exporter. + +To verify that remote notifications are configured properly, go to Remote tab in the demo and press "GetDeviceToken" +button, a dialog with your token (also printed to console in debug build) should show up. + + +The following steps are only necessary if you have a custom activity defined: + +5. Ensure that its launchMode is set to "singleTop" or "singleTask" in Android manifest. This is the default behaviour + in JUCE so you only need to do it if you have custom Android manifest content. You can do it from Projucer by + ensuring that "Custom Manifest XML Content" contains: + + + + + + + + +6. Ensure that you override onNewIntent() function in the same way as it is done in JuceActivity.java: + +package com.roli.juce; + +import android.app.Activity; +import android.content.Intent; + +//============================================================================== +public class JuceActivity extends Activity +{ + //============================================================================== + private native void appNewIntent (Intent intent); + + @Override + protected void onNewIntent (Intent intent) + { + super.onNewIntent(intent); + setIntent(intent); + + appNewIntent (intent); + } +} + +*/ + //============================================================================== class PushNotificationsDemo : public Component, private ChangeListener, @@ -101,11 +169,11 @@ public: #endif sendButton.onClick = [this] { sendLocalNotification(); }; - auxActionsView.getDeliveredNotificationsButton .onClick = [this] + auxActionsView.getDeliveredNotificationsButton .onClick = [] { PushNotifications::getInstance()->getDeliveredNotifications(); }; auxActionsView.removeDeliveredNotifWithIdButton.onClick = [this] { PushNotifications::getInstance()->removeDeliveredNotification (auxActionsView.deliveredNotifIdentifier.getText()); }; - auxActionsView.removeAllDeliveredNotifsButton .onClick = [this] + auxActionsView.removeAllDeliveredNotifsButton .onClick = [] { PushNotifications::getInstance()->removeAllDeliveredNotifications(); }; #if JUCE_IOS || JUCE_MAC auxActionsView.getPendingNotificationsButton .onClick = [this] @@ -116,7 +184,7 @@ public: { PushNotifications::getInstance()->removeAllPendingLocalNotifications(); }; #endif - remoteView.getDeviceTokenButton.onClick = [this] + remoteView.getDeviceTokenButton.onClick = [] { String token = PushNotifications::getInstance()->getDeviceToken(); @@ -129,7 +197,7 @@ public: }; #if JUCE_ANDROID - remoteView.sendRemoteMessageButton.onClick = [this] + remoteView.sendRemoteMessageButton.onClick = [] { StringPairArray data; data.set ("key1", "value1"); @@ -144,9 +212,9 @@ public: data); }; - remoteView.subscribeToSportsButton .onClick = [this] + remoteView.subscribeToSportsButton .onClick = [] { PushNotifications::getInstance()->subscribeToTopic ("sports"); }; - remoteView.unsubscribeFromSportsButton.onClick = [this] + remoteView.unsubscribeFromSportsButton.onClick = [] { PushNotifications::getInstance()->unsubscribeFromTopic ("sports"); }; #endif @@ -164,11 +232,31 @@ public: PushNotifications::ChannelGroup cg { "demoGroup", "demo group" }; PushNotifications::getInstance()->setupChannels ({ { cg } }, getAndroidChannels()); #endif + + #if JUCE_IOS || JUCE_ANDROID + setPortraitOrientationEnabled (true); + #endif } ~PushNotificationsDemo() { PushNotifications::getInstance()->removeListener (this); + + #if JUCE_IOS || JUCE_ANDROID + setPortraitOrientationEnabled (false); + #endif + } + + void setPortraitOrientationEnabled (bool shouldBeEnabled) + { + auto allowedOrientations = Desktop::getInstance().getOrientationsEnabled(); + + if (shouldBeEnabled) + allowedOrientations |= Desktop::upright; + else + allowedOrientations &= ~Desktop::upright; + + Desktop::getInstance().setOrientationsEnabled (allowedOrientations); } void paint (Graphics& g) override diff --git a/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt b/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt index 1ce2dac333..90abf88e8b 100644 --- a/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt +++ b/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt @@ -8,7 +8,7 @@ SET(BINARY_NAME "juce_jni") add_library("cpufeatures" STATIC "${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c") set_source_files_properties("${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c" PROPERTIES COMPILE_FLAGS "-Wno-sign-conversion -Wno-gnu-statement-expression") -add_definitions("-DJUCE_ANDROID=1" "-DJUCE_ANDROID_API_VERSION=23" "-DJUCE_PUSH_NOTIFICATIONS=1" "-DJUCE_ANDROID_GL_ES_VERSION_3_0=1" "-DJUCER_ANDROIDSTUDIO_7F0E4A25=1" "-DJUCE_APP_VERSION=1.0.0" "-DJUCE_APP_VERSION_HEX=0x10000") +add_definitions("-DJUCE_ANDROID=1" "-DJUCE_ANDROID_API_VERSION=23" "-DJUCE_PUSH_NOTIFICATIONS=1" "-DJUCE_PUSH_NOTIFICATIONS_ACTIVITY=\"com/roli/juce/JuceActivity\"" "-DJUCE_ANDROID_GL_ES_VERSION_3_0=1" "-DJUCER_ANDROIDSTUDIO_7F0E4A25=1" "-DJUCE_APP_VERSION=1.0.0" "-DJUCE_APP_VERSION_HEX=0x10000") include_directories( AFTER "../../../JuceLibraryCode" diff --git a/extras/AudioPerformanceTest/Builds/Android/app/build.gradle b/extras/AudioPerformanceTest/Builds/Android/app/build.gradle index a1119b36ef..cd5a272f44 100644 --- a/extras/AudioPerformanceTest/Builds/Android/app/build.gradle +++ b/extras/AudioPerformanceTest/Builds/Android/app/build.gradle @@ -89,7 +89,8 @@ android { main.java.srcDirs += ["../../../../../modules/juce_core/native/javacore/init", "../../../../../modules/juce_core/native/javacore/app", - "../../../../../modules/juce_gui_basics/native/javacore/app"] + "../../../../../modules/juce_gui_basics/native/javacore/app", + "../../../../../modules/juce_gui_basics/native/javaopt/app"] main.res.srcDirs += [] diff --git a/extras/AudioPerformanceTest/Builds/Android/app/src/main/AndroidManifest.xml b/extras/AudioPerformanceTest/Builds/Android/app/src/main/AndroidManifest.xml index 78eb252166..de868f8819 100644 --- a/extras/AudioPerformanceTest/Builds/Android/app/src/main/AndroidManifest.xml +++ b/extras/AudioPerformanceTest/Builds/Android/app/src/main/AndroidManifest.xml @@ -10,7 +10,7 @@ - diff --git a/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt b/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt index 3c4a655877..9de9ffb230 100644 --- a/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt +++ b/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt @@ -8,7 +8,7 @@ SET(BINARY_NAME "juce_jni") add_library("cpufeatures" STATIC "${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c") set_source_files_properties("${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c" PROPERTIES COMPILE_FLAGS "-Wno-sign-conversion -Wno-gnu-statement-expression") -add_definitions("-DJUCE_ANDROID=1" "-DJUCE_ANDROID_API_VERSION=23" "-DJUCE_PUSH_NOTIFICATIONS=1" "-DJUCE_ANDROID_GL_ES_VERSION_3_0=1" "-DJUCER_ANDROIDSTUDIO_7F0E4A25=1" "-DJUCE_APP_VERSION=1.0.0" "-DJUCE_APP_VERSION_HEX=0x10000") +add_definitions("-DJUCE_ANDROID=1" "-DJUCE_ANDROID_API_VERSION=23" "-DJUCE_PUSH_NOTIFICATIONS=1" "-DJUCE_PUSH_NOTIFICATIONS_ACTIVITY=\"com/roli/juce/JuceActivity\"" "-DJUCE_ANDROID_GL_ES_VERSION_3_0=1" "-DJUCER_ANDROIDSTUDIO_7F0E4A25=1" "-DJUCE_APP_VERSION=1.0.0" "-DJUCE_APP_VERSION_HEX=0x10000") include_directories( AFTER "../../../../../modules/juce_audio_processors/format_types/VST3_SDK" diff --git a/extras/AudioPluginHost/Builds/Android/app/build.gradle b/extras/AudioPluginHost/Builds/Android/app/build.gradle index 2887ac6373..fe112cc78b 100644 --- a/extras/AudioPluginHost/Builds/Android/app/build.gradle +++ b/extras/AudioPluginHost/Builds/Android/app/build.gradle @@ -86,7 +86,8 @@ android { main.java.srcDirs += ["../../../../../modules/juce_core/native/javacore/init", "../../../../../modules/juce_core/native/javacore/app", - "../../../../../modules/juce_gui_basics/native/javacore/app"] + "../../../../../modules/juce_gui_basics/native/javacore/app", + "../../../../../modules/juce_gui_basics/native/javaopt/app"] main.res.srcDirs += [] diff --git a/extras/AudioPluginHost/Builds/Android/app/src/main/AndroidManifest.xml b/extras/AudioPluginHost/Builds/Android/app/src/main/AndroidManifest.xml index 100f76348b..a81c4764c6 100644 --- a/extras/AudioPluginHost/Builds/Android/app/src/main/AndroidManifest.xml +++ b/extras/AudioPluginHost/Builds/Android/app/src/main/AndroidManifest.xml @@ -12,7 +12,7 @@ - diff --git a/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt b/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt index cf2ffaadb3..c8cc53b9da 100644 --- a/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt +++ b/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt @@ -8,7 +8,7 @@ SET(BINARY_NAME "juce_jni") add_library("cpufeatures" STATIC "${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c") set_source_files_properties("${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c" PROPERTIES COMPILE_FLAGS "-Wno-sign-conversion -Wno-gnu-statement-expression") -add_definitions("-DJUCE_ANDROID=1" "-DJUCE_ANDROID_API_VERSION=16" "-DJUCE_PUSH_NOTIFICATIONS=1" "-DJUCER_ANDROIDSTUDIO_7F0E4A25=1" "-DJUCE_APP_VERSION=1.0.0" "-DJUCE_APP_VERSION_HEX=0x10000") +add_definitions("-DJUCE_ANDROID=1" "-DJUCE_ANDROID_API_VERSION=16" "-DJUCE_PUSH_NOTIFICATIONS=1" "-DJUCE_PUSH_NOTIFICATIONS_ACTIVITY=\"com/roli/juce/JuceActivity\"" "-DJUCER_ANDROIDSTUDIO_7F0E4A25=1" "-DJUCE_APP_VERSION=1.0.0" "-DJUCE_APP_VERSION_HEX=0x10000") include_directories( AFTER "../../../JuceLibraryCode" diff --git a/extras/NetworkGraphicsDemo/Builds/Android/app/build.gradle b/extras/NetworkGraphicsDemo/Builds/Android/app/build.gradle index 8d8d7bc764..de758de0cf 100644 --- a/extras/NetworkGraphicsDemo/Builds/Android/app/build.gradle +++ b/extras/NetworkGraphicsDemo/Builds/Android/app/build.gradle @@ -86,7 +86,8 @@ android { main.java.srcDirs += ["../../../../../modules/juce_core/native/javacore/init", "../../../../../modules/juce_core/native/javacore/app", - "../../../../../modules/juce_gui_basics/native/javacore/app"] + "../../../../../modules/juce_gui_basics/native/javacore/app", + "../../../../../modules/juce_gui_basics/native/javaopt/app"] main.res.srcDirs += [] diff --git a/extras/NetworkGraphicsDemo/Builds/Android/app/src/main/AndroidManifest.xml b/extras/NetworkGraphicsDemo/Builds/Android/app/src/main/AndroidManifest.xml index ddb9f1dbc3..87a55c1e27 100644 --- a/extras/NetworkGraphicsDemo/Builds/Android/app/src/main/AndroidManifest.xml +++ b/extras/NetworkGraphicsDemo/Builds/Android/app/src/main/AndroidManifest.xml @@ -11,7 +11,7 @@ - diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Android.h b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Android.h index 59595865cd..e576c588a1 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Android.h +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Android.h @@ -84,6 +84,8 @@ public: static const char* getName() { return "Android"; } static const char* getValueTreeTypeName() { return "ANDROIDSTUDIO"; } + static const char* getDefaultActivityClass() { return "com.roli.juce.JuceActivity"; } + static const char* getDefaultApplicationClass() { return "com.roli.juce.JuceApp"; } static AndroidProjectExporter* createForSettings (Project& project, const ValueTree& settings) { @@ -98,7 +100,7 @@ public: androidCustomActivityClass, androidCustomApplicationClass, androidManifestCustomXmlElements, androidVersionCode, androidMinimumSDK, androidTargetSDK, androidTheme, androidSharedLibraries, androidStaticLibraries, androidExtraAssetsFolder, androidOboeRepositoryPath, androidInternetNeeded, androidMicNeeded, androidCameraNeeded, androidBluetoothNeeded, androidExternalReadPermission, - androidExternalWritePermission, androidInAppBillingPermission, androidVibratePermission,androidOtherPermissions, + androidExternalWritePermission, androidInAppBillingPermission, androidVibratePermission, androidOtherPermissions, androidEnableRemoteNotifications, androidRemoteNotificationsConfigFile, androidEnableContentSharing, androidKeyStore, androidKeyStorePass, androidKeyAlias, androidKeyAliasPass, gradleVersion, gradleToolchain, androidPluginVersion; @@ -111,8 +113,8 @@ public: androidRepositories (settings, Ids::androidRepositories, getUndoManager()), androidDependencies (settings, Ids::androidDependencies, getUndoManager()), androidScreenOrientation (settings, Ids::androidScreenOrientation, getUndoManager(), "unspecified"), - androidCustomActivityClass (settings, Ids::androidCustomActivityClass, getUndoManager()), - androidCustomApplicationClass (settings, Ids::androidCustomApplicationClass, getUndoManager(), "com.roli.juce.JuceApp"), + androidCustomActivityClass (settings, Ids::androidCustomActivityClass, getUndoManager(), getDefaultActivityClass()), + androidCustomApplicationClass (settings, Ids::androidCustomApplicationClass, getUndoManager(), getDefaultApplicationClass()), androidManifestCustomXmlElements (settings, Ids::androidManifestCustomXmlElements, getUndoManager()), androidVersionCode (settings, Ids::androidVersionCode, getUndoManager(), "1"), androidMinimumSDK (settings, Ids::androidMinimumSDK, getUndoManager(), "16"), @@ -570,7 +572,7 @@ private: mo << " classpath 'com.android.tools.build:gradle:" << androidPluginVersion.get().toString() << "'" << newLine; if (androidEnableRemoteNotifications.get()) - mo << " classpath 'com.google.gms:google-services:3.1.0'" << newLine; + mo << " classpath 'com.google.gms:google-services:4.0.1'" << newLine; mo << " }" << newLine; mo << "}" << newLine; @@ -814,8 +816,8 @@ private: if (androidEnableRemoteNotifications.get()) { - mo << " 'com.google.firebase:firebase-core:11.4.0'" << newLine; - mo << " compile 'com.google.firebase:firebase-messaging:11.4.0'" << newLine; + mo << " implementation 'com.google.firebase:firebase-core:16.0.1'" << newLine; + mo << " implementation 'com.google.firebase:firebase-messaging:17.6.0'" << newLine; } mo << " }" << newLine; @@ -834,17 +836,32 @@ private: return mo.toString(); } - void addModuleJavaFolderToSourceSet(StringArray& javaSourceSets, const File& javacore) const + void addModuleJavaFolderToSourceSet(StringArray& javaSourceSets, const File& source) const { - if (javacore.isDirectory()) + if (source.isDirectory()) { auto appFolder = getTargetFolder().getChildFile ("app"); - RelativePath relativePath (javacore, appFolder, RelativePath::buildTargetFolder); + RelativePath relativePath (source, appFolder, RelativePath::buildTargetFolder); javaSourceSets.add (relativePath.toUnixStyle()); } } + void addOptJavaFolderToSourceSetsForModule (StringArray& javaSourceSets, + const OwnedArray& modules, + const String& moduleID) const + { + for (auto& m : modules) + { + if (m->getID() == moduleID) + { + auto javaFolder = m->getFolder().getChildFile ("native").getChildFile ("javaopt"); + addModuleJavaFolderToSourceSet (javaSourceSets, javaFolder.getChildFile("app")); + return; + } + } + } + String getAndroidJavaSourceSets (const OwnedArray& modules) const { auto javaSourceSets = getSourceSetArrayFor (androidAdditionalJavaFolders.get().toString()); @@ -860,6 +877,12 @@ private: addModuleJavaFolderToSourceSet (javaSourceSets, javaFolder.getChildFile("app")); } + if (androidCustomActivityClass.get() == getDefaultActivityClass()) + addOptJavaFolderToSourceSetsForModule (javaSourceSets, modules, "juce_gui_basics"); + + if (androidEnableRemoteNotifications.get()) + addOptJavaFolderToSourceSetsForModule (javaSourceSets, modules, "juce_gui_extra"); + MemoryOutputStream mo; mo.setNewLineString ("\n"); @@ -974,7 +997,9 @@ private: props.add (new TextPropertyComponent (androidCustomActivityClass, "Custom Android Activity", 256, false), "If not empty, specifies the Android Activity class name stored in the app's manifest which " - "should be used instead of Android's default Activity."); + "should be used instead of default com.roli.juce.JuceActivity. If you specify a custom Activity " + "then you should implement onNewIntent() function like the one in com.roli.juce.JuceActivity, if " + "you wish to be able to handle push notification events."); props.add (new TextPropertyComponent (androidCustomApplicationClass, "Custom Android Application", 256, false), "If not empty, specifies the Android Application class name stored in the app's manifest which " @@ -1135,19 +1160,8 @@ private: } } - String getActivityClass() const - { - auto customActivityClass = androidCustomActivityClass.get().toString(); - - return (customActivityClass.isEmpty()) ? "android.app.Activity" : customActivityClass; - } - - String getApplicationClass() const - { - auto customApplicationClass = androidCustomApplicationClass.get().toString(); - - return (customApplicationClass.isEmpty()) ? "com.roli.juce.JuceApp" : customApplicationClass; - } + String getActivityClass() const { return androidCustomActivityClass.get(); } + String getApplicationClass() const { return androidCustomApplicationClass.get(); } String getJNIActivityClassName() const { @@ -1374,6 +1388,7 @@ private: defines.set ("JUCE_ANDROID", "1"); defines.set ("JUCE_ANDROID_API_VERSION", androidMinimumSDK.get()); defines.set ("JUCE_PUSH_NOTIFICATIONS", "1"); + defines.set ("JUCE_PUSH_NOTIFICATIONS_ACTIVITY", String::formatted("\"%s\"", getJNIActivityClassName().toUTF8())); if (androidInAppBillingPermission.get()) defines.set ("JUCE_IN_APP_PURCHASES", "1"); @@ -1381,6 +1396,12 @@ private: if (supportsGLv3()) defines.set ("JUCE_ANDROID_GL_ES_VERSION_3_0", "1"); + if (androidEnableRemoteNotifications.get()) + { + defines.set ("JUCE_FIREBASE_INSTANCE_ID_SERVICE_CLASSNAME", "com_roli_juce_JuceFirebaseInstanceIdService"); + defines.set ("JUCE_FIREBASE_MESSAGING_SERVICE_CLASSNAME", "com_roli_juce_JuceFirebaseMessagingService"); + } + return defines; } @@ -1683,12 +1704,12 @@ private: if (androidEnableRemoteNotifications.get()) { auto* service = application.createNewChildElement ("service"); - service->setAttribute ("android:name", ".JuceFirebaseMessagingService"); + service->setAttribute ("android:name", "com.roli.juce.JuceFirebaseMessagingService"); auto* intentFilter = service->createNewChildElement ("intent-filter"); intentFilter->createNewChildElement ("action")->setAttribute ("android:name", "com.google.firebase.MESSAGING_EVENT"); service = application.createNewChildElement ("service"); - service->setAttribute ("android:name", ".JuceFirebaseInstanceIdService"); + service->setAttribute ("android:name", "com.roli.juce.JuceFirebaseInstanceIdService"); intentFilter = service->createNewChildElement ("intent-filter"); intentFilter->createNewChildElement ("action")->setAttribute ("android:name", "com.google.firebase.INSTANCE_ID_EVENT"); diff --git a/modules/juce_gui_basics/native/javaopt/app/com/roli/juce/JuceActivity.java b/modules/juce_gui_basics/native/javaopt/app/com/roli/juce/JuceActivity.java new file mode 100644 index 0000000000..c8db5f74aa --- /dev/null +++ b/modules/juce_gui_basics/native/javaopt/app/com/roli/juce/JuceActivity.java @@ -0,0 +1,20 @@ +package com.roli.juce; + +import android.app.Activity; +import android.content.Intent; + +//============================================================================== +public class JuceActivity extends Activity +{ + //============================================================================== + private native void appNewIntent (Intent intent); + + @Override + protected void onNewIntent (Intent intent) + { + super.onNewIntent(intent); + setIntent(intent); + + appNewIntent (intent); + } +} \ No newline at end of file diff --git a/modules/juce_gui_extra/misc/juce_PushNotifications.h b/modules/juce_gui_extra/misc/juce_PushNotifications.h index 6529a14851..ec98d62495 100644 --- a/modules/juce_gui_extra/misc/juce_PushNotifications.h +++ b/modules/juce_gui_extra/misc/juce_PushNotifications.h @@ -700,11 +700,9 @@ private: #if JUCE_ANDROID friend bool juce_handleNotificationIntent (void*); - friend void juce_firebaseDeviceNotificationsTokenRefreshed (void*); - friend void juce_firebaseRemoteNotificationReceived (void*); - friend void juce_firebaseRemoteMessagesDeleted(); - friend void juce_firebaseRemoteMessageSent (void*); - friend void juce_firebaseRemoteMessageSendError (void*, void*); + + friend struct JuceFirebaseInstanceIdService; + friend struct JuceFirebaseMessagingService; #endif #if JUCE_PUSH_NOTIFICATIONS diff --git a/modules/juce_gui_extra/native/javaopt/app/com/roli/juce/JuceFirebaseInstanceIdService.java b/modules/juce_gui_extra/native/javaopt/app/com/roli/juce/JuceFirebaseInstanceIdService.java new file mode 100644 index 0000000000..9988249dba --- /dev/null +++ b/modules/juce_gui_extra/native/javaopt/app/com/roli/juce/JuceFirebaseInstanceIdService.java @@ -0,0 +1,16 @@ +package com.roli.juce; + +import com.google.firebase.iid.*; + +public final class JuceFirebaseInstanceIdService extends FirebaseInstanceIdService +{ + private native void firebaseInstanceIdTokenRefreshed (String token); + + @Override + public void onTokenRefresh() + { + String token = FirebaseInstanceId.getInstance().getToken(); + + firebaseInstanceIdTokenRefreshed (token); + } +} diff --git a/modules/juce_gui_extra/native/javaopt/app/com/roli/juce/JuceFirebaseMessagingService.java b/modules/juce_gui_extra/native/javaopt/app/com/roli/juce/JuceFirebaseMessagingService.java new file mode 100644 index 0000000000..945440e54c --- /dev/null +++ b/modules/juce_gui_extra/native/javaopt/app/com/roli/juce/JuceFirebaseMessagingService.java @@ -0,0 +1,35 @@ +package com.roli.juce; + +import com.google.firebase.messaging.*; + +public final class JuceFirebaseMessagingService extends FirebaseMessagingService +{ + private native void firebaseRemoteMessageReceived (RemoteMessage message); + private native void firebaseRemoteMessagesDeleted(); + private native void firebaseRemoteMessageSent (String messageId); + private native void firebaseRemoteMessageSendError (String messageId, String error); + + @Override + public void onMessageReceived (RemoteMessage message) + { + firebaseRemoteMessageReceived (message); + } + + @Override + public void onDeletedMessages() + { + firebaseRemoteMessagesDeleted(); + } + + @Override + public void onMessageSent (String messageId) + { + firebaseRemoteMessageSent (messageId); + } + + @Override + public void onSendError (String messageId, Exception e) + { + firebaseRemoteMessageSendError (messageId, e.toString()); + } +} diff --git a/modules/juce_gui_extra/native/juce_android_PushNotifications.cpp b/modules/juce_gui_extra/native/juce_android_PushNotifications.cpp index fffaa11b50..acbbf2e2ac 100644 --- a/modules/juce_gui_extra/native/juce_android_PushNotifications.cpp +++ b/modules/juce_gui_extra/native/juce_android_PushNotifications.cpp @@ -203,8 +203,8 @@ DECLARE_JNI_CLASS_WITH_MIN_SDK (RemoteInputBuilder, "android/app/RemoteInput$Bui #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ STATICMETHOD (getInstance, "getInstance", "()Lcom/google/firebase/messaging/FirebaseMessaging;") \ METHOD (send, "send", "(Lcom/google/firebase/messaging/RemoteMessage;)V") \ - METHOD (subscribeToTopic, "subscribeToTopic", "(Ljava/lang/String;)V") \ - METHOD (unsubscribeFromTopic, "unsubscribeFromTopic", "(Ljava/lang/String;)V") \ + METHOD (subscribeToTopic, "subscribeToTopic", "(Ljava/lang/String;)Lcom/google/android/gms/tasks/Task;") \ + METHOD (unsubscribeFromTopic, "unsubscribeFromTopic", "(Ljava/lang/String;)Lcom/google/android/gms/tasks/Task;") \ DECLARE_JNI_CLASS (FirebaseMessaging, "com/google/firebase/messaging/FirebaseMessaging") #undef JNI_CLASS_MEMBERS @@ -349,7 +349,7 @@ struct PushNotifications::Pimpl void notifyListenersAboutLocalNotification (const LocalRef& intent) { auto* env = getEnv(); - LocalRef context (getAppContext()); + LocalRef context (getMainActivity()); auto bundle = LocalRef (env->CallObjectMethod (intent, AndroidIntent.getExtras)); @@ -461,6 +461,7 @@ struct PushNotifications::Pimpl #endif } + //========================================================================== void subscribeToTopic (const String& topic) { #if defined(JUCE_FIREBASE_MESSAGING_SERVICE_CLASSNAME) @@ -469,7 +470,7 @@ struct PushNotifications::Pimpl auto firebaseMessaging = LocalRef (env->CallStaticObjectMethod (FirebaseMessaging, FirebaseMessaging.getInstance)); - env->CallVoidMethod (firebaseMessaging, FirebaseMessaging.subscribeToTopic, javaString (topic).get()); + env->CallObjectMethod (firebaseMessaging, FirebaseMessaging.subscribeToTopic, javaString (topic).get()); #else ignoreUnused (topic); #endif @@ -483,7 +484,7 @@ struct PushNotifications::Pimpl auto firebaseMessaging = LocalRef (env->CallStaticObjectMethod (FirebaseMessaging, FirebaseMessaging.getInstance)); - env->CallVoidMethod (firebaseMessaging, FirebaseMessaging.unsubscribeFromTopic, javaString (topic).get()); + env->CallObjectMethod (firebaseMessaging, FirebaseMessaging.unsubscribeFromTopic, javaString (topic).get()); #else ignoreUnused (topic); #endif @@ -545,7 +546,7 @@ struct PushNotifications::Pimpl void notifyListenersAboutRemoteNotificationFromService (const LocalRef& remoteNotification) { #if defined(JUCE_FIREBASE_MESSAGING_SERVICE_CLASSNAME) - GlobalRef rn (remoteNotification.get()); + GlobalRef rn (remoteNotification); MessageManager::callAsync ([this, rn] { @@ -570,7 +571,7 @@ struct PushNotifications::Pimpl void notifyListenersAboutUpstreamMessageSent (const LocalRef& messageId) { #if defined(JUCE_FIREBASE_MESSAGING_SERVICE_CLASSNAME) - GlobalRef mid (messageId); + GlobalRef mid (LocalRef(messageId.get())); MessageManager::callAsync ([this, mid] { @@ -586,7 +587,7 @@ struct PushNotifications::Pimpl const LocalRef& error) { #if defined(JUCE_FIREBASE_MESSAGING_SERVICE_CLASSNAME) - GlobalRef mid (messageId), e (error); + GlobalRef mid (LocalRef(messageId.get())), e (LocalRef(error.get())); MessageManager::callAsync ([this, mid, e] { @@ -603,7 +604,7 @@ struct PushNotifications::Pimpl static LocalRef getNotificationManager() { auto* env = getEnv(); - LocalRef context (getAppContext()); + LocalRef context (getMainActivity()); return LocalRef (env->CallObjectMethod (context.get(), AndroidContext.getSystemService, @@ -631,7 +632,7 @@ struct PushNotifications::Pimpl static LocalRef createNotificationBuilder (const PushNotifications::Notification& n) { auto* env = getEnv(); - LocalRef context (getAppContext()); + LocalRef context (getMainActivity()); jclass builderClass = env->FindClass ("android/app/Notification$Builder"); jassert (builderClass != 0); @@ -663,7 +664,7 @@ struct PushNotifications::Pimpl static void setupRequiredFields (const PushNotifications::Notification& n, LocalRef& notificationBuilder) { auto* env = getEnv(); - LocalRef context (getAppContext()); + LocalRef context (getMainActivity()); auto activityClass = LocalRef (env->CallObjectMethod (context.get(), JavaObject.getClass)); auto notifyIntent = LocalRef (env->NewObject (AndroidIntent, AndroidIntent.constructorWithContextAndClass, context.get(), activityClass.get())); @@ -902,7 +903,7 @@ struct PushNotifications::Pimpl LocalRef& notificationBuilder) { auto* env = getEnv(); - LocalRef context (getAppContext()); + LocalRef context (getMainActivity()); auto activityClass = LocalRef (env->CallObjectMethod (context.get(), JavaObject.getClass)); auto deleteIntent = LocalRef (env->NewObject (AndroidIntent, AndroidIntent.constructorWithContextAndClass, context.get(), activityClass.get())); @@ -930,7 +931,7 @@ struct PushNotifications::Pimpl return; auto* env = getEnv(); - LocalRef context (getAppContext()); + LocalRef context (getMainActivity()); int actionIndex = 0; @@ -1025,7 +1026,7 @@ struct PushNotifications::Pimpl static LocalRef juceUrlToAndroidUri (const URL& url) { auto* env = getEnv(); - LocalRef context (getAppContext()); + LocalRef context (getMainActivity()); auto packageNameString = LocalRef ((jstring) (env->CallObjectMethod (context.get(), AndroidContext.getPackageName))); @@ -1351,7 +1352,7 @@ struct PushNotifications::Pimpl dataDynamicObject->setProperty (juceString (key.get()), juceString (value.get())); } - var dataVar (dataDynamicObject); + var dataVar (dataDynamicObject.get()); DynamicObject::Ptr propertiesDynamicObject = new DynamicObject(); propertiesDynamicObject->setProperty ("collapseKey", juceString (collapseKey.get())); @@ -1402,7 +1403,7 @@ struct PushNotifications::Pimpl propertiesDynamicObject->setProperty ("link", link.get() != 0 ? juceString ((jstring) env->CallObjectMethod (link, AndroidUri.toString)) : String()); } - n.properties = var (propertiesDynamicObject); + n.properties = var (propertiesDynamicObject.get()); return n; } @@ -1492,7 +1493,7 @@ struct PushNotifications::Pimpl static bool intentActionContainsAnyOf (jobject intent, const StringArray& strings, bool includePackageName) { auto* env = getEnv(); - LocalRef context (getAppContext()); + LocalRef context (getMainActivity()); String packageName = includePackageName ? juceString ((jstring) env->CallObjectMethod (context.get(), AndroidContext.getPackageName)) @@ -1551,6 +1552,70 @@ struct PushNotifications::Pimpl PushNotifications& owner; }; +#if defined(JUCE_FIREBASE_INSTANCE_ID_SERVICE_CLASSNAME) +//============================================================================== +struct JuceFirebaseInstanceIdService +{ + #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ + CALLBACK (tokenRefreshed, "firebaseInstanceIdTokenRefreshed", "(Ljava/lang/String;)V") + + DECLARE_JNI_CLASS (InstanceIdService, "com/roli/juce/JuceFirebaseInstanceIdService") + #undef JNI_CLASS_MEMBERS + + static void JNICALL tokenRefreshed (void* token) + { + if (auto* instance = PushNotifications::getInstanceWithoutCreating()) + instance->pimpl->notifyListenersTokenRefreshed (juceString (static_cast (token))); + } +}; + +JuceFirebaseInstanceIdService::InstanceIdService_Class JuceFirebaseInstanceIdService::InstanceIdService; +#endif + +#if defined(JUCE_FIREBASE_MESSAGING_SERVICE_CLASSNAME) +//============================================================================== +struct JuceFirebaseMessagingService +{ + #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ + CALLBACK (remoteNotificationReceived, "firebaseRemoteMessageReceived", "(Lcom/google/firebase/messaging/RemoteMessage;)V") \ + CALLBACK (remoteMessagesDeleted, "firebaseRemoteMessagesDeleted", "()V") \ + CALLBACK (remoteMessageSent, "firebaseRemoteMessageSent", "(Ljava/lang/String;)V") \ + CALLBACK (remoteMessageSendError, "firebaseRemoteMessageSendError", "(Ljava/lang/String;Ljava/lang/String;)V") + + DECLARE_JNI_CLASS (MessagingService, "com/roli/juce/JuceFirebaseMessagingService") + #undef JNI_CLASS_MEMBERS + + static void JNICALL remoteNotificationReceived (JNIEnv*, jobject /*messagingService*/, void* remoteMessage) + { + if (auto* instance = PushNotifications::getInstanceWithoutCreating()) + instance->pimpl->notifyListenersAboutRemoteNotificationFromService (LocalRef (static_cast (remoteMessage))); + + } + + static void JNICALL remoteMessagesDeleted() + { + if (auto* instance = PushNotifications::getInstanceWithoutCreating()) + instance->pimpl->notifyListenersAboutRemoteNotificationsDeleted(); + } + + static void JNICALL remoteMessageSent (JNIEnv*, jobject /*messagingService*/, void* messageId) + { + if (auto* instance = PushNotifications::getInstanceWithoutCreating()) + instance->pimpl->notifyListenersAboutUpstreamMessageSent (LocalRef (static_cast (messageId))); + } + + static void JNICALL remoteMessageSendError (JNIEnv*, jobject /*messagingService*/, void* messageId, void* error) + { + if (auto* instance = PushNotifications::getInstanceWithoutCreating()) + instance->pimpl->notifyListenersAboutUpstreamMessageSendingError (LocalRef (static_cast (messageId)), + LocalRef (static_cast (error))); + } +}; + +JuceFirebaseMessagingService::MessagingService_Class JuceFirebaseMessagingService::MessagingService; +#endif + +//============================================================================== bool juce_handleNotificationIntent (void* intent) { auto* instance = PushNotifications::getInstanceWithoutCreating(); @@ -1582,35 +1647,25 @@ bool juce_handleNotificationIntent (void* intent) return false; } -void juce_firebaseDeviceNotificationsTokenRefreshed (void* token) -{ - if (auto* instance = PushNotifications::getInstanceWithoutCreating()) - instance->pimpl->notifyListenersTokenRefreshed (juceString (static_cast (token))); -} - -void juce_firebaseRemoteNotificationReceived (void* remoteMessage) +//============================================================================== +struct JuceActivityNewIntentListener { - if (auto* instance = PushNotifications::getInstanceWithoutCreating()) - instance->pimpl->notifyListenersAboutRemoteNotificationFromService (LocalRef (static_cast (remoteMessage))); -} + #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ + CALLBACK (appNewIntent, "appNewIntent", "(Landroid/content/Intent;)V") -void juce_firebaseRemoteMessagesDeleted() -{ - if (auto* instance = PushNotifications::getInstanceWithoutCreating()) - instance->pimpl->notifyListenersAboutRemoteNotificationsDeleted(); -} + DECLARE_JNI_CLASS (JavaActivity, JUCE_PUSH_NOTIFICATIONS_ACTIVITY) + #undef JNI_CLASS_MEMBERS -void juce_firebaseRemoteMessageSent (void* messageId) -{ - if (auto* instance = PushNotifications::getInstanceWithoutCreating()) - instance->pimpl->notifyListenersAboutUpstreamMessageSent (LocalRef (static_cast (messageId))); -} + static void JNICALL appNewIntent (JNIEnv*, jobject /*activity*/, jobject intentData) + { + #if JUCE_PUSH_NOTIFICATIONS && JUCE_MODULE_AVAILABLE_juce_gui_extra + juce_handleNotificationIntent(static_cast(intentData)); + #else + juce::ignoreUnused(intentData); + #endif + } +}; -void juce_firebaseRemoteMessageSendError (void* messageId, void* error) -{ - if (auto* instance = PushNotifications::getInstanceWithoutCreating()) - instance->pimpl->notifyListenersAboutUpstreamMessageSendingError (LocalRef (static_cast (messageId)), - LocalRef (static_cast (error))); -} +JuceActivityNewIntentListener::JavaActivity_Class JuceActivityNewIntentListener::JavaActivity; } // namespace juce