diff --git a/examples/Assets/DemoUtilities.h b/examples/Assets/DemoUtilities.h index ffdfc3631c..b2d38fffb6 100644 --- a/examples/Assets/DemoUtilities.h +++ b/examples/Assets/DemoUtilities.h @@ -244,10 +244,8 @@ struct SlowerBouncingNumber : public BouncingNumber inline std::unique_ptr makeInputSource (const URL& url) { - #if JUCE_ANDROID - if (auto doc = AndroidDocument::fromDocument (url)) + if (const auto doc = AndroidDocument::fromDocument (url)) return std::make_unique (doc); - #endif #if ! JUCE_IOS if (url.isLocalFile()) @@ -257,4 +255,17 @@ inline std::unique_ptr makeInputSource (const URL& url) return std::make_unique (url); } +inline std::unique_ptr makeOutputStream (const URL& url) +{ + if (const auto doc = AndroidDocument::fromDocument (url)) + return doc.createOutputStream(); + + #if ! JUCE_IOS + if (url.isLocalFile()) + return url.getLocalFile().createOutputStream(); + #endif + + return url.createOutputStream(); +} + #endif // PIP_DEMO_UTILITIES_INCLUDED diff --git a/examples/Audio/AudioRecordingDemo.h b/examples/Audio/AudioRecordingDemo.h index 38bf15b7d7..8084383caa 100644 --- a/examples/Audio/AudioRecordingDemo.h +++ b/examples/Audio/AudioRecordingDemo.h @@ -305,17 +305,14 @@ private: LiveScrollingAudioDisplay liveAudioScroller; RecordingThumbnail recordingThumbnail; - AudioRecorder recorder { recordingThumbnail.getAudioThumbnail() }; + AudioRecorder recorder { recordingThumbnail.getAudioThumbnail() }; - Label explanationLabel { {}, "This page demonstrates how to record a wave file from the live audio input..\n\n" - #if (JUCE_ANDROID || JUCE_IOS) - "After you are done with your recording you can share with other apps." - #else - "Pressing record will start recording a file in your \"Documents\" folder." - #endif - }; + Label explanationLabel { {}, + "This page demonstrates how to record a wave file from the live audio input.\n\n" + "After you are done with your recording you can choose where to save it." }; TextButton recordButton { "Record" }; File lastRecording; + FileChooser chooser { "Output file...", File::getCurrentWorkingDirectory().getChildFile ("recording.wav"), "*.wav" }; void startRecording() { @@ -350,28 +347,18 @@ private: { recorder.stop(); - #if JUCE_CONTENT_SHARING - SafePointer safeThis (this); - File fileToShare = lastRecording; + chooser.launchAsync ( FileBrowserComponent::saveMode + | FileBrowserComponent::canSelectFiles + | FileBrowserComponent::warnAboutOverwriting, + [this] (const FileChooser& c) + { + if (FileInputStream inputStream (lastRecording); inputStream.openedOk()) + if (const auto outputStream = makeOutputStream (c.getURLResult())) + outputStream->writeFromInputStream (inputStream, -1); - ContentSharer::getInstance()->shareFiles (Array ({URL (fileToShare)}), - [safeThis, fileToShare] (bool success, const String& error) - { - if (fileToShare.existsAsFile()) - fileToShare.deleteFile(); - - if (! success && error.isNotEmpty()) - NativeMessageBox::showAsync (MessageBoxOptions() - .withIconType (MessageBoxIconType::WarningIcon) - .withTitle ("Sharing Error") - .withMessage (error), - nullptr); - }); - #endif - - lastRecording = File(); - recordButton.setButtonText ("Record"); - recordingThumbnail.setDisplayFullThumbnail (true); + recordButton.setButtonText ("Record"); + recordingThumbnail.setDisplayFullThumbnail (true); + }); } JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioRecordingDemo) diff --git a/modules/juce_core/native/juce_android_RuntimePermissions.cpp b/modules/juce_core/native/juce_android_RuntimePermissions.cpp index 285b92c1e1..45a30233e7 100644 --- a/modules/juce_core/native/juce_android_RuntimePermissions.cpp +++ b/modules/juce_core/native/juce_android_RuntimePermissions.cpp @@ -43,7 +43,11 @@ static StringArray jucePermissionToAndroidPermissions (RuntimePermissions::Permi "android.permission.BLUETOOTH_CONNECT" }; } - case RuntimePermissions::writeExternalStorage: return { "android.permission.WRITE_EXTERNAL_STORAGE" }; + // WRITE_EXTERNAL_STORAGE has no effect on SDK 29+ + case RuntimePermissions::writeExternalStorage: + return getAndroidSDKVersion() < 29 ? StringArray { "android.permission.WRITE_EXTERNAL_STORAGE" } + : StringArray{}; + case RuntimePermissions::camera: return { "android.permission.CAMERA" }; case RuntimePermissions::readExternalStorage: