Skip to content
This repository was archived by the owner on Jul 13, 2026. It is now read-only.

Commit 52f0866

Browse files
authored
[Xamarin.Android.Tools.AndroidSdk] Check all <intent-filter/>s (#214)
Context: https://developercommunity.visualstudio.com/t/Cannot-deploy-to-Android-emulators-and-d/10428163 Context: https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1863835 Context: https://developer.android.com/guide/components/intents-filters The [`<activity/>`][0] and related elements within `AndroidManifest.xml` can have multiple [`<intent-filter/>`][1]s specified. Android does not require that `<intent-filter/>`s be listed in any particular order. However, Visual Studio *does* care about the order (?!)! [Activity(Exported = true, Label = "@string/app_name", MainLauncher = true)] [IntentFilter( new[] { Android.Content.Intent.ActionView }, Categories = new[] { Android.Content.Intent.CategoryDefault, Android.Content.Intent.CategoryBrowsable, } )] [IntentFilter( new[] { Android.Content.Intent.ActionMain }, Categories = new[] { Android.Content.Intent.CategoryLauncher, Android.Content.Intent.CategoryLeanbackLauncher, } )] public partial class MainActivity : Activity {} If the `[IntentFilter]` with `Android.Content.Intent.ActionMain` is *not* first, then Visual Studio does not consider this Activity to be a launchable activity. The reason for this is, in part, because `AndroidAppManifest.GetLaunchableActivities()` only looked at the *first* `<intent-filter/>` to see if it had the category of `android.intent.category.LAUNCHER`. Update `AndroidAppManifest.GetLaunchableActivities()` so that *all* `<intent-filter/>` elements are checked for the `.LAUNCHER` category. **Workaround**: Specify the `[IntentFilter]` with `Intent.ActionMain` first: [Activity(Exported = true, Label = "@string/app_name", MainLauncher = true)] [IntentFilter( new[] { Android.Content.Intent.ActionMain }, Categories = new[] { Android.Content.Intent.CategoryLauncher, Android.Content.Intent.CategoryLeanbackLauncher, } )] [IntentFilter( new[] { Android.Content.Intent.ActionView }, Categories = new[] { Android.Content.Intent.CategoryDefault, Android.Content.Intent.CategoryBrowsable, } )] public partial class MainActivity : Activity {} Note: this change, in and of itself, may not be sufficient to fix Visual Studio, as there are a few other places that have the same "only check the first `<intent-filter/>`" bug. [0]: https://developer.android.com/guide/topics/manifest/activity-element [1]: https://developer.android.com/guide/topics/manifest/intent-filter-element
1 parent 57be026 commit 52f0866

3 files changed

Lines changed: 22 additions & 2 deletions

File tree

‎src/Xamarin.Android.Tools.AndroidSdk/AndroidAppManifest.cs‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -323,8 +323,7 @@ void RemoveAndroidPermissions (IEnumerable<string> permissions)
323323
IEnumerable<XElement>GetLaunchableActivities()
324324
{
325325
foreach(varactivityinapplication.Elements("activity")){
326-
varfilter=activity.Element("intent-filter");
327-
if(filter!=null){
326+
foreach(varfilterinactivity.Elements("intent-filter")){
328327
foreach(varcategoryinfilter.Elements("category"))
329328
if(category!=null&&(string?)category.Attribute(aName)=="android.intent.category.LAUNCHER")
330329
yieldreturnactivity;

‎tests/Xamarin.Android.Tools.AndroidSdk-Tests/AndroidAppManifestTests.cs‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,16 @@ static XDocument GetTestAppManifest ()
4545
}
4646
}
4747

48+
[Test]
49+
publicvoidGetLaunchableActivityNames()
50+
{
51+
varversions=newAndroidVersions(Array.Empty<AndroidVersion>());
52+
varmanifest=AndroidAppManifest.Load(GetTestAppManifest(),versions);
53+
varlaunchers=manifest.GetLaunchableActivityNames().ToList();
54+
Assert.AreEqual(1,launchers.Count);
55+
Assert.AreEqual(".HasMultipleIntentFilters",launchers[0]);
56+
}
57+
4858
[Test]
4959
publicvoidSetNewPermissions()
5060
{

‎tests/Xamarin.Android.Tools.AndroidSdk-Tests/Resources/manifest-simplewidget.xml‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,17 @@
2222
<categoryandroid:name="android.intent.category.LAUNCHER" />
2323
</intent-filter>
2424
</activity>
25+
<activityandroid:name=".HasMultipleIntentFilters"android:label="launcher?">
26+
<intent-filter>
27+
<actionandroid:name="android.intent.action.VIEW" />
28+
<categoryandroid:name="android.intent.category.DEFAULT" />
29+
<categoryandroid:name="android.intent.category.BROWSABLE" />
30+
</intent-filter>
31+
<intent-filter>
32+
<actionandroid:name="android.intent.action.MAIN" />
33+
<categoryandroid:name="android.intent.category.LAUNCHER" />
34+
</intent-filter>
35+
</activity>
2536
</application>
2637
<uses-permissionandroid:name="android.permission.INTERNET" />
2738
<uses-permissionandroid:name="android.permission.READ_CONTACTS" />

0 commit comments

Comments
 (0)