From 1433142a70f0d71015f519587881c66bacc54006 Mon Sep 17 00:00:00 2001 From: Mike Miller Date: Fri, 24 Nov 2023 13:47:17 +0200 Subject: [PATCH] Update Android SDK Target to v32 (Android 12); request MANAGE_EXTERNAL_STORAGE (#563) * Add 12L permissions request * Ignore code on non-Android, and catch exception and ignore on API < 30 * Use Android's Environment.isExternalStorageManager instead of Permission.HasUserAuthorizedPermission --------- Co-authored-by: Mike Nisbet --- Assets/Plugins/Android/AndroidManifest.xml | 1 + Assets/Scenes/Loading.unity | 21 ++++++ Assets/Scripts/LoadingScene.cs | 68 +++++++++++++++++++ .../Strings/Strings Shared Data.asset | 6 +- .../Localization/Strings/Strings_en.asset | 10 ++- ProjectSettings/ProjectSettings.asset | 4 +- 6 files changed, 104 insertions(+), 6 deletions(-) diff --git a/Assets/Plugins/Android/AndroidManifest.xml b/Assets/Plugins/Android/AndroidManifest.xml index fd52ce5206..8b803d7168 100644 --- a/Assets/Plugins/Android/AndroidManifest.xml +++ b/Assets/Plugins/Android/AndroidManifest.xml @@ -18,4 +18,5 @@ + diff --git a/Assets/Scenes/Loading.unity b/Assets/Scenes/Loading.unity index bfeffc32f9..3118b0fd1d 100644 --- a/Assets/Scenes/Loading.unity +++ b/Assets/Scenes/Loading.unity @@ -206,6 +206,27 @@ MonoBehaviour: m_VrCamera: {fileID: 1815664868} m_MaximumLoadingTime: 60 m_SceneLoadRatio: 0.75 + m_LoadingText: + m_TableReference: + m_TableCollectionName: GUID:c84355079ab3f3e4f8f3812258805f86 + m_TableEntryReference: + m_KeyId: 287897575133184 + m_Key: + m_FallbackState: 0 + m_WaitForCompletion: 0 + m_LocalVariables: [] + m_RequestAndroidFolderPermissions: + m_TableReference: + m_TableCollectionName: GUID:c84355079ab3f3e4f8f3812258805f86 + m_TableEntryReference: + m_KeyId: 170004956477833216 + m_Key: + m_FallbackState: 0 + m_WaitForCompletion: 0 + m_LocalVariables: [] + references: + version: 2 + RefIds: [] --- !u!4 &326031496 Transform: m_ObjectHideFlags: 0 diff --git a/Assets/Scripts/LoadingScene.cs b/Assets/Scripts/LoadingScene.cs index 46afef83d2..491401df6b 100644 --- a/Assets/Scripts/LoadingScene.cs +++ b/Assets/Scripts/LoadingScene.cs @@ -15,6 +15,11 @@ using System.Collections; using UnityEngine; using UnityEngine.SceneManagement; +using UnityEngine.Localization; + +#if UNITY_ANDROID +using UnityEngine.Android; +#endif namespace TiltBrush { @@ -27,11 +32,17 @@ public class LoadingScene : MonoBehaviour // Amount of the progress bar taken up by the scene load [SerializeField] private float m_SceneLoadRatio; + [SerializeField] private LocalizedString m_LoadingText; + [SerializeField] private LocalizedString m_RequestAndroidFolderPermissions; + // We have a slightly faked loading position that will always increase // The fake loading rate is the minimum amount it will increase in one second, the reciprocal of // m_MaximumLoadingTime private float m_FakeLoadingRate; private float m_CurrentLoadingPosition; +#if UNITY_ANDROID + private bool m_FolderPermissionOverride = false; +#endif private IEnumerator Start() { @@ -58,6 +69,23 @@ private IEnumerator Start() DontDestroyOnLoad(gameObject); +#if UNITY_ANDROID + if (Application.platform == RuntimePlatform.Android) + { + if (!UserHasManageExternalStoragePermission()) + { + m_Overlay.MessageStatus = m_RequestAndroidFolderPermissions.GetLocalizedString(); + AskForManageStoragePermission(); + while (!UserHasManageExternalStoragePermission()) + { + yield return new WaitForEndOfFrame(); + } + + m_Overlay.MessageStatus = m_LoadingText.GetLocalizedString(); + } + } +#endif + AsyncOperation asyncLoad = SceneManager.LoadSceneAsync("Main"); while (!asyncLoad.isDone) { @@ -91,5 +119,45 @@ private void UpdateProgress(float start, float scale, float progress) m_CurrentLoadingPosition = Mathf.Max(m_CurrentLoadingPosition, position); m_Overlay.Progress = m_CurrentLoadingPosition; } + +#if UNITY_ANDROID + private bool UserHasManageExternalStoragePermission() + { + bool isExternalStorageManager = false; + try + { + AndroidJavaClass environmentClass = new AndroidJavaClass("android.os.Environment"); + isExternalStorageManager = environmentClass.CallStatic("isExternalStorageManager"); + } + catch (AndroidJavaException e) + { + Debug.LogError("Java Exception caught and ignored: " + e.Message); + Debug.LogError("Assuming this means this device doesn't support isExternalStorageManager."); + } + return m_FolderPermissionOverride || isExternalStorageManager; + } + + private void AskForManageStoragePermission() + { + try + { + using var unityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); + using AndroidJavaObject currentActivityObject = unityClass.GetStatic("currentActivity"); + string packageName = currentActivityObject.Call("getPackageName"); + using var uriClass = new AndroidJavaClass("android.net.Uri"); + using AndroidJavaObject uriObject = uriClass.CallStatic("fromParts", "package", packageName, null); + using var intentObject = new AndroidJavaObject("android.content.Intent", "android.settings.MANAGE_APP_ALL_FILES_ACCESS_PERMISSION", uriObject); + intentObject.Call("addCategory", "android.intent.category.DEFAULT"); + currentActivityObject.Call("startActivity", intentObject); + } + catch (AndroidJavaException e) + { + // TODO: only skip this if it's of type act=android.settings.MANAGE_APP_ALL_FILES_ACCESS_PERMISSION + m_FolderPermissionOverride = true; + Debug.LogError("Java Exception caught and ignored: " + e.Message); + Debug.LogError("Assuming this means we don't need android.settings.MANAGE_APP_ALL_FILES_ACCESS_PERMISSION (e.g., Android SDK < 30)"); + } + } +#endif } } // namespace TiltBrush diff --git a/Assets/Settings/Localization/Strings/Strings Shared Data.asset b/Assets/Settings/Localization/Strings/Strings Shared Data.asset index 7668047cbb..bcb1066875 100644 --- a/Assets/Settings/Localization/Strings/Strings Shared Data.asset +++ b/Assets/Settings/Localization/Strings/Strings Shared Data.asset @@ -540,7 +540,7 @@ MonoBehaviour: m_Metadata: m_Items: [] - m_Id: 287897575133184 - m_Key: LOADING_SCENE_OVERLAY_MESSAGE + m_Key: LOADING_SCENE_OVERLAY_LOADING m_Metadata: m_Items: [] - m_Id: 7892854560759808 @@ -3271,6 +3271,10 @@ MonoBehaviour: m_Key: POPUP_RECORD_UNSUPPORTED_TEXT m_Metadata: m_Items: [] + - m_Id: 170004956477833216 + m_Key: LOADING_SCENE_OVERLAY_ANDROIDPERMISSIONS + m_Metadata: + m_Items: [] m_Metadata: m_Items: [] m_KeyGenerator: diff --git a/Assets/Settings/Localization/Strings/Strings_en.asset b/Assets/Settings/Localization/Strings/Strings_en.asset index 3095eb46f3..c46cc808e2 100644 --- a/Assets/Settings/Localization/Strings/Strings_en.asset +++ b/Assets/Settings/Localization/Strings/Strings_en.asset @@ -3101,7 +3101,7 @@ MonoBehaviour: m_Metadata: m_Items: [] - m_Id: 106429517453328384 - m_Localized: "Background Images" + m_Localized: Background Images m_Metadata: m_Items: [] - m_Id: 95221400803737600 @@ -3457,11 +3457,15 @@ MonoBehaviour: m_Metadata: m_Items: [] - m_Id: 151490030713540608 - m_Localized: 'You can create a video of your sketch by opening it on a Mac or PC. - Search for "Exporting video" on our docs website: https://docs.openbrush.app + m_Localized: 'You can create a video of your sketch by opening it on a Mac or + PC. Search for "Exporting video" on our docs website: https://docs.openbrush.app for a step by step guide.' m_Metadata: m_Items: [] + - m_Id: 170004956477833216 + m_Localized: Please give Open Brush file access to save your creations! + m_Metadata: + m_Items: [] references: version: 2 RefIds: [] diff --git a/ProjectSettings/ProjectSettings.asset b/ProjectSettings/ProjectSettings.asset index d6545b629e..c24ca29363 100644 --- a/ProjectSettings/ProjectSettings.asset +++ b/ProjectSettings/ProjectSettings.asset @@ -175,8 +175,8 @@ PlayerSettings: tvOS: 0 overrideDefaultApplicationIdentifier: 1 AndroidBundleVersionCode: 1 - AndroidMinSdkVersion: 27 - AndroidTargetSdkVersion: 29 + AndroidMinSdkVersion: 29 + AndroidTargetSdkVersion: 32 AndroidPreferredInstallLocation: 0 aotOptions: stripEngineCode: 1