Bug 3674 - Intent filters clash with MainLauncher
Summary: Intent filters clash with MainLauncher
Status: RESOLVED FIXED
Alias: None
Product: Android
Classification: Xamarin
Component: MSBuild ()
Version: 4.0
Hardware: All Mac OS
: Normal normal
Target Milestone: ---
Assignee: Bugzilla
URL:
: 5970 ()
Depends on:
Blocks:
 
Reported: 2012-02-28 19:25 UTC by adam.lickel
Modified: 2012-07-04 12:06 UTC (History)
6 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED FIXED

Description adam.lickel 2012-02-28 19:25:00 UTC
If an activity has MainLauncher set to true, and there are additional IntentFilters, it arbitrarily merges the intent filters as in:

    [Activity ( MainLauncher = true )]
    (.. multiple intent filters ..)
    [IntentFilter (
        new[] { Intent.ActionView },
        Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable },
        DataScheme = "http",
        DataHost = "rdio.com",
        DataPathPrefix = "/people/")]
    (.. multiple intent filters ..)

      <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:host="rdio.com" android:pathPrefix="/people/" android:scheme="http" />
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>

The MainLauncher intent filter should *always* be a distinct <intent-filter> entry.

If the intent filter is explicitly added, then the manifest is OK, but MonoDevelop won't be able to launch the activity with the following error:
"Application does not contain a launchable activity".  This is obviously a minor issue, but interesting nonetheless.
    [IntentFilter (
        new[] { Intent.ActionMain },
        Categories = new[] { Intent.CategoryLauncher })]
Comment 1 Atsushi Eno 2012-04-26 05:40:13 UTC
IMO, instead of making conflicting IntentFilters distinct and pass the build, our build task should error out such conflicts, because it will most likely result in "unexpected" merge for developers (and I think comparing those members are likely error-prone, which end up to bite developers).
Comment 2 adam.lickel 2012-04-26 12:02:12 UTC
Atsushi: I think you misunderstood the problem.
Each [IntentFilter] should be unique.

MainLauncher = true should implicitly do:
    [IntentFilter (
        new[] { Intent.ActionMain },
        Categories = new[] { Intent.CategoryLauncher })]

If you have no other intent filters defined, this works correctly.
Unfortunately, if you add *any* other intent filters to the activity, it will munge one of those filters (randomly chosen) with the MainLauncher intent filter.

You can define any number of <intent-filter> blocks, and the MainLauncher intent filter does not conflict with others, so this is definitely the wrong behavior.
If I set MainLauncher to false and create that intent filter block manually, Android has no problems with it.
Unfortunately, in that situation, MonoDevelop does not know what to do with the APK.
Comment 3 Atsushi Eno 2012-05-11 10:51:47 UTC
I'm still likely unclear, but so far I guess and try to create a repro case.

Now I have an Activity which is from default "Hello World"-ish example, with additional attributes

	[Activity (Label = "AndroidTest8", MainLauncher = true)]
    [IntentFilter (
        new[] { Intent.ActionView },
        Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable
},
        DataScheme = "http",
        DataHost = "rdio.com",
        DataPathPrefix = "/people/")]
    [IntentFilter (
        new[] { Intent.ActionView },
        Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable
},
        DataScheme = "https",
        DataHost = "foobar.com",
        DataPathPrefix = "/baz/")]
	public class Activity1 : Activity
	{
...
	}

When I built the application, the relevant fragment in  obj/Debug/android/AndroidManifest.xml looks like:

    <activity android:label="AndroidTest8" android:name="androidtest8.Activity1">
      <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:host="rdio.com" android:pathPrefix="/people/" android:scheme="http" />
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
      <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:host="foobar.com" android:pathPrefix="/baz/" android:scheme="https" />
      </intent-filter>
    </activity>

I think this resulted in "distinct" intent filters - correct?

If so, then we likely fixed this issue in 4.2.
Comment 4 adam.lickel 2012-05-11 11:13:35 UTC
You only have two <intent-filter> tags.

It should look something like:

    <activity android:label="AndroidTest8"
android:name="androidtest8.Activity1">
      <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:host="rdio.com" android:pathPrefix="/people/"
android:scheme="http" />
       </intent-filter>    <!-- ******* ADDED LINE ******* -->
       <intent-filter>      <!-- ******* ADDED LINE ******* -->
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
      <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:host="foobar.com" android:pathPrefix="/baz/"
android:scheme="https" />
      </intent-filter>
    </activity>
Comment 5 Atsushi Eno 2012-05-11 12:12:16 UTC
OK, thanks, that made it clear! This is now fixed in our sources. We seem to be doing the old behavior without solid understanding.

Though since we are already finalizing package for 4.2, this fix will be available for later version. Sorry for inconvenience.
Comment 6 Alex Corrado [MSFT] 2012-07-03 19:01:28 UTC
I get "Application does not contain a launchable activity" trying to launch an app with an IntentFilter attribute on the same activity as MainLauncher = true. This appears to be a regression in MfA 4.2.3/4.2.4, as it works fine in MfA 4.2.2.
Comment 7 Atsushi Eno 2012-07-04 05:27:41 UTC
This should be "fixed" (I recorded the details a bit more in the commit msg).
Comment 8 PJ 2012-07-04 12:06:06 UTC
*** Bug 5970 has been marked as a duplicate of this bug. ***