Bug 33514 - IntentFilterAttribute does not allow specifying the equivalent of multiple "data" attributes
Summary: IntentFilterAttribute does not allow specifying the equivalent of multiple "d...
Alias: None
Product: Android
Classification: Xamarin
Component: BCL Class Libraries ()
Version: unspecified
Hardware: PC Windows
: High enhancement
Target Milestone: C6SR1
Assignee: Atsushi Eno
Depends on:
Reported: 2015-08-31 12:32 UTC by Dimitar Dobrev
Modified: 2015-11-23 12:34 UTC (History)
3 users (show)

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:

Description Dimitar Dobrev 2015-08-31 12:32:31 UTC
The Android documentation clearly states that a single intent filter can have multiple "data" (http://developer.android.com/guide/topics/manifest/data-element.html). However, IntentFilterAttribute.Data* properties are all strings, not lists of strings. This makes it extremely inconvenient to use IntentFilterAttribute to handle multiple schemes (http(s)) and multiple paths because a separate IntentFilterAttribute has to be used for each combination. This means that if one needs to handle 2 schemes, 2 URL-s and 5 paths, he would need 2 x 2 x 5 = 20 (!!!) attributes.
I am aware that in such cases Android.manifest can be directly used. However, that doesn't always work because one might need to use different filters per build config (using #ifdef). I am also aware that you cannot create a Data struct (with a DataScheme, DataHost, etc string properties) and use a list of Data in IntentFilterAttribute since properties of attributed are resolved at compilation time. However, you can change the Data* properties to Data*s list properties and use them to construct <data /> elements in the manifest, the same way you do with actions and categories.
Comment 1 Jonathan Pryor 2015-09-01 14:13:27 UTC
This might be one of those instances where it's better to just let you manually write XML in Properties\AndroidManifest.xml and rely on the default "content merge" behavior:


The fundamental problem is that the types that a custom attribute can contain are limited:


Furthermore, since <activity/>/etc. can have multiple <intent-filter/> descriptions, I don't think that's it's really feasible to split out the <data/> element into a separate custom attribute, because order of custom attributes is not necessarily preserved (at least I know of nothing requiring that custom attribute application order be preserved in C# or any other language), meaning something like this:

    [IntentFilter (IntentFilter1...)]
    [Data (Data1...)]
    [IntentFilter (IntentFilter2)]
    [Data (Data2...)]
    public partial class MyActivity : Activity {}

may not be able to reliably match Data1 to the IntentFilter1, and Data2 to IntentFilter2...

If it's not reliable, consistent, or understandable, it's not happening. :-)

It's complicated, and in the absence of a better way to do it (and an array of structs would be SO HANDY for this...), the sanest solution I can think of is the already existing "use Properties\AndroidManifest.xml".
Comment 2 Dimitar Dobrev 2015-09-01 14:24:18 UTC
This wasn't my suggestion at all. I suggested changing IntentFilterAttribute.Data* from strings to lists of strings. This way we will be able to write:

[IntentFilter(DataHosts = new [] { "URL1", "URL2", ... }, DataPaths = new [] { "Path 1", ... } )]

that is, what I said earlier - the same as IntentFilterAttribute.Categories and IntentFilterAttribute.Actions.
Comment 3 Jonathan Pryor 2015-09-01 14:30:16 UTC
> I suggested changing IntentFilterAttribute.Data* from strings to lists of strings

And what happens when the arrays have separate lengths?

    [IntentFilter (
        DataPaths=new[]{"path1", "path2"},
        DataPathPrefixes=new[]{"prefix1", "prefix2", "prefix3"}

What <data/> elements should the above generate? Should "same indexes" be used?

Though trying to infer whether indexes match each other might be moot; from the docs:

> So, for example, the following filter specification,...
> is equivalent to this one:

Which suggests that the above [IntentFilter] could emit:

    <data android:host="url1" />
    <data android:path="path1" />
    <data android:path="path2" />
    <data android:prefix="prefix1" />
    <data android:prefix="prefix2" />
    <data android:prefix="prefix3" />

and have no relation between anything at all.

The docs certainly imply that the above should work...
Comment 4 Dimitar Dobrev 2015-09-01 14:31:39 UTC
Comment 5 Atsushi Eno 2015-09-16 09:30:59 UTC
Dimitar, with the latest commit to monodroid, I have added those properties on IntentFilterAttribute as you suggested:

                public string[]   DataHosts       {get; set;}
                public string[]   DataMimeTypes   {get; set;}
                public string[]   DataPaths       {get; set;}
                public string[]   DataPathPatterns{get; set;}
                public string[]   DataPathPrefixes{get; set;}
                public string[]   DataPorts       {get; set;}
                public string[]   DataSchemes     {get; set;}

Thanks for the report and ideas!

[master 5eb7c0a]
Comment 6 Dimitar Dobrev 2015-09-16 09:44:38 UTC
You're welcome, I'm glad I could help. I'd be even more glad if you could comment about https://bugzilla.xamarin.com/show_bug.cgi?id=25245, it's been half a year.
Comment 7 Atsushi Eno 2015-09-16 12:41:08 UTC
(Not really an official update to the bug so I comment here instead; one of our devs wrote the most part of the alternative to the existing Java API parser, but he's been busy and had little time to make it solid for general consumption yet. In fact a few days ago we had discussed that particular stuff and that exact bug,  and decided to investigate that get working enough.
We might be able to make it in the next major release (in our optimistic vision) or the next to next. The next major release is still months away, but we branch way earlier to make the product solid enough.)
Comment 8 Dimitar Dobrev 2015-09-16 12:49:03 UTC
Excellent, I am happy to hear there's been some progress about that issue. Parameter names would be really useful. Thank you.
Comment 9 Abhishek 2015-11-23 11:47:11 UTC
I am able to reproduce this issue. Here is the screencast for the same:

To verify this issue I have checked this issue with the latest master build:
mono-android-6.0.99-216_4059261ee02c8339979f555a633c297ada98c8c9. Now new properties on IntentFilterAttribute has been added. Here is the screencast for the same:

Hence closing this issue.

Comment 10 Abhishek 2015-11-23 12:34:22 UTC
An Update to the Comment 9.

I have checked this issue with the latest master build on Windows:

Now new properties on IntentFilterAttribute has been added.
Screencast for VS: http://www.screencast.com/t/0WBx5qtXg
Screencast for XS: http://www.screencast.com/t/qfouepcGGl