diff --git a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Android.h b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Android.h index ddc2402b25..cbe1346ecd 100644 --- a/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Android.h +++ b/extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Android.h @@ -1804,7 +1804,10 @@ private: StringArray s = StringArray::fromTokens (androidOtherPermissions.get().toString(), ", ", {}); if (androidInternetNeeded.get()) + { s.add ("android.permission.INTERNET"); + s.add ("android.permission.CHANGE_WIFI_MULTICAST_STATE"); + } if (androidMicNeeded.get()) s.add ("android.permission.RECORD_AUDIO"); diff --git a/modules/juce_core/native/juce_android_Network.cpp b/modules/juce_core/native/juce_android_Network.cpp index 83e8522d0a..8808d1707e 100644 --- a/modules/juce_core/native/juce_android_Network.cpp +++ b/modules/juce_core/native/juce_android_Network.cpp @@ -213,6 +213,62 @@ DECLARE_JNI_CLASS_WITH_BYTECODE (HTTPStream, "com/roli/juce/JuceHTTPStream", 16, DECLARE_JNI_CLASS (AndroidInputStream, "java/io/InputStream") #undef JNI_CLASS_MEMBERS +//============================================================================== +#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ + METHOD (acquire, "acquire", "()V") \ + METHOD (release, "release", "()V") \ + +DECLARE_JNI_CLASS (AndroidMulticastLock, "android/net/wifi/WifiManager$MulticastLock") +#undef JNI_CLASS_MEMBERS + +#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \ + METHOD (createMulticastLock, "createMulticastLock", "(Ljava/lang/String;)Landroid/net/wifi/WifiManager$MulticastLock;") \ + +DECLARE_JNI_CLASS (AndroidWifiManager, "android/net/wifi/WifiManager") +#undef JNI_CLASS_MEMBERS + +static LocalRef getMulticastLock() +{ + static LocalRef multicastLock; + static bool hasChecked = false; + + if (! hasChecked) + { + hasChecked = true; + + auto* env = getEnv(); + + LocalRef wifiManager (env->CallObjectMethod (getAppContext().get(), + AndroidContext.getSystemService, + javaString ("wifi").get())); + + if (wifiManager != nullptr) + { + multicastLock = LocalRef (env->CallObjectMethod (wifiManager.get(), + AndroidWifiManager.createMulticastLock, + javaString ("JUCE_MulticastLock").get())); + } + } + + return multicastLock; +} + +JUCE_API void JUCE_CALLTYPE acquireMulticastLock() +{ + auto multicastLock = getMulticastLock(); + + if (multicastLock != nullptr) + getEnv()->CallVoidMethod (multicastLock.get(), AndroidMulticastLock.acquire); +} + +JUCE_API void JUCE_CALLTYPE releaseMulticastLock() +{ + auto multicastLock = getMulticastLock(); + + if (multicastLock != nullptr) + getEnv()->CallVoidMethod (multicastLock.get(), AndroidMulticastLock.release); +} + //============================================================================== void MACAddress::findAllAddresses (Array& /*result*/) { diff --git a/modules/juce_events/interprocess/juce_NetworkServiceDiscovery.cpp b/modules/juce_events/interprocess/juce_NetworkServiceDiscovery.cpp index 3175ad06a4..f2ddcc5c4a 100644 --- a/modules/juce_events/interprocess/juce_NetworkServiceDiscovery.cpp +++ b/modules/juce_events/interprocess/juce_NetworkServiceDiscovery.cpp @@ -23,6 +23,11 @@ namespace juce { +#if JUCE_ANDROID + extern void acquireMulticastLock(); + extern void releaseMulticastLock(); +#endif + NetworkServiceDiscovery::Advertiser::Advertiser (const String& serviceTypeUID, const String& serviceDescription, int broadcastPortToUse, int connectionPort, @@ -73,6 +78,10 @@ void NetworkServiceDiscovery::Advertiser::sendBroadcast() NetworkServiceDiscovery::AvailableServiceList::AvailableServiceList (const String& serviceType, int broadcastPort) : Thread ("Discovery_listen"), serviceTypeUID (serviceType) { + #if JUCE_ANDROID + acquireMulticastLock(); + #endif + socket.bindToPort (broadcastPort); startThread (2); } @@ -81,6 +90,10 @@ NetworkServiceDiscovery::AvailableServiceList::~AvailableServiceList() { socket.shutdown(); stopThread (2000); + + #if JUCE_ANDROID + releaseMulticastLock(); + #endif } void NetworkServiceDiscovery::AvailableServiceList::run()