diff --git a/platform/android/java/editor/src/main/AndroidManifest.xml b/platform/android/java/editor/src/main/AndroidManifest.xml index cbe5a9d2a7..9908bfafa2 100644 --- a/platform/android/java/editor/src/main/AndroidManifest.xml +++ b/platform/android/java/editor/src/main/AndroidManifest.xml @@ -52,7 +52,7 @@ android:configChanges="layoutDirection|locale|orientation|keyboardHidden|screenSize|smallestScreenSize|density|keyboard|navigation|screenLayout|uiMode" android:exported="false" android:icon="@mipmap/themed_icon" - android:launchMode="singleTask" + android:launchMode="singleInstancePerTask" android:screenOrientation="userLandscape"> + + + + + + + + + () + override fun getGodotAppLayout() = R.layout.godot_editor_layout internal open fun getEditorWindowInfo() = EDITOR_MAIN_INFO @@ -319,6 +324,91 @@ abstract class BaseGodotEditor : GodotActivity(), GameMenuFragment.GameMenuListe super.onNewIntent(newIntent) } + override fun handleStartIntent(intent: Intent, newLaunch: Boolean) { + when (intent.action) { + Intent.ACTION_VIEW -> { + val rootDir = Environment.getExternalStorageDirectory().canonicalPath + + val dataPath = when (intent.scheme) { + ContentResolver.SCHEME_FILE -> { + intent.data?.path + } + + ContentResolver.SCHEME_CONTENT -> { + // This approach is not recommend with 'content' scheme, but we require the filesystem path in + // order to open its parent directory and load the project. + val uriPath = intent.data?.path + if (uriPath != null) { + // Try and see if the external storage directory is part of the uri path. + val rootDirIndex = uriPath.indexOf(rootDir) + if (rootDirIndex != -1) { + uriPath.substring(rootDirIndex) + } else { + // Try and see if we can retrieve an existing relative path. + val pathParts = uriPath.split(':', '/') + var currentPath = "" + for (index in pathParts.size -1 downTo 0) { + currentPath = if (currentPath == "") { + pathParts[index] + } else { + "${pathParts[index]}/$currentPath" + } + val currentFile = File(rootDir, currentPath) + if (currentFile.exists()) { + break + } + } + currentPath + } + } else { + null + } + } + + else -> null + } + + if (!dataPath.isNullOrBlank()) { + var dataFile = File(dataPath) + if (!dataFile.isAbsolute) { + dataFile = File(rootDir, dataPath) + } + + val dataDir = dataFile.parentFile + if (dataDir?.isDirectory == true) { + val loadProjectArgs = arrayOf(EDITOR_ARG, PATH_ARG, dataDir.absolutePath) + if (newLaunch) { + // Update the command line parameters to load the specified project. + updatedCommandLineParams.addAll(loadProjectArgs) + } else { + // Check if we are already editing the specified directory. + var isEditor = false + var nextIsPath = false + var currentPath = "" + for (arg in commandLine) { + if (nextIsPath) { + currentPath = arg + nextIsPath = false + } + + if (arg == EDITOR_ARG || arg == EDITOR_ARG_SHORT) { + isEditor = true + } else if (arg == PATH_ARG) { + nextIsPath = true + } + } + if (!isEditor || currentPath != dataDir.absolutePath) { + onNewGodotInstanceRequested(loadProjectArgs) + } + } + } + } + } + } + + super.handleStartIntent(intent, newLaunch) + } + protected open fun shouldShowGameMenuBar() = gameMenuContainer != null private fun setupGameMenuBar() { @@ -404,6 +494,9 @@ abstract class BaseGodotEditor : GodotActivity(), GameMenuFragment.GameMenuListe override fun getCommandLine(): MutableList { val params = super.getCommandLine() + if (updatedCommandLineParams.isNotEmpty()) { + params.addAll(updatedCommandLineParams) + } if (BuildConfig.BUILD_TYPE == "debug" && !params.contains("--benchmark")) { params.add("--benchmark") } diff --git a/platform/android/java/lib/src/main/java/org/godotengine/godot/GodotActivity.kt b/platform/android/java/lib/src/main/java/org/godotengine/godot/GodotActivity.kt index b4547d7fd2..56fedc4443 100644 --- a/platform/android/java/lib/src/main/java/org/godotengine/godot/GodotActivity.kt +++ b/platform/android/java/lib/src/main/java/org/godotengine/godot/GodotActivity.kt @@ -202,7 +202,8 @@ abstract class GodotActivity : FragmentActivity(), GodotHost { handleStartIntent(intent, false) } - private fun handleStartIntent(intent: Intent, newLaunch: Boolean) { + @CallSuper + protected open fun handleStartIntent(intent: Intent, newLaunch: Boolean) { if (!newLaunch) { val newLaunchRequested = intent.getBooleanExtra(EXTRA_NEW_LAUNCH, false) if (newLaunchRequested) {