diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Android.h b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Android.h index 2b46da3a61..918b8866d0 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Android.h +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Android.h @@ -99,8 +99,8 @@ public: androidScreenOrientation, androidCustomActivityClass, androidCustomApplicationClass, androidManifestCustomXmlElements, androidGradleSettingsContent, androidVersionCode, androidMinimumSDK, androidTargetSDK, androidTheme, androidExtraAssetsFolder, androidOboeRepositoryPath, androidInternetNeeded, androidMicNeeded, androidCameraNeeded, androidBluetoothNeeded, androidExternalReadPermission, androidExternalWritePermission, androidInAppBillingPermission, androidVibratePermission, androidOtherPermissions, - androidEnableRemoteNotifications, androidRemoteNotificationsConfigFile, androidEnableContentSharing, androidKeyStore, androidKeyStorePass, androidKeyAlias, androidKeyAliasPass, - gradleVersion, gradleToolchain, androidPluginVersion; + androidPushNotifications, androidEnableRemoteNotifications, androidRemoteNotificationsConfigFile, androidEnableContentSharing, androidKeyStore, androidKeyStorePass, + androidKeyAlias, androidKeyAliasPass, gradleVersion, gradleToolchain, androidPluginVersion; //============================================================================== AndroidProjectExporter (Project& p, const ValueTree& t) @@ -113,7 +113,7 @@ public: androidDependencies (settings, Ids::androidDependencies, getUndoManager()), androidCustomAppBuildGradleContent (settings, Ids::androidCustomAppBuildGradleContent, getUndoManager()), androidScreenOrientation (settings, Ids::androidScreenOrientation, getUndoManager(), "unspecified"), - androidCustomActivityClass (settings, Ids::androidCustomActivityClass, getUndoManager(), getDefaultActivityClass()), + androidCustomActivityClass (settings, Ids::androidCustomActivityClass, getUndoManager()), androidCustomApplicationClass (settings, Ids::androidCustomApplicationClass, getUndoManager(), getDefaultApplicationClass()), androidManifestCustomXmlElements (settings, Ids::androidManifestCustomXmlElements, getUndoManager()), androidGradleSettingsContent (settings, Ids::androidGradleSettingsContent, getUndoManager(), isLibrary() ? "include ':lib'" : "include ':app'"), @@ -132,6 +132,7 @@ public: androidInAppBillingPermission (settings, Ids::androidInAppBilling, getUndoManager(), false), androidVibratePermission (settings, Ids::androidVibratePermissionNeeded, getUndoManager(), false), androidOtherPermissions (settings, Ids::androidOtherPermissions, getUndoManager()), + androidPushNotifications (settings, Ids::androidPushNotifications, getUndoManager(), ! isLibrary()), androidEnableRemoteNotifications (settings, Ids::androidEnableRemoteNotifications, getUndoManager(), false), androidRemoteNotificationsConfigFile (settings, Ids::androidRemoteNotificationsConfigFile, getUndoManager()), androidEnableContentSharing (settings, Ids::androidEnableContentSharing, getUndoManager(), false), @@ -268,12 +269,12 @@ protected: public: AndroidBuildConfiguration (Project& p, const ValueTree& settings, const ProjectExporter& e) : BuildConfiguration (p, settings, e), - androidArchitectures (config, Ids::androidArchitectures, getUndoManager(), isDebug() ? "armeabi-v7a x86 arm64-v8a x86_64" : ""), + androidArchitectures (config, Ids::androidArchitectures, getUndoManager(), isDebug() ? "armeabi-v7a x86 arm64-v8a x86_64" : ""), androidBuildConfigRemoteNotifsConfigFile (config, Ids::androidBuildConfigRemoteNotifsConfigFile, getUndoManager()), - androidAdditionalXmlValueResources (config, Ids::androidAdditionalXmlValueResources, getUndoManager()), - androidAdditionalDrawableResources (config, Ids::androidAdditionalDrawableResources, getUndoManager()), - androidAdditionalRawValueResources (config, Ids::androidAdditionalRawValueResources, getUndoManager()), - androidCustomStringXmlElements (config, Ids::androidCustomStringXmlElements, getUndoManager()) + androidAdditionalXmlValueResources (config, Ids::androidAdditionalXmlValueResources, getUndoManager()), + androidAdditionalDrawableResources (config, Ids::androidAdditionalDrawableResources, getUndoManager()), + androidAdditionalRawValueResources (config, Ids::androidAdditionalRawValueResources, getUndoManager()), + androidCustomStringXmlElements (config, Ids::androidCustomStringXmlElements, getUndoManager()) { linkTimeOptimisationValue.setDefault (false); optimisationLevelValue.setDefault (isDebug() ? gccO0 : gccO3); @@ -562,7 +563,7 @@ private: mo << " dependencies {" << newLine; mo << " classpath 'com.android.tools.build:gradle:" << androidPluginVersion.get().toString() << "'" << newLine; - if (androidEnableRemoteNotifications.get()) + if (areRemoteNotificationsEnabled()) mo << " classpath 'com.google.gms:google-services:4.0.1'" << newLine; mo << " }" << newLine; @@ -780,7 +781,7 @@ private: auto repositories = StringArray::fromLines (androidProjectRepositories.get().toString()); - if (androidEnableRemoteNotifications.get()) + if (areRemoteNotificationsEnabled()) repositories.add ("maven { url \"https://maven.google.com\" }"); mo << " repositories {" << newLine; @@ -823,7 +824,7 @@ private: for (auto& d : StringArray::fromLines (androidJavaLibs.get().toString())) mo << " implementation files('libs/" << File (d).getFileName() << "')" << newLine; - if (androidEnableRemoteNotifications.get()) + if (areRemoteNotificationsEnabled()) { mo << " implementation 'com.google.firebase:firebase-core:16.0.1'" << newLine; mo << " implementation 'com.google.firebase:firebase-messaging:17.6.0'" << newLine; @@ -839,7 +840,7 @@ private: MemoryOutputStream mo; mo.setNewLineString ("\n"); - if (androidEnableRemoteNotifications.get()) + if (areRemoteNotificationsEnabled()) mo << "apply plugin: 'com.google.gms.google-services'" << newLine; return mo.toString(); @@ -889,7 +890,7 @@ private: if (project.getEnabledModules().isModuleEnabled ("juce_gui_basics") && androidCustomActivityClass.get() == getDefaultActivityClass()) addOptJavaFolderToSourceSetsForModule (javaSourceSets, modules, "juce_gui_basics"); - if (androidEnableRemoteNotifications.get()) + if (areRemoteNotificationsEnabled()) addOptJavaFolderToSourceSetsForModule (javaSourceSets, modules, "juce_gui_extra"); MemoryOutputStream mo; @@ -1016,7 +1017,7 @@ 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 default com.roli.juce.JuceActivity. If you specify a custom Activity " + "should be used instead of Android's default Activity. 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."); @@ -1075,9 +1076,13 @@ private: props.add (new TextPropertyComponent (androidOtherPermissions, "Custom Permissions", 2048, false), "A space-separated list of other permission flags that should be added to the manifest."); - props.add (new ChoicePropertyComponent (androidEnableRemoteNotifications, "Remote Notifications"), - "Enable to be able to send remote notifications to devices running your app (min API level 14). Provide Remote Notifications Config File, " - "configure your app in Firebase Console and ensure you have the latest Google Repository in Android Studio's SDK Manager."); + props.add (new ChoicePropertyComponent (androidPushNotifications, "Push Notifications Capability"), + "Enable this to grant your app the capability to receive push notifications."); + + props.add (new ChoicePropertyComponentWithEnablement (androidEnableRemoteNotifications, androidPushNotifications, "Remote Notifications"), + "Enable to be able to send remote notifications to devices running your app (min API level 14). Enable the \"Push Notifications Capability\" " + "setting, provide Remote Notifications Config File, configure your app in Firebase Console and ensure you have the latest Google Repository " + "in Android Studio's SDK Manager."); props.add (new TextPropertyComponent (androidRemoteNotificationsConfigFile.getPropertyAsValue(), "Remote Notifications Config File", 2048, false), "Path to google-services.json file. This will be the file provided by Firebase when creating a new app in Firebase console."); @@ -1144,7 +1149,7 @@ private: copyExtraResourceFiles (cfg.getAdditionalDrawableResources(), drawablesPath); copyExtraResourceFiles (cfg.getAdditionalRawResources(), rawPath); - if (androidEnableRemoteNotifications.get()) + if (areRemoteNotificationsEnabled()) { auto remoteNotifsConfigFilePath = cfg.getRemoteNotifsConfigFile(); @@ -1179,12 +1184,24 @@ private: } } - String getActivityClass() const { return androidCustomActivityClass.get(); } - String getApplicationClass() const { return androidCustomApplicationClass.get(); } + String getActivityClassString() const + { + auto customActivityClass = androidCustomActivityClass.get().toString(); + + if (customActivityClass.isNotEmpty()) + return customActivityClass; + + return arePushNotificationsEnabled() ? getDefaultActivityClass() : "android.app.Activity"; + } + + String getApplicationClassString() const { return androidCustomApplicationClass.get(); } + + bool arePushNotificationsEnabled() const { return androidPushNotifications.get(); } + bool areRemoteNotificationsEnabled() const { return arePushNotificationsEnabled() && androidEnableRemoteNotifications.get(); } String getJNIActivityClassName() const { - return getActivityClass().replaceCharacter ('.', '/'); + return getActivityClassString().replaceCharacter ('.', '/'); } static LibraryModule* getCoreModule (const OwnedArray& modules) @@ -1406,8 +1423,12 @@ 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 (arePushNotificationsEnabled()) + { + 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"); @@ -1415,7 +1436,7 @@ private: if (supportsGLv3()) defines.set ("JUCE_ANDROID_GL_ES_VERSION_3_0", "1"); - if (androidEnableRemoteNotifications.get()) + if (areRemoteNotificationsEnabled()) { defines.set ("JUCE_FIREBASE_INSTANCE_ID_SERVICE_CLASSNAME", "com_roli_juce_JuceFirebaseInstanceIdService"); defines.set ("JUCE_FIREBASE_MESSAGING_SERVICE_CLASSNAME", "com_roli_juce_JuceFirebaseMessagingService"); @@ -1621,7 +1642,7 @@ private: { auto* app = getOrCreateChildWithName (manifest, "application"); setAttributeIfNotPresent (*app, "android:label", "@string/app_name"); - setAttributeIfNotPresent (*app, "android:name", getApplicationClass()); + setAttributeIfNotPresent (*app, "android:name", getApplicationClassString()); if (androidTheme.get().toString().isNotEmpty()) setAttributeIfNotPresent (*app, "android:theme", androidTheme.get()); @@ -1651,7 +1672,7 @@ private: { auto* act = getOrCreateChildWithName (application, "activity"); - setAttributeIfNotPresent (*act, "android:name", getActivityClass()); + setAttributeIfNotPresent (*act, "android:name", getActivityClassString()); setAttributeIfNotPresent (*act, "android:label", "@string/app_name"); if (! act->hasAttribute ("android:configChanges")) @@ -1720,7 +1741,7 @@ private: void createServiceElements (XmlElement& application) const { - if (androidEnableRemoteNotifications.get()) + if (areRemoteNotificationsEnabled()) { auto* service = application.createNewChildElement ("service"); service->setAttribute ("android:name", "com.roli.juce.JuceFirebaseMessagingService"); diff --git a/extras/Projucer/Source/Utility/Helpers/jucer_PresetIDs.h b/extras/Projucer/Source/Utility/Helpers/jucer_PresetIDs.h index 7ef65d834c..1b6ad20229 100644 --- a/extras/Projucer/Source/Utility/Helpers/jucer_PresetIDs.h +++ b/extras/Projucer/Source/Utility/Helpers/jucer_PresetIDs.h @@ -223,6 +223,7 @@ namespace Ids DECLARE_ID (androidExternalWriteNeeded); DECLARE_ID (androidInAppBilling); DECLARE_ID (androidVibratePermissionNeeded); + DECLARE_ID (androidPushNotifications); DECLARE_ID (androidEnableRemoteNotifications); DECLARE_ID (androidRemoteNotificationsConfigFile); DECLARE_ID (androidEnableContentSharing); diff --git a/extras/Projucer/Source/Utility/UI/PropertyComponents/jucer_PropertyComponentsWithEnablement.h b/extras/Projucer/Source/Utility/UI/PropertyComponents/jucer_PropertyComponentsWithEnablement.h index 490b520602..2137e620f3 100644 --- a/extras/Projucer/Source/Utility/UI/PropertyComponents/jucer_PropertyComponentsWithEnablement.h +++ b/extras/Projucer/Source/Utility/UI/PropertyComponents/jucer_PropertyComponentsWithEnablement.h @@ -88,6 +88,17 @@ public: valueChanged (value); } + ChoicePropertyComponentWithEnablement (ValueWithDefault& valueToControl, + ValueWithDefault valueToListenTo, + const String& propertyName) + : ChoicePropertyComponent (valueToControl, propertyName), + valueWithDefault (valueToListenTo), + value (valueToListenTo.getPropertyAsValue()) + { + value.addListener (this); + valueChanged (value); + } + ~ChoicePropertyComponentWithEnablement() override { value.removeListener (this); } private: