diff --git a/modules/juce_audio_devices/native/juce_HighPerformanceAudioHelpers_android.h b/modules/juce_audio_devices/native/juce_HighPerformanceAudioHelpers_android.h index 997557084a..f76b72020d 100644 --- a/modules/juce_audio_devices/native/juce_HighPerformanceAudioHelpers_android.h +++ b/modules/juce_audio_devices/native/juce_HighPerformanceAudioHelpers_android.h @@ -84,10 +84,8 @@ namespace juce::AndroidHighPerformanceAudioHelpers if (canUseHighPerformanceAudioPath (nativeBufferSize, nativeBufferSize, (int) requestedSampleRate)) { // see https://developer.android.com/ndk/guides/audio/opensl/opensl-prog-notes.html#sandp - // "For Android 4.2 (API level 17) and earlier, a buffer count of two or more is required - // for lower latency. Beginning with Android 4.3 (API level 18), a buffer count of one - // is sufficient for lower latency." - return (getAndroidSDKVersion() >= 18 ? 1 : 2); + // > Beginning with Android 4.3 (API level 18), a buffer count of one is sufficient for lower latency. + return 1; } // not using low-latency path so we can use the absolute minimum number of buffers to queue diff --git a/modules/juce_audio_devices/native/juce_Oboe_android.cpp b/modules/juce_audio_devices/native/juce_Oboe_android.cpp index fbd3e935ed..2e49a99681 100644 --- a/modules/juce_audio_devices/native/juce_Oboe_android.cpp +++ b/modules/juce_audio_devices/native/juce_Oboe_android.cpp @@ -398,7 +398,7 @@ private: oboe::Direction::Output, oboe::SharingMode::Exclusive, 2, - getAndroidSDKVersion() >= 21 ? oboe::AudioFormat::Float : oboe::AudioFormat::I16, + oboe::AudioFormat::Float, (int) AndroidHighPerformanceAudioHelpers::getNativeSampleRate(), bufferSizeHint, &callback); @@ -1023,19 +1023,18 @@ OboeAudioIODevice::OboeSessionBase* OboeAudioIODevice::OboeSessionBase::create ( int bufferSize) { - std::unique_ptr session; - auto sdkVersion = getAndroidSDKVersion(); - // SDK versions 21 and higher should natively support floating point... - if (sdkVersion >= 21) - { - session.reset (new OboeSessionImpl (owner, inputDeviceId, outputDeviceId, - numInputChannels, numOutputChannels, sampleRate, bufferSize)); + std::unique_ptr session = std::make_unique> (owner, + inputDeviceId, + outputDeviceId, + numInputChannels, + numOutputChannels, + sampleRate, + bufferSize); - // ...however, some devices lie so re-try without floating point - if (session != nullptr && (! session->openedOk())) - session.reset(); - } + // ...however, some devices lie so re-try without floating point + if (session != nullptr && (! session->openedOk())) + session.reset(); if (session == nullptr) { diff --git a/modules/juce_core/native/juce_AndroidDocument_android.cpp b/modules/juce_core/native/juce_AndroidDocument_android.cpp index f1f4d0aaba..6282ea6a67 100644 --- a/modules/juce_core/native/juce_AndroidDocument_android.cpp +++ b/modules/juce_core/native/juce_AndroidDocument_android.cpp @@ -218,9 +218,6 @@ struct AndroidDocumentDetail static void setPermissions (const URL& url, jmethodID func) { - if (getAndroidSDKVersion() < 19) - return; - const auto javaUri = urlToUri (url); if (const auto resolver = AndroidContentUriResolver::getContentResolver()) @@ -402,19 +399,18 @@ struct AndroidDocument::Utils AndroidMimeTypeMap.getSingleton) } }; }; - class AndroidDocumentPimplApi19 : public Pimpl + //============================================================================== + class AndroidDocumentPimplApi21 : public Pimpl { public: - AndroidDocumentPimplApi19() = default; + AndroidDocumentPimplApi21() = default; - explicit AndroidDocumentPimplApi19 (const URL& uriIn) - : AndroidDocumentPimplApi19 (urlToUri (uriIn)) {} + explicit AndroidDocumentPimplApi21 (const URL& uriIn) + : AndroidDocumentPimplApi21 (urlToUri (uriIn)) {} - explicit AndroidDocumentPimplApi19 (const LocalRef& uriIn) + explicit AndroidDocumentPimplApi21 (const LocalRef& uriIn) : uri (uriIn) {} - std::unique_ptr clone() const override { return std::make_unique (*this); } - bool deleteDocument() const override { if (const auto resolver = AndroidContentUriResolver::getContentResolver()) @@ -523,16 +519,6 @@ struct AndroidDocument::Utils NativeInfo getNativeInfo() const override { return { uri }; } - private: - GlobalRef uri; - }; - - //============================================================================== - class AndroidDocumentPimplApi21 : public AndroidDocumentPimplApi19 - { - public: - using AndroidDocumentPimplApi19::AndroidDocumentPimplApi19; - std::unique_ptr clone() const override { return std::make_unique (*this); } std::unique_ptr createChildDocumentWithTypeAndName (const String& type, const String& name) const override @@ -558,6 +544,9 @@ struct AndroidDocument::Utils return nullptr; } + + private: + GlobalRef uri; }; //============================================================================== @@ -607,8 +596,7 @@ struct AndroidDocument::Utils return createPimplForSdkImpl (uri, VersionTag { 24 }, - VersionTag { 21 }, - VersionTag { 19 }); + VersionTag { 21 }); } static std::unique_ptr createPimplForSdkImpl (const LocalRef&) @@ -777,9 +765,6 @@ std::vector AndroidDocumentPermission::getPersistedPe #if ! JUCE_ANDROID return {}; #else - if (getAndroidSDKVersion() < 19) - return {}; - auto* env = getEnv(); const LocalRef permissions { env->CallObjectMethod (AndroidContentUriResolver::getContentResolver().get(), ContentResolver19.getPersistedUriPermissions) }; @@ -829,13 +814,6 @@ AndroidDocument AndroidDocument::fromFile (const File& filePath) AndroidDocument AndroidDocument::fromDocument ([[maybe_unused]] const URL& documentUrl) { #if JUCE_ANDROID - if (getAndroidSDKVersion() < 19) - { - // This function is unsupported on this platform. - jassertfalse; - return AndroidDocument{}; - } - const auto javaUri = urlToUri (documentUrl); if (! getEnv()->CallStaticBooleanMethod (DocumentsContract19, @@ -855,13 +833,6 @@ AndroidDocument AndroidDocument::fromDocument ([[maybe_unused]] const URL& docum AndroidDocument AndroidDocument::fromTree ([[maybe_unused]] const URL& treeUrl) { #if JUCE_ANDROID - if (getAndroidSDKVersion() < 21) - { - // This function is unsupported on this platform. - jassertfalse; - return AndroidDocument{}; - } - const auto javaUri = urlToUri (treeUrl); LocalRef treeDocumentId { getEnv()->CallStaticObjectMethod (DocumentsContract21, DocumentsContract21.getTreeDocumentId, @@ -1042,7 +1013,7 @@ AndroidDocumentIterator AndroidDocumentIterator::makeNonRecursive (const Android using Detail = AndroidDocumentDetail; #if JUCE_ANDROID - if (21 <= getAndroidSDKVersion()) + if (getAndroidSDKVersion() == 21) { if (auto uri = dir.getNativeInfo().uri) return Utils::makeWithEngine (Detail::makeDocumentsContractIteratorEngine (uri)); @@ -1060,7 +1031,7 @@ AndroidDocumentIterator AndroidDocumentIterator::makeRecursive (const AndroidDoc using Detail = AndroidDocumentDetail; #if JUCE_ANDROID - if (21 <= getAndroidSDKVersion()) + if (getAndroidSDKVersion() == 21) { if (auto uri = dir.getNativeInfo().uri) return Utils::makeWithEngine (Detail::RecursiveEngine { uri }); diff --git a/modules/juce_core/native/juce_Files_android.cpp b/modules/juce_core/native/juce_Files_android.cpp index 3d35ee5be5..5e7885ce74 100644 --- a/modules/juce_core/native/juce_Files_android.cpp +++ b/modules/juce_core/native/juce_Files_android.cpp @@ -359,45 +359,18 @@ private: static Array getSecondaryStorageDirectories() { + auto* env = getEnv(); + static jmethodID m = (env->GetMethodID (AndroidContext, "getExternalFilesDirs", + "(Ljava/lang/String;)[Ljava/io/File;")); + if (m == nullptr) + return {}; + + auto paths = convertFileArray (LocalRef (env->CallObjectMethod (getAppContext().get(), m, nullptr))); + Array results; - if (getAndroidSDKVersion() >= 19) - { - auto* env = getEnv(); - static jmethodID m = (env->GetMethodID (AndroidContext, "getExternalFilesDirs", - "(Ljava/lang/String;)[Ljava/io/File;")); - if (m == nullptr) - return {}; - - auto paths = convertFileArray (LocalRef (env->CallObjectMethod (getAppContext().get(), m, nullptr))); - - for (auto path : paths) - results.add (getMountPointForFile (path)); - } - else - { - // on older SDKs other external storages are located "next" to the primary - // storage mount point - auto mountFolder = getMountPointForFile (getPrimaryStorageDirectory()) - .getParentDirectory(); - - // don't include every folder. Only folders which are actually mountpoints - juce_statStruct info; - if (! juce_stat (mountFolder.getFullPathName(), info)) - return {}; - - auto rootFsDevice = info.st_dev; - - for (const auto& iter : RangedDirectoryIterator (mountFolder, false, "*", File::findDirectories)) - { - auto candidate = iter.getFile(); - - if (juce_stat (candidate.getFullPathName(), info) - && info.st_dev != rootFsDevice) - results.add (candidate); - } - - } + for (auto path : paths) + results.add (getMountPointForFile (path)); return results; } @@ -827,12 +800,7 @@ String File::getVersion() const static File getDocumentsDirectory() { - auto* env = getEnv(); - - if (getAndroidSDKVersion() >= 19) - return getWellKnownFolder ("DIRECTORY_DOCUMENTS"); - - return juceFile (LocalRef (env->CallStaticObjectMethod (AndroidEnvironment, AndroidEnvironment.getDataDirectory))); + return getWellKnownFolder ("DIRECTORY_DOCUMENTS"); } static File getAppDataDir (bool dataDir) diff --git a/modules/juce_core/native/juce_JNIHelpers_android.cpp b/modules/juce_core/native/juce_JNIHelpers_android.cpp index 23a57c80b1..dd8d55147f 100644 --- a/modules/juce_core/native/juce_JNIHelpers_android.cpp +++ b/modules/juce_core/native/juce_JNIHelpers_android.cpp @@ -680,23 +680,20 @@ bool androidHasSystemFeature (const String& property) String audioManagerGetProperty (const String& property) { - if (getAndroidSDKVersion() >= 17) + auto* env = getEnv(); + LocalRef audioManager (env->CallObjectMethod (getAppContext().get(), AndroidContext.getSystemService, + javaString ("audio").get())); + + if (audioManager != nullptr) { - auto* env = getEnv(); - LocalRef audioManager (env->CallObjectMethod (getAppContext().get(), AndroidContext.getSystemService, - javaString ("audio").get())); + LocalRef jProperty (javaString (property)); - if (audioManager != nullptr) - { - LocalRef jProperty (javaString (property)); + auto methodID = env->GetMethodID (AndroidAudioManager, "getProperty", "(Ljava/lang/String;)Ljava/lang/String;"); - auto methodID = env->GetMethodID (AndroidAudioManager, "getProperty", "(Ljava/lang/String;)Ljava/lang/String;"); - - if (methodID != nullptr) - return juceString (LocalRef ((jstring) env->CallObjectMethod (audioManager.get(), - methodID, - javaString (property).get()))); - } + if (methodID != nullptr) + return juceString (LocalRef ((jstring) env->CallObjectMethod (audioManager.get(), + methodID, + javaString (property).get()))); } return {}; diff --git a/modules/juce_gui_basics/native/accessibility/juce_Accessibility_android.cpp b/modules/juce_gui_basics/native/accessibility/juce_Accessibility_android.cpp index c657db3775..4ab7bd9db8 100644 --- a/modules/juce_gui_basics/native/accessibility/juce_Accessibility_android.cpp +++ b/modules/juce_gui_basics/native/accessibility/juce_Accessibility_android.cpp @@ -160,19 +160,12 @@ static void loadSDKDependentMethods() hasChecked = true; auto* env = getEnv(); - const auto sdkVersion = getAndroidSDKVersion(); - if (sdkVersion >= 18) - { - nodeInfoSetEditable = env->GetMethodID (AndroidAccessibilityNodeInfo, "setEditable", "(Z)V"); - nodeInfoSetTextSelection = env->GetMethodID (AndroidAccessibilityNodeInfo, "setTextSelection", "(II)V"); - } + nodeInfoSetEditable = env->GetMethodID (AndroidAccessibilityNodeInfo, "setEditable", "(Z)V"); + nodeInfoSetTextSelection = env->GetMethodID (AndroidAccessibilityNodeInfo, "setTextSelection", "(II)V"); - if (sdkVersion >= 19) - { - nodeInfoSetLiveRegion = env->GetMethodID (AndroidAccessibilityNodeInfo, "setLiveRegion", "(I)V"); - accessibilityEventSetContentChangeTypes = env->GetMethodID (AndroidAccessibilityEvent, "setContentChangeTypes", "(I)V"); - } + nodeInfoSetLiveRegion = env->GetMethodID (AndroidAccessibilityNodeInfo, "setLiveRegion", "(I)V"); + accessibilityEventSetContentChangeTypes = env->GetMethodID (AndroidAccessibilityEvent, "setContentChangeTypes", "(I)V"); } } @@ -498,58 +491,55 @@ public: } } - if (getAndroidSDKVersion() >= 19) + if (auto* tableInterface = accessibilityHandler.getTableInterface()) { - if (auto* tableInterface = accessibilityHandler.getTableInterface()) + const auto rows = tableInterface->getNumRows(); + const auto columns = tableInterface->getNumColumns(); + const LocalRef collectionInfo { env->CallStaticObjectMethod (AndroidAccessibilityNodeInfoCollectionInfo, + AndroidAccessibilityNodeInfoCollectionInfo.obtain, + (jint) rows, + (jint) columns, + (jboolean) false) }; + env->CallVoidMethod (info, AndroidAccessibilityNodeInfo19.setCollectionInfo, collectionInfo.get()); + } + + if (auto* enclosingTableHandler = detail::AccessibilityHelpers::getEnclosingHandlerWithInterface (&accessibilityHandler, &AccessibilityHandler::getTableInterface)) + { + auto* interface = enclosingTableHandler->getTableInterface(); + jassert (interface != nullptr); + const auto rowSpan = interface->getRowSpan (accessibilityHandler); + const auto columnSpan = interface->getColumnSpan (accessibilityHandler); + + enum class IsHeader { no, yes }; + + const auto addCellInfo = [env, &info] (AccessibilityTableInterface::Span rows, AccessibilityTableInterface::Span columns, IsHeader header) { - const auto rows = tableInterface->getNumRows(); - const auto columns = tableInterface->getNumColumns(); - const LocalRef collectionInfo { env->CallStaticObjectMethod (AndroidAccessibilityNodeInfoCollectionInfo, - AndroidAccessibilityNodeInfoCollectionInfo.obtain, - (jint) rows, - (jint) columns, - (jboolean) false) }; - env->CallVoidMethod (info, AndroidAccessibilityNodeInfo19.setCollectionInfo, collectionInfo.get()); + const LocalRef collectionItemInfo { env->CallStaticObjectMethod (AndroidAccessibilityNodeInfoCollectionItemInfo, + AndroidAccessibilityNodeInfoCollectionItemInfo.obtain, + (jint) rows.begin, + (jint) rows.num, + (jint) columns.begin, + (jint) columns.num, + (jboolean) (header == IsHeader::yes)) }; + env->CallVoidMethod (info, AndroidAccessibilityNodeInfo19.setCollectionItemInfo, collectionItemInfo.get()); + }; + + if (rowSpan.hasValue() && columnSpan.hasValue()) + { + addCellInfo (*rowSpan, *columnSpan, IsHeader::no); } - - if (auto* enclosingTableHandler = detail::AccessibilityHelpers::getEnclosingHandlerWithInterface (&accessibilityHandler, &AccessibilityHandler::getTableInterface)) + else { - auto* interface = enclosingTableHandler->getTableInterface(); - jassert (interface != nullptr); - const auto rowSpan = interface->getRowSpan (accessibilityHandler); - const auto columnSpan = interface->getColumnSpan (accessibilityHandler); - - enum class IsHeader { no, yes }; - - const auto addCellInfo = [env, &info] (AccessibilityTableInterface::Span rows, AccessibilityTableInterface::Span columns, IsHeader header) + if (auto* tableHeader = interface->getHeaderHandler()) { - const LocalRef collectionItemInfo { env->CallStaticObjectMethod (AndroidAccessibilityNodeInfoCollectionItemInfo, - AndroidAccessibilityNodeInfoCollectionItemInfo.obtain, - (jint) rows.begin, - (jint) rows.num, - (jint) columns.begin, - (jint) columns.num, - (jboolean) (header == IsHeader::yes)) }; - env->CallVoidMethod (info, AndroidAccessibilityNodeInfo19.setCollectionItemInfo, collectionItemInfo.get()); - }; - - if (rowSpan.hasValue() && columnSpan.hasValue()) - { - addCellInfo (*rowSpan, *columnSpan, IsHeader::no); - } - else - { - if (auto* tableHeader = interface->getHeaderHandler()) + if (accessibilityHandler.getParent() == tableHeader) { - if (accessibilityHandler.getParent() == tableHeader) - { - const auto children = tableHeader->getChildren(); - const auto column = std::distance (children.cbegin(), std::find (children.cbegin(), children.cend(), &accessibilityHandler)); + const auto children = tableHeader->getChildren(); + const auto column = std::distance (children.cbegin(), std::find (children.cbegin(), children.cend(), &accessibilityHandler)); - // Talkback will only treat a row as a column header if its row index is zero - // https://github.com/google/talkback/blob/acd0bc7631a3dfbcf183789c7557596a45319e1f/utils/src/main/java/CollectionState.java#L853 - addCellInfo ({ 0, 1 }, { (int) column, 1 }, IsHeader::yes); - } + // Talkback will only treat a row as a column header if its row index is zero + // https://github.com/google/talkback/blob/acd0bc7631a3dfbcf183789c7557596a45319e1f/utils/src/main/java/CollectionState.java#L853 + addCellInfo ({ 0, 1 }, { (int) column, 1 }, IsHeader::yes); } } } diff --git a/modules/juce_gui_basics/native/juce_ContentSharer_android.cpp b/modules/juce_gui_basics/native/juce_ContentSharer_android.cpp index d2c6178013..2f25098ed1 100644 --- a/modules/juce_gui_basics/native/juce_ContentSharer_android.cpp +++ b/modules/juce_gui_basics/native/juce_ContentSharer_android.cpp @@ -288,9 +288,6 @@ public: constexpr int grantReadUriPermission = 1; constexpr int grantPrefixUriPermission = 128; - if (getAndroidSDKVersion() < 21) - return grantReadUriPermission; - return grantReadUriPermission | grantPrefixUriPermission; }; diff --git a/modules/juce_gui_basics/native/juce_FileChooser_android.cpp b/modules/juce_gui_basics/native/juce_FileChooser_android.cpp index b79ab45d6b..6869d59ae9 100644 --- a/modules/juce_gui_basics/native/juce_FileChooser_android.cpp +++ b/modules/juce_gui_basics/native/juce_FileChooser_android.cpp @@ -59,7 +59,6 @@ public: currentFileChooser = this; auto* env = getEnv(); - auto sdkVersion = getAndroidSDKVersion(); auto saveMode = ((flags & FileBrowserComponent::saveMode) != 0); auto selectsDirectories = ((flags & FileBrowserComponent::canSelectDirectories) != 0); auto canSelectMultiple = ((flags & FileBrowserComponent::canSelectMultipleItems) != 0); @@ -67,24 +66,9 @@ public: // You cannot save a directory jassert (! (saveMode && selectsDirectories)); - if (sdkVersion < 19) - { - // native save dialogs are only supported in Android versions >= 19 - jassert (! saveMode); - saveMode = false; - } - - if (sdkVersion < 21) - { - // native directory chooser dialogs are only supported in Android versions >= 21 - jassert (! selectsDirectories); - selectsDirectories = false; - } - const char* action = (selectsDirectories ? "android.intent.action.OPEN_DOCUMENT_TREE" : (saveMode ? "android.intent.action.CREATE_DOCUMENT" - : (sdkVersion >= 19 ? "android.intent.action.OPEN_DOCUMENT" - : "android.intent.action.GET_CONTENT"))); + : "android.intent.action.OPEN_DOCUMENT")); intent = GlobalRef (LocalRef (env->NewObject (AndroidIntent, AndroidIntent.constructWithString, @@ -108,13 +92,10 @@ public: uri.get()); } - if (canSelectMultiple && sdkVersion >= 18) - { - env->CallObjectMethod (intent.get(), - AndroidIntent.putExtraBool, - javaString ("android.intent.extra.ALLOW_MULTIPLE").get(), - true); - } + env->CallObjectMethod (intent.get(), + AndroidIntent.putExtraBool, + javaString ("android.intent.extra.ALLOW_MULTIPLE").get(), + canSelectMultiple); if (! selectsDirectories) { diff --git a/modules/juce_gui_extra/native/juce_PushNotifications_android.cpp b/modules/juce_gui_extra/native/juce_PushNotifications_android.cpp index 455bfecd4d..1d77f03554 100644 --- a/modules/juce_gui_extra/native/juce_PushNotifications_android.cpp +++ b/modules/juce_gui_extra/native/juce_PushNotifications_android.cpp @@ -383,7 +383,7 @@ struct PushNotifications::Pimpl owner.listeners.call ([&] (Listener& l) { l.handleNotificationAction (true, notification, actionTitle, {}); }); } - else if (getAndroidSDKVersion() >= 20 && actionString.contains (notificationTextInputActionString)) + else if (actionString.contains (notificationTextInputActionString)) { auto prefix = notificationTextInputActionString + notification.identifier + "."; @@ -613,10 +613,7 @@ struct PushNotifications::Pimpl if (n.actions.size() > 0) setupActions (n, notificationBuilder); - if (getAndroidSDKVersion() >= 16) - return LocalRef (env->CallObjectMethod (notificationBuilder, NotificationBuilderApi16.build)); - - return LocalRef (env->CallObjectMethod (notificationBuilder, NotificationBuilderBase.getNotification)); + return LocalRef (env->CallObjectMethod (notificationBuilder, NotificationBuilderApi16.build)); } static LocalRef createNotificationBuilder (const PushNotifications::Notification& n) @@ -684,7 +681,7 @@ struct PushNotifications::Pimpl env->CallObjectMethod (notificationBuilder, NotificationBuilderBase.setSmallIcon, iconId); - if (getAndroidSDKVersion() >= 21 && n.publicVersion != nullptr) + if (n.publicVersion != nullptr) { // Public version of a notification is not expected to have another public one! jassert (n.publicVersion->publicVersion == nullptr); @@ -814,61 +811,49 @@ struct PushNotifications::Pimpl env->CallObjectMethod (notificationBuilder, NotificationBuilderBase.setOngoing, n.ongoing); env->CallObjectMethod (notificationBuilder, NotificationBuilderBase.setOnlyAlertOnce, n.alertOnlyOnce); - if (getAndroidSDKVersion() >= 16) + if (n.subtitle.isNotEmpty()) + env->CallObjectMethod (notificationBuilder, NotificationBuilderApi16.setSubText, javaString (n.subtitle).get()); + + env->CallObjectMethod (notificationBuilder, NotificationBuilderApi16.setPriority, n.priority); + + if (getAndroidSDKVersion() < 24) { - if (n.subtitle.isNotEmpty()) - env->CallObjectMethod (notificationBuilder, NotificationBuilderApi16.setSubText, javaString (n.subtitle).get()); - - env->CallObjectMethod (notificationBuilder, NotificationBuilderApi16.setPriority, n.priority); - - if (getAndroidSDKVersion() < 24) - { - const bool useChronometer = n.timestampVisibility == PushNotifications::Notification::chronometer; - env->CallObjectMethod (notificationBuilder, NotificationBuilderApi16.setUsesChronometer, useChronometer); - } + const bool useChronometer = n.timestampVisibility == PushNotifications::Notification::chronometer; + env->CallObjectMethod (notificationBuilder, NotificationBuilderApi16.setUsesChronometer, useChronometer); } - if (getAndroidSDKVersion() >= 17) + const bool showTimeStamp = n.timestampVisibility != PushNotifications::Notification::off; + env->CallObjectMethod (notificationBuilder, NotificationBuilderApi17.setShowWhen, showTimeStamp); + + if (n.groupId.isNotEmpty()) { - const bool showTimeStamp = n.timestampVisibility != PushNotifications::Notification::off; - env->CallObjectMethod (notificationBuilder, NotificationBuilderApi17.setShowWhen, showTimeStamp); + env->CallObjectMethod (notificationBuilder, NotificationBuilderApi20.setGroup, javaString (n.groupId).get()); + env->CallObjectMethod (notificationBuilder, NotificationBuilderApi20.setGroupSummary, n.groupSummary); } - if (getAndroidSDKVersion() >= 20) - { - if (n.groupId.isNotEmpty()) - { - env->CallObjectMethod (notificationBuilder, NotificationBuilderApi20.setGroup, javaString (n.groupId).get()); - env->CallObjectMethod (notificationBuilder, NotificationBuilderApi20.setGroupSummary, n.groupSummary); - } + if (n.groupSortKey.isNotEmpty()) + env->CallObjectMethod (notificationBuilder, NotificationBuilderApi20.setSortKey, javaString (n.groupSortKey).get()); - if (n.groupSortKey.isNotEmpty()) - env->CallObjectMethod (notificationBuilder, NotificationBuilderApi20.setSortKey, javaString (n.groupSortKey).get()); + env->CallObjectMethod (notificationBuilder, NotificationBuilderApi20.setLocalOnly, n.localOnly); - env->CallObjectMethod (notificationBuilder, NotificationBuilderApi20.setLocalOnly, n.localOnly); + auto extras = LocalRef (env->NewObject (AndroidBundle, AndroidBundle.constructor)); - auto extras = LocalRef (env->NewObject (AndroidBundle, AndroidBundle.constructor)); + env->CallVoidMethod (extras, AndroidBundle.putBundle, javaString ("notificationData").get(), + juceNotificationToBundle (n).get()); - env->CallVoidMethod (extras, AndroidBundle.putBundle, javaString ("notificationData").get(), - juceNotificationToBundle (n).get()); + env->CallObjectMethod (notificationBuilder, NotificationBuilderApi20.addExtras, extras.get()); - env->CallObjectMethod (notificationBuilder, NotificationBuilderApi20.addExtras, extras.get()); - } + if (n.person.isNotEmpty()) + env->CallObjectMethod (notificationBuilder, NotificationBuilderApi21.addPerson, javaString (n.person).get()); - if (getAndroidSDKVersion() >= 21) - { - if (n.person.isNotEmpty()) - env->CallObjectMethod (notificationBuilder, NotificationBuilderApi21.addPerson, javaString (n.person).get()); + auto categoryString = typeToCategory (n.type); + if (categoryString.isNotEmpty()) + env->CallObjectMethod (notificationBuilder, NotificationBuilderApi21.setCategory, javaString (categoryString).get()); - auto categoryString = typeToCategory (n.type); - if (categoryString.isNotEmpty()) - env->CallObjectMethod (notificationBuilder, NotificationBuilderApi21.setCategory, javaString (categoryString).get()); + if (n.accentColour != Colour()) + env->CallObjectMethod (notificationBuilder, NotificationBuilderApi21.setColor, n.accentColour.getARGB()); - if (n.accentColour != Colour()) - env->CallObjectMethod (notificationBuilder, NotificationBuilderApi21.setColor, n.accentColour.getARGB()); - - env->CallObjectMethod (notificationBuilder, NotificationBuilderApi21.setVisibility, n.lockScreenAppearance); - } + env->CallObjectMethod (notificationBuilder, NotificationBuilderApi21.setVisibility, n.lockScreenAppearance); if (getAndroidSDKVersion() >= 24) { @@ -917,9 +902,6 @@ struct PushNotifications::Pimpl static void setupActions (const PushNotifications::Notification& n, LocalRef& notificationBuilder) { - if (getAndroidSDKVersion() < 16) - return; - auto* env = getEnv(); LocalRef context (getMainActivity()); @@ -956,59 +938,51 @@ struct PushNotifications::Pimpl iconId = env->CallIntMethod (resources, AndroidResources.getIdentifier, javaString (n.icon).get(), javaString ("raw").get(), packageNameString.get()); - if (getAndroidSDKVersion() >= 20) + auto actionBuilder = LocalRef (env->NewObject (NotificationActionBuilder, + NotificationActionBuilder.constructor, + iconId, + javaString (action.title).get(), + notifyPendingIntent.get())); + + env->CallObjectMethod (actionBuilder, NotificationActionBuilder.addExtras, + varToBundleWithPropertiesString (action.parameters).get()); + + if (isTextStyle) { - auto actionBuilder = LocalRef (env->NewObject (NotificationActionBuilder, - NotificationActionBuilder.constructor, - iconId, - javaString (action.title).get(), - notifyPendingIntent.get())); + auto resultKey = javaString (action.title + String (actionIndex)); + auto remoteInputBuilder = LocalRef (env->NewObject (RemoteInputBuilder, + RemoteInputBuilder.constructor, + resultKey.get())); - env->CallObjectMethod (actionBuilder, NotificationActionBuilder.addExtras, - varToBundleWithPropertiesString (action.parameters).get()); + if (! action.textInputPlaceholder.isEmpty()) + env->CallObjectMethod (remoteInputBuilder, RemoteInputBuilder.setLabel, javaString (action.textInputPlaceholder).get()); - if (isTextStyle) + if (! action.allowedResponses.isEmpty()) { - auto resultKey = javaString (action.title + String (actionIndex)); - auto remoteInputBuilder = LocalRef (env->NewObject (RemoteInputBuilder, - RemoteInputBuilder.constructor, - resultKey.get())); + env->CallObjectMethod (remoteInputBuilder, RemoteInputBuilder.setAllowFreeFormInput, false); - if (! action.textInputPlaceholder.isEmpty()) - env->CallObjectMethod (remoteInputBuilder, RemoteInputBuilder.setLabel, javaString (action.textInputPlaceholder).get()); + const int size = action.allowedResponses.size(); - if (! action.allowedResponses.isEmpty()) + auto array = LocalRef (env->NewObjectArray (size, env->FindClass ("java/lang/String"), nullptr)); + + for (int i = 0; i < size; ++i) { - env->CallObjectMethod (remoteInputBuilder, RemoteInputBuilder.setAllowFreeFormInput, false); + const auto& response = action.allowedResponses[i]; + auto responseString = javaString (response); - const int size = action.allowedResponses.size(); - - auto array = LocalRef (env->NewObjectArray (size, env->FindClass ("java/lang/String"), nullptr)); - - for (int i = 0; i < size; ++i) - { - const auto& response = action.allowedResponses[i]; - auto responseString = javaString (response); - - env->SetObjectArrayElement (array, i, responseString.get()); - } - - env->CallObjectMethod (remoteInputBuilder, RemoteInputBuilder.setChoices, array.get()); + env->SetObjectArrayElement (array, i, responseString.get()); } - env->CallObjectMethod (actionBuilder, NotificationActionBuilder.addRemoteInput, - env->CallObjectMethod (remoteInputBuilder, RemoteInputBuilder.build)); + env->CallObjectMethod (remoteInputBuilder, RemoteInputBuilder.setChoices, array.get()); } - env->CallObjectMethod (notificationBuilder, NotificationBuilderApi20.addAction, - env->CallObjectMethod (actionBuilder, NotificationActionBuilder.build)); - } - else - { - env->CallObjectMethod (notificationBuilder, NotificationBuilderApi16.addAction, - iconId, javaString (action.title).get(), notifyPendingIntent.get()); + env->CallObjectMethod (actionBuilder, NotificationActionBuilder.addRemoteInput, + env->CallObjectMethod (remoteInputBuilder, RemoteInputBuilder.build)); } + env->CallObjectMethod (notificationBuilder, NotificationBuilderApi20.addAction, + env->CallObjectMethod (actionBuilder, NotificationActionBuilder.build)); + ++actionIndex; } } @@ -1244,9 +1218,6 @@ struct PushNotifications::Pimpl static PushNotifications::Notification javaNotificationToJuceNotification (const LocalRef& notification) { - if (getAndroidSDKVersion() < 20) - return {}; - auto* env = getEnv(); auto extras = LocalRef (env->GetObjectField (notification, AndroidNotification.extras)); diff --git a/modules/juce_gui_extra/native/juce_WebBrowserComponent_android.cpp b/modules/juce_gui_extra/native/juce_WebBrowserComponent_android.cpp index 7c7f85b6b8..562a450259 100644 --- a/modules/juce_gui_extra/native/juce_WebBrowserComponent_android.cpp +++ b/modules/juce_gui_extra/native/juce_WebBrowserComponent_android.cpp @@ -941,18 +941,8 @@ void WebBrowserComponent::clearCookies() auto cookieManager = LocalRef (env->CallStaticObjectMethod (AndroidCookieManager, AndroidCookieManager.getInstance)); - jmethodID clearCookiesMethod = nullptr; - - if (getAndroidSDKVersion() >= 21) - { - clearCookiesMethod = env->GetMethodID (AndroidCookieManager, "removeAllCookies", "(Landroid/webkit/ValueCallback;)V"); - env->CallVoidMethod (cookieManager, clearCookiesMethod, 0); - } - else - { - clearCookiesMethod = env->GetMethodID (AndroidCookieManager, "removeAllCookie", "()V"); - env->CallVoidMethod (cookieManager, clearCookiesMethod); - } + jmethodID clearCookiesMethod = env->GetMethodID (AndroidCookieManager, "removeAllCookies", "(Landroid/webkit/ValueCallback;)V"); + env->CallVoidMethod (cookieManager, clearCookiesMethod, 0); } bool WebBrowserComponent::areOptionsSupported (const Options& options) diff --git a/modules/juce_video/native/juce_CameraDevice_android.h b/modules/juce_video/native/juce_CameraDevice_android.h index 9163c0cdbb..f1b1303424 100644 --- a/modules/juce_video/native/juce_CameraDevice_android.h +++ b/modules/juce_video/native/juce_CameraDevice_android.h @@ -549,21 +549,14 @@ struct CameraDevice::Pimpl void continueOpenRequest (bool granted) { - if (getAndroidSDKVersion() >= 21) + if (granted) { - if (granted) - { - getEnv()->CallVoidMethod (getAppContext().get(), AndroidApplication.registerActivityLifecycleCallbacks, activityLifeListener.get()); - scopedCameraDevice.reset (new ScopedCameraDevice (*this, cameraId, cameraManager, handler, getAutoFocusModeToUse())); - } - else - { - invokeCameraOpenCallback ("Camera permission not granted"); - } + getEnv()->CallVoidMethod (getAppContext().get(), AndroidApplication.registerActivityLifecycleCallbacks, activityLifeListener.get()); + scopedCameraDevice.reset (new ScopedCameraDevice (*this, cameraId, cameraManager, handler, getAutoFocusModeToUse())); } else { - invokeCameraOpenCallback ("Camera requires android sdk version 21 or greater"); + invokeCameraOpenCallback ("Camera permission not granted"); } } @@ -636,9 +629,6 @@ struct CameraDevice::Pimpl static StringArray getAvailableDevices() { - if (getAndroidSDKVersion() < 21) - return StringArray(); // Camera requires SDK version 21 or later - StringArray results; auto* env = getEnv(); diff --git a/modules/juce_video/native/juce_Video_android.h b/modules/juce_video/native/juce_Video_android.h index 8096ad471e..18f9b69e2b 100644 --- a/modules/juce_video/native/juce_Video_android.h +++ b/modules/juce_video/native/juce_Video_android.h @@ -354,9 +354,6 @@ struct VideoComponent::Pimpl , systemVolumeListener (*this) #endif { - // Video requires SDK version 21 or higher - jassert (getAndroidSDKVersion() >= 21); - setVisible (true); auto* env = getEnv(); @@ -1617,9 +1614,6 @@ private: //============================================================================== static LocalRef getAudioAttributes() { - // Video requires SDK version 21 or higher - jassert (getAndroidSDKVersion() >= 21); - auto* env = getEnv(); auto audioAttribsBuilder = LocalRef (env->NewObject (AndroidAudioAttributesBuilder,