.NET MAUI - James Montemagno https://staging.montemagno.com/tag/net-maui/ https://staging.montemagno.com/content/images/2017/08/MonogramIcon_Orange_NoBuffer.png .NET MAUI - James Montemagno https://staging.montemagno.com/tag/net-maui/ Hugo -- gohugo.io Tue, 13 Oct 2026 20:48:55 GMT 60 Developing Android Apps on Windows Arm Devices https://staging.montemagno.com/developing-android-apps-on-windows-arm/ 644961ecfaa091003df357e4 Thu, 27 Apr 2023 23:00:11 GMT

I have gone all in on Arm devices! My main MAC machine is a Mac Book Air M1 and now my main driver at work is a Windows Dev Kit 2023 (aka Project Volterra). One tricky thing for developers is getting all the software we use to work properly on Arm. Things have come a long way since the original release of Arm devices for Mac and Windows. I have a full setup guide for my M1 for Xamarin and now .NET MAUI development, but what about Windows?

Visual Studio 2022 recently released a full native Arm version and they have been adding more workloads for developers to use. .NET MAUI was recently introduced, which got me excited but I right away ran into an issue, which was that there are no compatible Android emulators for Windows Arm and apparently no plans from Google :(. So, what are our options? Two come to mind.

Deploy to a device

Well, it may be obvious, but you can just plug in a device and use something like Vysor to mirror your device. I am always a fan of deploying and testing on devices as you have full access to everything including Google Play services. As a bonus you don't drag down any resources on your main machine. If you don't have a device, you are still in luck!

Windows Subsystem for Android

That's right! I have blogged and talked about it a bunch, but the Windows Subsystem for Android(WSA) is a great way to deploy and debug applications on any Windows 11 machine. It has expanded into more regions since its first release, which is awesome. If you haven't heard about WSA, it is a mode that you can enable that allows you to run Android applications directly on your Windows machine. There are limitations of course, the largest being no access to Google Play services, but for a lot of developers this will get you off the ground running. Checkout my full video:

If you are using Visual Studio 2022 there is a great extension that will help you get up and running and automatically connect.

Once you have it all set up, it is ready and available!

So, there you go! Two ways to get deploying Android apps if you are developing on a Windows Arm device.

]]>
Enabling Users to Manage Subscriptions on iOS/Android https://staging.montemagno.com/enabling-users-to-manage-subscriptions-on-ios-android/ 632f2485ae7288003d7930aa Sat, 24 Sep 2022 16:01:17 GMT

You know I love talking about in app purchases and subscriptions. Due to my InAppBilling library I get all the "fun" updates when Apple or Google force developers to make changes to stay compliant. Upcoming is a nice large change from Google to push Android developers to use Billing v4 (which my library does!) and another is that we must now give users a way to easily manage and cancel their subscriptions. You may have recently seen this message from google:

We’re updating our Subscriptions policy to state that users must be able to easily cancel their subscriptions from within the app. {#we%E2%80%99re-updating-our-subscriptions-policy-to-state-that-users-must-be-able-to-easily-cancel-their-subscriptions-from-within-the-app}

What does this mean? What do I need to do Google?!?!! Well if you dig through the documentation you will see that you have to add a button to your purchase screen and also create a deep link to launch the store management screen. Let's see what this looks like in code for Xamarin and .NET MAUI apps:

public async Task ManageSubscription(string sku)
{
    var url = string.Empty;
    if (DeviceInfo.Platform == DevicePlatform.iOS)
    {
        url = "https://support.apple.com/HT202039";
    }
    else if (DeviceInfo.Platform == DevicePlatform.Android)
    {
        if (string.IsNullOrWhiteSpace(sku))
        {
            url = "https://play.google.com/store/account/subscriptions";
        }
        else
        {
            url = $"https://play.google.com/store/account/subscriptions?sku={sku}&package={AppInfo.PackageName}";
        }
    }

    if (string.IsNullOrWhiteSpace(url))
        return;

    await Browser.OpenAsync(url);
}

For iOS there isn't really a requirement or even an API to give users an easy way to manage subscriptions, but I figure why not.

For Android, there are two cases here:

  1. They don't have any non-expired subscriptions and you just launch the generic page.
  2. Your user has a non-expired subscriptions for your app, where expiryTime is in the future or autoRenewing is set to true. In this case you would want to open the subscription page to the very specific subscription for them to manage.

And, that is about it... Well actually you could simplify this entire process by creating a Manage App Subscriptions page on your website and linking to that. Then your code becomes:

await Browser.OpenAsync("https://refractored.com/manage-app-subscriptions");

This should also adhere to the app store guidelines and also you can add additional information. Cheers!

Checkout my videos on YouTube

]]>
App Configuration Settings in .NET MAUI (appsettings.json) https://staging.montemagno.com/dotnet-maui-appsettings-json-configuration/ 62195c853cfb01003d2c9dbd Fri, 25 Feb 2022 23:11:36 GMT

.NET MAUI is right around the corner and Preview 13 is out right now! There are so many great features packed into .NET MAUI and my favorite has to be all of the great Dependency Injection and configuration that goes into the MauiProgram startup. If you want to know more checkout my most recent YouTube video breaking down Preview 13 and all of the configuration that is built in including Essentials, Blazor, and more.

But, what if you want to do other things that aren't included out of the box... such as reading app configuration through a appsettings.json file?!?!? Well you can, and it is super easy! Thanks to the MauiAppBuilder we can use the ConfigurationManager that is built in to configure settings in our .NET MAUI app. First things first, let's add the appsettings.json file as an EmbeddedResource:

{
  "Settings": {
    "KeyOne": 1,
    "KeyTwo": true,
    "KeyThree": {
      "Message": "Oh, that's nice..."
    }
  }
}

Next, let's create a few classes that represent these configuration settings anywhere in the project:

public class Settings
{
	public int KeyOne { get; set; }
	public bool KeyTwo { get; set; }
	public NestedSettings KeyThree { get; set; } = null!;
}

public class NestedSettings
{
	public string Message { get; set; } = null!;
}

We will now need to configure our json file with a few Microsoft.Extensions.Configuration NuGet packages. Added the following into your .csproj:

<ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="6.0.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" />
</ItemGroup>

Now, let's read in our json file, and add it to our builder.Configuration in our CreateMauiApp method after we create the builder:

var a = Assembly.GetExecutingAssembly();
using var stream = a.GetManifestResourceStream("MauiApp27.appsettings.json");

var config = new ConfigurationBuilder()
			.AddJsonStream(stream)
			.Build();

builder.Configuration.AddConfiguration(config);

The code above reads in the manifest resource from the assembly into a stream. You will want to change the MauiApp27 to whatever your assembly name is for your project. After that we load it up and add our new configuration to the builder's main ConfigurationManager. We do this so we can dependency inject our IConfiguration anywhere we want.

Note here that there will be some perf here for reading it in from the file. You should consider if you really need to use appsettings.json as your json is never going to change once compiled up.

We will want to add our MainPage as a Transient into our IServiceCollection in our CreateMauiApp method:

 builder.Services.AddTransient<MainPage>();

Now we can adjust our App.xaml.cs to inject our MainPage:

	public App(MainPage page)
	{
		InitializeComponent();

		MainPage = page;
	}

Then over on our MainPage, we can inject our IConfiguration and then use it when our button is clicked to read in our Settings and bind them together:

	int count = 0;
	IConfiguration configuration;
	public MainPage(IConfiguration config)
	{
		InitializeComponent();

		configuration = config;

	}

	private async void OnCounterClicked(object sender, EventArgs e)
	{
		count++;
		CounterLabel.Text = $"Current count: {count}";

		SemanticScreenReader.Announce(CounterLabel.Text);

		var settings = configuration.GetRequiredSection("Settings").Get<Settings>();
		await DisplayAlert("Config", $"{nameof(settings.KeyOne)}: {settings.KeyOne}" +
            $"{nameof(settings.KeyTwo)}: {settings.KeyTwo}" +
            $"{nameof(settings.KeyThree.Message)}: {settings.KeyThree.Message}", "OK");
	}

Now, if you aren't using constructor injection don't worry as you can still access it manually by exposing the IServiceProvider in our MauiProgram.cs:

public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        //normal builder stuff

        var app = builder.Build();
        Services = app.Services;

        return app;
    }

    public static IServiceProvider Services { get; private set; }
}

Then you can access it via: MauiProgram.Services.GetService();

Either way, you are good to go and you have access to these settings!!!

Want to learn more? Be sure to read the full documentation on Configuration in .NET. Full source code example can be found on GitHub right here!

Want to go farther? Check out Allan Ritchie's awesome Shiny Extensions library at https://github.com/shinyorg/configurationextensions

Checkout my videos on YouTube

]]>
Goodbye Android Emulators, the Windows Subsystem for Android is Here! https://staging.montemagno.com/goodbye-android-emulators-windows-subsytem-for-android-is-here/ 6172b75df2a01a003b1a2b76 Fri, 22 Oct 2021 17:39:00 GMT

Android Emulators have been a pain in everyone's side for pretty much ever. Intel HAXM is great, but limited to Intel, then there were custom emulators like Xamarin Android Player and Genymotion, but required additional installs, and finally Hyper-V support, which brought with it AMD support, and side by side Docker support as well. But now, Windows 11 is here and so is a brand new Insiders Preview that brings with it Android app support, which is CRAZY AWESOME. More so is that you can use the new Windows Subsystem for Android to develop, debug, and deploy your Android apps from your favorite IDE! Let's walk through what you need to do to get it all setup. However, if you want to just watch a video I have that for you as well!

Windows Subsystem for Android

So, what is this thing? Well, it is like the Windows Subsystem for Linux enabling you to have a full subsystem available for Android instead of Linux. Now at this point, you don't have access to 100% Android. It is not a device just sitting there, but instead think of Windows being the OS that can run Android apps. There is no Android launcher because Windows is the launcher of the apps.

Get Windows Insiders Beta

The first thing that you will need is the Windows Insiders Beta build (not Dev) that matches Windows 11 Build 22000.xxx. You can read all about how to turn on Windows Insiders on their blog.

Windows 11 21H21
Windows 11 21H21

Install Windows Subsystem for Android

Now it is time to install the Windows Subsystem for Android, which also comes with the Amazon App Store. This is done directly from the Microsoft Store on Windows and will require a reboot and some final installation steps.

App Store Listing for WSA
App Store Listing for WSA

Once it is installed you will want to search and pin the Windows Subsystem for Android app.

Search for Android
Search for Android

Developer Mode Setup

Inside of the WSA app you will find all sorts of great options, but a few things to turn on are "Continuous" mode, so the subsystem is always ready to go.

Then, flip on Developer mode:

Notice here that once you turn on developer mode you get instructions on how to connect to adb.

ADB Connect

I am going to steal this part directly from the documentation. To connect to the Windows Subsystem for Android VM for debugging, you have two options:

Recommended Method:

  • Use localhost for connecting to debugging. The IP address of the localhost is: 127.0.0.1:58526. Windows Subsystem for Android must be running in order to connect, the best way to launch Windows Subsystem for Android is by launching an Android app that was installed with the Amazon Appstore.
  • To connect to the localhost address of Windows Subsystem for Android, enter: adb connect 127.0.0.1:58526

Alternative Method: Use the Windows Subsystem for Android Settings app to get the IP address.

  • Launch the Settings app. (Use Windows Search to select and launch.)
  • The IP address will be displayed under the IP address section. If there is no IP address being displayed, launch an Android app that was installed using the Amazon Appstore, then select Refresh on the IP address button in the Settings app.

Now that you have the IP address to connect to the Windows Subsystem for Android VM, connect using adb connect: adb connect 172.22.137.166

Originally, I had to connect through the IP address, however after a reboot and relaunching WSA, I got a firewall prompt and then 127.0.0.1 started working for me.

Debug!

Now that you are connected via ADB, WSA will just show up in your IDE of choice because it is a device!

Debug away!

Your Apps are on Windows

That is right, your apps are on Windows! You don't need to boot things up to see your app because they are literally in the start menu!

Also, when you open the app setting, they are the Android app settings! How cool is that!?!?!

Limitations

There are a few things to be aware of with WSA. There is no Google Play Services, so if you are testing out maps or other services that is not going to work. It isn't an emulator, which means you don't get to control the skin or conditions under where your app runs since it is running under WSA, not an emulator. Not every sensor is connected, for example it looks like Bluetooth isn't forwarded to WSA from your Windows machine. I also haven't found a way for apps running under WSA to talk about to the local machine for debugging web servers, but I am sure it is a matter of time before someone figures it out.

However, this is the very first preview of WSA and I am extremely happy with it! I love it and never want to open an Android emulator ever again!

Checkout my videos on YouTube

]]>