Browse Source

Android: Add support for new bluetooth permissions from Android API 31

v7.0.9
reuk 2 years ago
parent
commit
26a23dfc9d
No known key found for this signature in database GPG Key ID: 9ADCD339CFC98A11
4 changed files with 84 additions and 18 deletions
  1. +62
    -14
      extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Android.h
  2. +3
    -0
      extras/Projucer/Source/Utility/Helpers/jucer_PresetIDs.h
  3. +10
    -3
      modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.cpp
  4. +9
    -1
      modules/juce_core/native/juce_android_RuntimePermissions.cpp

+ 62
- 14
extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Android.h View File

@@ -73,15 +73,8 @@ public:
void updateDeprecatedSettings() override
{
const auto needsExternalRead = getSettingString (Ids::androidExternalReadNeeded);
settings.removeProperty (Ids::androidExternalReadNeeded, nullptr);
if (needsExternalRead.isEmpty())
return;
androidReadMediaAudioPermission .setValue (needsExternalRead, nullptr);
androidReadMediaImagesPermission.setValue (needsExternalRead, nullptr);
androidReadMediaVideoPermission .setValue (needsExternalRead, nullptr);
updateExternalReadPermission();
updateBluetoothPermission();
}
static String getDisplayName() { return "Android"; }
@@ -107,7 +100,8 @@ public:
androidCustomActivityClass, androidCustomApplicationClass, androidManifestCustomXmlElements,
androidGradleSettingsContent, androidVersionCode, androidMinimumSDK, androidTargetSDK, androidTheme,
androidExtraAssetsFolder, androidOboeRepositoryPath, androidInternetNeeded, androidMicNeeded, androidCameraNeeded,
androidBluetoothNeeded, androidReadMediaAudioPermission, androidReadMediaImagesPermission,
androidBluetoothScanNeeded, androidBluetoothAdvertiseNeeded, androidBluetoothConnectNeeded,
androidReadMediaAudioPermission, androidReadMediaImagesPermission,
androidReadMediaVideoPermission, androidExternalWritePermission,
androidInAppBillingPermission, androidVibratePermission, androidOtherPermissions, androidPushNotifications,
androidEnableRemoteNotifications, androidRemoteNotificationsConfigFile, androidEnableContentSharing, androidKeyStore,
@@ -137,7 +131,9 @@ public:
androidInternetNeeded (settings, Ids::androidInternetNeeded, getUndoManager(), true),
androidMicNeeded (settings, Ids::microphonePermissionNeeded, getUndoManager(), false),
androidCameraNeeded (settings, Ids::cameraPermissionNeeded, getUndoManager(), false),
androidBluetoothNeeded (settings, Ids::androidBluetoothNeeded, getUndoManager(), true),
androidBluetoothScanNeeded (settings, Ids::androidBluetoothScanNeeded, getUndoManager(), false),
androidBluetoothAdvertiseNeeded (settings, Ids::androidBluetoothAdvertiseNeeded, getUndoManager(), false),
androidBluetoothConnectNeeded (settings, Ids::androidBluetoothConnectNeeded, getUndoManager(), false),
androidReadMediaAudioPermission (settings, Ids::androidReadMediaAudioPermission, getUndoManager(), true),
androidReadMediaImagesPermission (settings, Ids::androidReadMediaImagesPermission, getUndoManager(), true),
androidReadMediaVideoPermission (settings, Ids::androidReadMediaVideoPermission, getUndoManager(), true),
@@ -358,6 +354,32 @@ protected:
}
private:
void updateExternalReadPermission()
{
const auto needsExternalRead = getSettingString (Ids::androidExternalReadNeeded);
settings.removeProperty (Ids::androidExternalReadNeeded, nullptr);
if (needsExternalRead.isEmpty())
return;
androidReadMediaAudioPermission .setValue (needsExternalRead, nullptr);
androidReadMediaImagesPermission.setValue (needsExternalRead, nullptr);
androidReadMediaVideoPermission .setValue (needsExternalRead, nullptr);
}
void updateBluetoothPermission()
{
const auto needsBluetooth = getSettingString (Ids::androidBluetoothNeeded);
settings.removeProperty (Ids::androidBluetoothNeeded, nullptr);
if (needsBluetooth.isEmpty())
return;
androidBluetoothScanNeeded .setValue (needsBluetooth, nullptr);
androidBluetoothAdvertiseNeeded.setValue (needsBluetooth, nullptr);
androidBluetoothConnectNeeded .setValue (needsBluetooth, nullptr);
}
void writeCmakeFile (const File& file) const
{
build_tools::writeStreamToFile (file, [&] (MemoryOutputStream& mo)
@@ -1116,8 +1138,14 @@ private:
props.add (new ChoicePropertyComponent (androidCameraNeeded, "Camera Required"),
"If enabled, this will set the android.permission.CAMERA flag in the manifest.");
props.add (new ChoicePropertyComponent (androidBluetoothNeeded, "Bluetooth Permissions Required"),
"If enabled, this will set the android.permission.BLUETOOTH and android.permission.BLUETOOTH_ADMIN flag in the manifest. This is required for Bluetooth MIDI on Android.");
props.add (new ChoicePropertyComponent (androidBluetoothScanNeeded, "Bluetooth Scan Required"),
"If enabled, this will set the android.permission.BLUETOOTH_SCAN, android.permission.BLUETOOTH and android.permission.BLUETOOTH_ADMIN flags in the manifest. This is required for Bluetooth MIDI on Android.");
props.add (new ChoicePropertyComponent (androidBluetoothAdvertiseNeeded, "Bluetooth Advertise Required"),
"If enabled, this will set the android.permission.BLUETOOTH_ADVERTISE, android.permission.BLUETOOTH and android.permission.BLUETOOTH_ADMIN flags in the manifest.");
props.add (new ChoicePropertyComponent (androidBluetoothConnectNeeded, "Bluetooth Connect Required"),
"If enabled, this will set the android.permission.BLUETOOTH_CONNECT, android.permission.BLUETOOTH and android.permission.BLUETOOTH_ADMIN flags in the manifest.");
props.add (new ChoicePropertyComponent (androidReadMediaAudioPermission, "Read Audio From External Storage"),
"If enabled, this will set the android.permission.READ_MEDIA_AUDIO and android.permission.READ_EXTERNAL_STORAGE flags in the manifest.");
@@ -1711,6 +1739,13 @@ private:
// This permission has no effect on later Android versions.
if (permission == "android.permission.READ_EXTERNAL_STORAGE")
usesPermission->setAttribute ("android:maxSdkVersion", "32");
// These permissions are obsoleted by new more fine-grained permissions in API level 31
if (permission == "android.permission.BLUETOOTH"
|| permission == "android.permission.BLUETOOTH_ADMIN")
{
usesPermission->setAttribute ("android:maxSdkVersion", "30");
}
}
}
@@ -1868,7 +1903,18 @@ private:
if (androidCameraNeeded.get())
s.add ("android.permission.CAMERA");
if (androidBluetoothNeeded.get())
if (androidBluetoothScanNeeded.get())
s.add ("android.permission.BLUETOOTH_SCAN");
if (androidBluetoothAdvertiseNeeded.get())
s.add ("android.permission.BLUETOOTH_ADVERTISE");
if (androidBluetoothConnectNeeded.get())
s.add ("android.permission.BLUETOOTH_CONNECT");
if ( androidBluetoothScanNeeded.get()
|| androidBluetoothAdvertiseNeeded.get()
|| androidBluetoothConnectNeeded.get())
{
s.add ("android.permission.BLUETOOTH");
s.add ("android.permission.BLUETOOTH_ADMIN");
@@ -1888,7 +1934,9 @@ private:
if ( androidReadMediaAudioPermission.get()
|| androidReadMediaImagesPermission.get()
|| androidReadMediaVideoPermission.get())
{
s.add ("android.permission.READ_EXTERNAL_STORAGE");
}
if (androidExternalWritePermission.get())
s.add ("android.permission.WRITE_EXTERNAL_STORAGE");


+ 3
- 0
extras/Projucer/Source/Utility/Helpers/jucer_PresetIDs.h View File

@@ -234,6 +234,9 @@ namespace Ids
DECLARE_ID (androidGradleSettingsContent);
DECLARE_ID (androidCustomStringXmlElements);
DECLARE_ID (androidBluetoothNeeded);
DECLARE_ID (androidBluetoothScanNeeded);
DECLARE_ID (androidBluetoothAdvertiseNeeded);
DECLARE_ID (androidBluetoothConnectNeeded);
DECLARE_ID (androidExternalReadNeeded);
DECLARE_ID (androidReadMediaAudioPermission);
DECLARE_ID (androidReadMediaImagesPermission);


+ 10
- 3
modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.cpp View File

@@ -1193,11 +1193,18 @@ void AudioDeviceSelectorComponent::updateAllControls()
void AudioDeviceSelectorComponent::handleBluetoothButton()
{
if (! RuntimePermissions::isGranted (RuntimePermissions::bluetoothMidi))
RuntimePermissions::request (RuntimePermissions::bluetoothMidi, nullptr);
if (RuntimePermissions::isGranted (RuntimePermissions::bluetoothMidi))
{
BluetoothMidiDevicePairingDialogue::open();
}
else
{
RuntimePermissions::request (RuntimePermissions::bluetoothMidi, [] (auto)
{
if (RuntimePermissions::isGranted (RuntimePermissions::bluetoothMidi))
BluetoothMidiDevicePairingDialogue::open();
});
}
}
ListBox* AudioDeviceSelectorComponent::getMidiInputSelectorListBox() const noexcept


+ 9
- 1
modules/juce_core/native/juce_android_RuntimePermissions.cpp View File

@@ -34,7 +34,14 @@ static StringArray jucePermissionToAndroidPermissions (RuntimePermissions::Permi
switch (permission)
{
case RuntimePermissions::recordAudio: return { "android.permission.RECORD_AUDIO" };
case RuntimePermissions::bluetoothMidi: return { "android.permission.ACCESS_FINE_LOCATION" };
case RuntimePermissions::bluetoothMidi:
{
if (getAndroidSDKVersion() < 31)
return { "android.permission.ACCESS_FINE_LOCATION" };
return { "android.permission.BLUETOOTH_SCAN" };
}
case RuntimePermissions::writeExternalStorage: return { "android.permission.WRITE_EXTERNAL_STORAGE" };
case RuntimePermissions::camera: return { "android.permission.CAMERA" };
@@ -76,6 +83,7 @@ static RuntimePermissions::PermissionID androidPermissionToJucePermission (const
{ "android.permission.READ_MEDIA_AUDIO", RuntimePermissions::readMediaAudio },
{ "android.permission.READ_MEDIA_IMAGES", RuntimePermissions::readMediaImages },
{ "android.permission.READ_MEDIA_VIDEO", RuntimePermissions::readMediaVideo },
{ "android.permission.BLUETOOTH_SCAN", RuntimePermissions::bluetoothMidi },
};
const auto iter = map.find (permission);


Loading…
Cancel
Save