Search code examples
androidxamarinxamarin.formsandroid-widget

How to specify a full android package name for external apps using Xamarin Forms?


I am having trouble creating a widget configuration activity using Xamarin Forms. What I think is going on is, when compiled, the name of the package gets replaced by a random #/string for the main activity and whatnot. However, if I inspect the resulting APK, I can see that the <appwidget-provider ... android:configure="my.package.myClass".../> does not get updated. I think it should be <appwidget-provider ... android:configure="randomstring.myClass".../>. So I believe this is preventing the configuration screen from appearing. Is there a way to force the package name on this attribute to be updated using Xamarin? Or is there a way to set this attribute in code before it gets called during widget placement?

Here is my configuration (package name has been simplified to help debug):

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="288dip"
    android:minHeight="72dip"
    android:resizeMode="horizontal"
    android:minResizeWidth="144dip"
    android:updatePeriodMillis="1000"
    android:initialLayout="@layout/Widget"
    android:previewImage="@drawable/previewImage"
    android:configure="quickclip.QuickClipConfigActivity"

/>
namespace quickclip
{
    [Activity(Label = "QuickClipConfigActivity", Name= "quickclip.QuickClipConfigActivity", Exported=true )]
    [IntentFilter(new string[] { "android.appwidget.action.APPWIDGET_CONFIGURE" })]
    public class QuickClipConfigActivity : Activity
    {
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            SetContentView(Resource.Layout.Setup);
            SetResult(Result.Canceled);


            // Create your application here
        }
    }
}

The name field of the [Activity] attribute was just added for debug purposes. With or without it, placing the widget does not display the config screen, nor does it enter the activity class (verified by breakpoints), nor does the widget display. However, if I remove the android:configure="my.package.myClass" I can get the widget to appear normally.


Solution

  • If you don't explicitly specify it, Xamarin.Android will calculate some MD5 and use that to prefix all Android Callable Wrappers with that MD5 for the namespace.

    To avoid that you can use the RegisterAttribute on your types:

    [Register("my.cool.namespace.MyType")]
    public class MyType : SomeJavaType
    {
    }
    

    For an Activity or Service you can use the Name property in the ActivityAttribute or ServiceAttribute like so:

    [Activity(Label = "My Activity", Name = "my.cool.namespace.MyActivity")]
    public class MyActivity : Activity
    {
    }
    

    Or you can combine the ActivityAttribute with the RegisterAttribute:

    [Register("my.cool.namespace.MyActivity")]
    [Activity(Label = "My Activity")]
    public class MyActivity : Activity
    {
    }
    

    This should produce a nice entry in your AndroidManifest which is easy to use from either layout files or other Apps/Widgets.