From 644495e9398baeaeab0e0ec6e7c16ebc4afeeaa8 Mon Sep 17 00:00:00 2001 From: Anthony Berg Date: Mon, 11 May 2026 14:39:28 +0200 Subject: [PATCH] Allow wider recognition of osu! files on Android (#37614) The main goal of this PR is to fix opening files outside of osu! without having to share or import it through the osu! interface, partially related to https://github.com/ppy/osu/issues/11911. It should hopefully avoid people getting confused on how to import certain files such as https://osu.ppy.sh/community/forums/topics/1823096. From what I understand the main problem is how certain applications pass the content URI to the file as mentioned on this [Stack Overflow post](https://stackoverflow.com/a/61331776/13629413) and it's why I added the broader MIME types. From what I gathered, [Files by Google](https://play.google.com/store/apps/details?id=com.google.android.apps.nbu.files&hl=en) views the osu! files as `application/octet-stream`, and that's why you couldn't open it normally before this PR. However, [Material Files](https://play.google.com/store/apps/details?id=me.zhanghai.android.files&hl=en) does also see it as a `application/octet-stream`, but I assume the content URI ends with the correct file extension. I also added labels when opening/sharing the file to osu!, as can be seen in this screenshot from opening the files with Material Files: osu android file handling --- osu.Android/OsuGameActivity.cs | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/osu.Android/OsuGameActivity.cs b/osu.Android/OsuGameActivity.cs index 66c697801b..b0213c7d5a 100644 --- a/osu.Android/OsuGameActivity.cs +++ b/osu.Android/OsuGameActivity.cs @@ -20,13 +20,24 @@ using Uri = Android.Net.Uri; namespace osu.Android { [Activity(ConfigurationChanges = DEFAULT_CONFIG_CHANGES, Exported = true, LaunchMode = DEFAULT_LAUNCH_MODE, MainLauncher = true)] - [IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault }, DataScheme = "content", DataPathPattern = ".*\\\\.osz", DataHost = "*", DataMimeType = "*/*")] - [IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault }, DataScheme = "content", DataPathPattern = ".*\\\\.osk", DataHost = "*", DataMimeType = "*/*")] - [IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault }, DataScheme = "content", DataPathPattern = ".*\\\\.osr", DataHost = "*", DataMimeType = "*/*")] - [IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault }, DataScheme = "content", DataMimeType = "application/x-osu-beatmap-archive")] - [IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault }, DataScheme = "content", DataMimeType = "application/x-osu-skin-archive")] - [IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault }, DataScheme = "content", DataMimeType = "application/x-osu-replay")] - [IntentFilter(new[] { Intent.ActionSend, Intent.ActionSendMultiple }, Categories = new[] { Intent.CategoryDefault }, DataMimeTypes = new[] + [IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault }, Label = "Import beatmap", DataScheme = "content", DataPathPattern = ".*\\\\.osz", DataHost = "*", + DataMimeType = "*/*")] + [IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault }, Label = "Import skin", DataScheme = "content", DataPathPattern = ".*\\\\.osk", DataHost = "*", + DataMimeType = "*/*")] + [IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault }, Label = "Import replay", DataScheme = "content", DataPathPattern = ".*\\\\.osr", DataHost = "*", + DataMimeType = "*/*")] + [IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault }, Label = "Import beatmap", DataScheme = "content", DataMimeType = "application/x-osu-beatmap-archive")] + [IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault }, Label = "Import skin", DataScheme = "content", DataMimeType = "application/x-osu-skin-archive")] + [IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault }, Label = "Import replay", DataScheme = "content", DataMimeType = "application/x-osu-replay")] + [IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault }, Label = "Import file", DataScheme = "content", DataMimeTypes = new[] + { + "application/zip", + "application/octet-stream", + "application/download", + "application/x-zip", + "application/x-zip-compressed", + })] + [IntentFilter(new[] { Intent.ActionSend, Intent.ActionSendMultiple }, Categories = new[] { Intent.CategoryDefault }, Label = "Import", DataMimeTypes = new[] { "application/zip", "application/octet-stream",