[mono-android] Newbie - confused on custom attribute vs AndroidManifest.xml and other things
Jonathan Pryor
jonp at xamarin.com
Sun Feb 19 16:19:25 UTC 2012
On Feb 18, 2012, at 7:57 PM, tweaver60 wrote:
> if I can use a combination of custom attributes, with adding my own items into the AndroidManifest.xml file, such as receiver.
You can, and in some instances, you must.
The rule of thumb is that if the type is written in C# AND it is an Activity, Service, BroadcastReceiver, or ContentProvider, then you should use the custom attributes (which coincidentally have the same name as the base type ;-). Otherwise you must use XML within AndroidManifest.xml.
For example, AdMob provides a Java Activity that you need to add to your AndroidActivity.xml. There is no way to use custom attributes for the AdMob activity, so you must instead add the <activity/> to Properties\AndroidManifest.xml:
<activity android:name="com.google.ads.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"/>
> I am very confused by the following statement in that article: "The merging that mandroid.exe produces is trivial: it uses the custom attributes within the code to generate XML elements, and inserts those elements into AndroidManifest.xml. Elements nested within /manifest/application are not merged, and Properties\AndroidManifest.xml always overrides data provided by custom attributes."
>
> Especially the nesting, since most of the custom attributes I would think go inside the application tag.
That is correct, [Activity], [Service], etc. generate elements within the //application element.
What the text means is this: consider the following type:
namespace Example {
[Service]
public class MyService : Service { /* ... */ }
}
This will generate an Android Callable Wrapper named `example.MyService`, and would normally generate the appropriate XML:
<!-- generated based on custom attributes -->
<service android:name="example.MyService" />
HOWEVER, if your AndroidManifest.xml _already_ contains a declaration for that type:
<!-- within Properties\AndroidManifest.xml -->
<service android:name="example.MyService" android:enabled="false" />
then the Properties\AndroidManifest.xml version overrides whatever you specified in the custom attributes. So if you update your C# code:
[Service(Icon="@drawable/foo")]
public class MyService : Service { /* ... */ }
the resulting AndroidManifest.xml will NOT contain a //service/@android:icon attribute, because you already provided the //service[@android:name="example.MyService"] element.
As the documentation states, no merging is done: it's one or the other, and AndroidManifest.xml trumps custom attributes.
> Ultimately, my goal is to create a widget, but the tutorial I found (using Eclipse/Java) discusses creating an XML to define the AppWidget provider
Presumably it's something like this:
http://developer.android.com/guide/topics/appwidgets/index.html
The XML it uses is a <receiver/> element, so you could just use the [BroadcastReceiver] custom attribute to generate the <receiver/> element. That example also has <intent-filter/> and <meta-data/>, which also have custom attributes defined:
[BroadcastReceiver]
[IntentFilter (new[]{"android.appwidget.action.APPWIDGET_UPDATE"})]
[MetaData ("android.appwidget.provider", Resource="@xml/example_appwidget_info")]
class MyAppWidgetProvider : Android.Appwidget.AppWidgetProvider {
// ...
}
However, there are no custom attributes for the <appwidget-provider/> element, so that would need to be manually provided (and it wouldn't be within AndroidManifest.xml either; "Define the AppWidgetProviderInfo object in an XML resource...").
> and I'm not sure where to place that XML file, since the folder structure is quite different from the Mono for Android structure.
It's not that different. What Android calls "res" we call "Resources"; the contents are the same. Thus, for an XML resource, you'd want to create Resources\xml\example_appwidget_info.xml. Don't forget to set its Build action to AndroidResource; failure to do so will prevent the resource from being added to the Android package.
- Jon
More information about the Monodroid
mailing list