The “UNAVAILABLE: Trying to connect an http1.x server” gRPC error

I’m working with on C# client library using gRpc. This is not a web based library where there’s a need for envoy or other application to help work with HTTP2. Instead this was on a C# client using tcp/ip.

Everything was working fine on my machine until the machine was relocated (not that this specifically was the problem as I later found out others were having similar problems, some times intermittently) at which point I found that the client would exception with the message “UNAVAILABLE: Trying to connect an http1.x server”.

Note: if you turn on all exceptions within Visual Studio, you’ll firstly see an exception where grpc tries to get a Value from a Nullable when it’s null (this was the call to Native.grpcsharp_batch_context_recv_message_length). This is a red herring, it’s simple that the nullable is null which seems to be expected behaviour, maybe should be handled in the gRPC .NET library code.

Testing the client on another machine demonstrated the problem was seemingly network related, turns out it was HTTP proxy related to be precise.

This doesn’t seem to be too well documented from what I could tell, but setting the ChannelOption grpc.enable_http_proxy to 0 (see https://grpc.github.io/grpc/core/group__grpc__arg__keys.html) fixed the problem.

var channel = new ManagedChannel(
   host, 
   port, 
   ChannelCredentials.Insecure,
   new []{ new ChannelOption("grpc.enable_http_proxy", 0)} );

Controlling a Philips Hue

First off, the Philips Hue bridge exposes a web server, so take a look at the wireless connections on your network (see also How to develop for Hue) for other methods of locating your Hue bridge on the network.

Much of the information in this post is taken from How to develop for Hue?. More information is available if you register as a Philips Hue developer.

Once you’ve located your bridge IP address you can use a web browser to connect the CLIP API Debugger, i.e.

https://<bridge ip address>/debug/clip.html

The Hue bridge API

The first thing we need to do is a key for interacting with the device. The Hue actually calls this your username and it’s a randomly generated string, once we have this we have an authorise user.

So for example if you try to use any command without a key you’ll get a response along the following lines

[
  {
    "error": {
      "type": 1,
      "address": "/",
      "description": "unauthorized user"
    }
  }
]

Creating our user

To get our username and thus create an authorized user, we use the following API

  • Method: POST
  • Url: /api
  • Body: {“devicetype”:”my_hue_app#my_name”}

The “my_hue_app#my_name” appears to simply be a unique resource name. Before you run this command you should press the link button on the Hue bridge then execute this HTTP request.

If all works correctly you should get a response like this

[
  {
    "success": {
      "username": "sYA1egf8VZteeIWnXmlIdrxFE3uHgUr-jk2Vrt12"
    }
  }
]

Now we use the username value (i.e. sYA1egf8VZteeIWnXmlIdrxFE3uHgUr-jk2Vrt12) in our method calls going forward.

Getting more information

  • Method: GET
  • Url: /api/sYA1egf8VZteeIWnXmlIdrxFE3uHgUr-jk2Vrt12

This will return a JSON response (which it too large to include here) including information on the available lights, their state, brightness, hue etc. along with stored scenes.

Getting light information

  • Method: GET
  • Url: https:///api/sYA1egf8VZteeIWnXmlIdrxFE3uHgUr-jk2Vrt12/lights

If successful, this will return light specific information, such as state, name, brightness etc.

Getting light information for a specific light

If we want to just get information for a specific light, we use it’s ID, by simply appending it the the previous URL, for example we’ll get information for light 1

  • Method: GET
  • Url: https:///api/sYA1egf8VZteeIWnXmlIdrxFE3uHgUr-jk2Vrt12/lights/1

Turning a light on and off

To change the state of a light we append state to the previous URL, for example

  • Method: PUT
  • Url: https:///api/sYA1egf8VZteeIWnXmlIdrxFE3uHgUr-jk2Vrt12/lights/1/state
  • Body: {“on”:false}

We should get a response similar to the one below

[
  {
    "success": {
      "/lights/1/state/on": false
    }
  }
]

More than just on and off

  • Method: PUT
  • Url: https:///api/sYA1egf8VZteeIWnXmlIdrxFE3uHgUr-jk2Vrt12/lights/1/state
  • Body: {“on”:true, “sat”:254, “bri”:254,”hue”:10000}

After executing this, you’ll get a response similar to the following

[
  {
    "success": {
      "/lights/2/state/on": true
    }
  },
  {
    "success": {
      "/lights/2/state/hue": 10000
    }
  },
  {
    "success": {
      "/lights/2/state/sat": 254
    }
  },
  {
    "success": {
      "/lights/2/state/bri": 254
    }
  }
]

C#/.NET Libraries

There are also several .NET libraries for interacting with the Hue, that allows us a better API experience, such as

  • https://github.com/Q42/Q42.HueApi
  • https://github.com/cDima/Hue
  • https://github.com/qJake/SharpHue

References

Become a Philips Hue Developer to light up your ideas

Razor templates in your Xamarin application

I had a situation where I wanted to have a template file made up of HTML along with data supplied by my Xamarin application. There are several options to do this but a Razor template file would be a perfect fit, but how to embed one in my (non-Web) application?

Note: Whilst this post talks about a Xamarin application this should be usable in other types of application.

  • I created a Templates folder (not required for this to work) in my solution.
  • Within the Templates folder I add a new text file but saved with a .cshtml extension, for example EmployeeTemplate.cshtml. Visual Studio 2019 doesn’t have a specific template for Xamarin application, but just naming it with the correct extension works.
  • Select the file in the solution explorer and open it’s properties, set the Custom Tool to RazorTemplatePreprocessor.

Here’s a snippet of the contents within the Razor template file

<div class="row">
  <div>Date: @Model.DateEntered</div>
    <div>
      <div>Employee Number:</div>
      <div>@Model.OrderDetails.EmployeeNumber</div>
    </div>
</div>

Visual Studio will (due the use of the RazorTemplatePreprocessor Custom Tool) generate a .cs file that is a class that we can pass our model into and will process the template file and output a string representing the combination of the template with our model.

To generate our output string we simply use the following code

var template = new EmployeeTemplate() 
{ 
  Model = viewModel 
};

var result = template.GenerateString();

Text to Speech on mobile with Xamarin

Previously I looked at Speech synthesis in Windows with C# but what about speech synthesis on mobile.

Xamarin.Essentials has this covered with the TextToSpeechTextToSpeech class and is included by default when creating a Xamarin Forms mobile application.

It’s really simple to add text to speech capabilities, we simply write code such as

await TextToSpeech.SpeakAsync("Hello World");

As you can see by the use of the await keyword (and the standard Async suffix), the SpeakAsync method returns a task. It also accepts a cancellation token if you need to cancel mid utterance. There’s also an overload which accepts SpeechOptions which allows us to set the volume, pitch and locale.

The second TextToSpeech method is GetLocalesAsync which allows is to get a list of supported locales from the device that can then be used within the SpeakAsync method’s SpeechOptions.

await TextToSpeech.GetLocalesAsync();

Note: It’s fun listening to the attempts at different accents depending upon the locale.

Changing the date/time on the Tizen emulator

To set the date/time on the Tizen emulator

  • Obviously ensure you have the emulator running
  • Right mouse click on the emulator
  • Select Shell
  • Type su to switch to super user or you’ll get an “Operation not permitted” error
  • The default password is tizen
  • Type date –set=”27 Mar 2020 23:59:45″ and press enter
  • Tizen is a Linux based OS, hence we can use Linux commands in the shell.

Adding a Tizen project to Xamarin Forms

The great thing about creating a Xamarin Forms project is that you can create projects for Android, iOS and UWP at the same time, but there’s no options for Tizen.

Assuming we’re installed the Tizen Visual Studio templates, then it’s easy to add Tizen to an existing Xamarin Forms project and have it use the shared code project.

Assuming you’ve already created a Mobile App (Xamarin.Forms) application (mine’s called MyProject) and selected Android, iOS and UWP, now…

  • From File | New | Project select the Tizen XAML App (Xamarin.Forms) project, name the project along the lines of MyProject.Tizen
  • After you click Create you’ll be presented with the Tizen Project Wizard
  • Select Common (if not already selected) and leave Mobile, TV etc. options unchecked
  • Select the option Select Project in Solution and choose the shared project name, i.e. ours is MyProject
  • Click OK

Now you’ll see the Tizen project and it’s already set up to use your project’s shared code. So we can write our XAML for all four platforms. Obviously if we’re aiming to deploy to a watch (for example) we’ll need to optimise the XAML for this type of device. We use OnIdiom, for example

FontSize="{OnIdiom Watch=Small, Phone=Large}

and we’re done.

Custom Fonts in Xamarin Forms

First off, this post Fonts in Xamarin.Forms is a far more complete description of all things font related in Xamarin Forms than this post will be, so go check it out.

In this post I’m just going to discuss how we can add and use “custom” fonts, i.e. fonts not on a device by default.

Custom Fonts

In this instance a custom font simply means a font that’s not, by default, loaded onto a device.

We can find lots of free fonts etc. via Google Fonts.

As per the previously mentioned Microsoft/Xamarin post, we’ll demonstrate things using the Lobster-Regular.ttf font.

Within Google Font simply search for Lobster and then download the Lobster.zip to your machine. If you then unzip this file you’ll have two files, the .ttf and a license file.

To look at the font and/or to get the Font name, in Windows we can right mouse click the .ttf file and select Preview. Hence we see the following

  • Font name: Lobster
  • Version: Version 2.100
  • OpenType Layout, TrueType Outlines

We also see a sample of the font for the alphabet, but more interestingly a sample for different font sizes, 12, 18, 24, 36 etc.

Preview Feature

Within the previously mentioned post they talk about adding your custom font to the shared project of your Xamarin Forms application. This was a preview feature and at the time of writing this post, I was unable to see this work. Hence this post will be out of data as soon as this is implemented. However for completeness I’ll relay what the post says on this.

To add a custom font to your shared project…

  • Create a Resources/Fonts folder (this folder configuration isn’t a requirement)
  • Add your .ttf or otf font files to this new folder and mark their properties as Embedded Resource
  • In the AssemblyInfo.cs file (for example) ad the ExportFont attribute, for example
    using Xamarin.Forms;
    
    [assembly: ExportFont("Lobster-Regular.ttf")]
    
  • Using the font is then as simple as writing the following

    <Label Text="Hello Xamarin.Forms"
       FontFamily="Lobster-Regular" />
    

    Existing/non-preview usage

    So, as mentioned, I was unable to get the preview working at this time, so let’s look at the “current” way to implement custom fonts. Let’s therefore assume we did not do any of the Preview steps.

    For Android…

    Copy your .ttf or .otf files into your Android project’s Assets folder and mark them as AndroidAsset via the file’s properties option in Visual Studio.

    Now it the shared project we need to reference the font slightly differently

    <Label Text="Hello Xamarin.Forms"
       FontFamily="Lobster-Regular.ttf#Lobster Regular" />
    

    For iOS…

    Copy your .ttf or .otf files into your iOS project’s Resources folder and mark them as BundleResource via the file’s properties option in Visual Studio.

    There’s and addition step, where we need to add the font(s) to the info.plist, i.e.

    <key>UIAppFonts</key>
    <array>
        <string>Lobster-Regular.ttf</string>
    </array>
    

    The big difference to the Android example is that the code only has the typeface name, for example

    <Label Text="Hello Xamarin.Forms"
       FontFamily="Lobster-Regular" />
    

    For UWP…

    Copy your .ttf or .otf files into your UWP project’s Assets folder and mark them as Content via the file’s properties option in Visual Studio.

    As per the Android example, the code would look like this within the shared project

    <Label Text="Hello Xamarin.Forms"
       FontFamily="Lobster-Regular.ttf#Lobster Regular" />
    

    Different fonts for different OS’s

    As you’ve seen in the examples for setting the FontFamily attribute, Android and iOS differ in what they expect, so we’re going to need a better way to supply this value. Or it may be we actually want different font’s on different devices.

    We can create a style and use OnPlatform capabilities of Xamarin Forms to achieve this.

    i.e. in this example we’ll set the fonts

    <ResourceDictionary>
      <OnPlatform x:TypeArguments="x:String" x:Key="LabelFont">
        <On Platform="Android" Value="Lobster-Regular.ttf#Lobster Regular" />
        <On Platform="UWP" Value="/Assets/Lobster-Regular.ttf#Lobster Regular" />
        <On Platform="iOS" Value="Lobster-Regular" />
      </OnPlatform>
    </ResourceDictionary>
    

    and then we can change our Label sample code to the following

    <Label Text="Hello Xamarin.Forms"
       FontFamily="{StaticResource LabelFont}" />
    

    Sample Project

    See https://github.com/putridparrot/blog-projects/FontTestApp

Creating an Android Virtual Device

Whilst running Android applications on a real device is pretty quick nowadays, it’s still useful to run our apps against an emulator.

In this post we’re going to look at creating an emulator which works/looks like a Samsung s10e.

Device information and skins

In the case of Samsung devices, simply visit Samsung, Emulator Skin Overview.

Here you can find skin downloads (to give your emulator more of a look of the device) along with device information, such as screen size, resolution etc. Download the skin.

Note: You’ll need to be registered on the Samsung developer site to download the skins, but it’s a painless process.

In the case of the s10e, the device has a 5.8 inch display and a resolution of 1080×2280. So we’re put that information into our virtual device in a minute, before we do that, extract the downloaded skin into the following folder

%USERPROFILE%\AppData\Local\Android\Sdk\skins\samsung_s10e

Now we’re got all the relevant skin related files let’s move onto creating our virtual device.

Android device manager

From Visual Studio or Android Studio, locate the button to run the Android Device Manager. In either case either press New… or Create Virtual Device…

To save trying to describe both UI’s I’m going to stick with the Android Studio UI. So after click on Create Virtual Device, do the following

  • Click New Hardware Profile
  • Set Device Name to Samsung S10e
  • Ensure Device Type is Phone/Tablet
  • Set screen size to 5.8
  • Set Resolution to 1080 x 2280

Leave all other options as they are but now scroll down to the Default Skin option. Clicking on the … button does nothing until you switch from No Skin to select a skin, any skin will work. Don’t worry if you get a warning about the skin not being the right size as we’re going to change it now. Click on the … button and locate the samsaung_s10e folder we put the skin files into.

Finally, click Finish.

  • With the new device selected, press the Next button
  • Currently the s10e is running Android Pie API Level 28, so select this or your preferred version of Android
  • Press Next and if all looks good, then press Finish

If you need to edit the configuration you can do so via the Android Virtual Device Manager, you’ll need to select the device and then click the edit button. You’ll need to click the Show Advanced Settings button to change memory, or if you wish to change the skin.

Multilingual App Toolkit (MAT)

I’ve previously looked at the MAT in the post Adventures in UWP – Globalization & Localization UWP – Globalization & Localization. I’ve also used this within mobile applications using Xamarin Forms which I was about to update, but then realised I’d forgotten how this stuff worked.

Requirements

Before we start, we need to install a couple of things.

  • From Visual Studio 2019 (if not already installed) select Extensions | Manage Extensions and download the Multilingual App Toolkit. You’ll need to restart Visual Studio for the installation to take place.
  • Install (if not already installed) the Multilingual app toolkit 4.0 Editor as this is extremely useful for managing our translated files, but is NOT required.

Note: This does not currently seem to be supported in Visual Studio for Mac.

Mobile Application

Let’s start by creating a Xamarin Forms application to see how things work.

  • Create a Mobile App (Xamarin.Forms) in Visual Studio
  • Add a Resources folder to the shared project and then add a Resource File item to this folder, named AppResources.resx
  • Right mouse click on the shared project and select Properties, now select Package and towards the bottom of this screen, change the Assembly neutral language to your default language – for example mine’s English (United Kingdom). In other words our project culture will be set to en-GB
  • Enable MAT by selecting Tools | Multilingual App Toolkit | Enable on your solutions

At this point we now have the basics in place to begin localizing our application. We can now start adding strings to our AppResources.resx or alternatively we could start adding new languages, so let’s do that.

  • Right mouse click on your shared project and select Multilingual App Toolkit and from this select, Add translation languages…

Note: You may get and error regarding the need to install translation providers, this requires us to add an Azure subscription, but we don’t actually need this to use the tools, so just ignore this error for now.

From the Translation Languages check on any languages you want to support (you can also add languages at any point so don’t worry if you need to add more at a later date).

In my case I’m going to add German [de] and French (France) [fr-FR]. Once you press OK you’ll see two additional AppResources files added to the Resources folder, AppResources.de.resx for German and AppResources.fr-FR.resx for French.

You’ll also see the MultiligualResources folder with two .xlf files, one for German and one for French, these are used by MAT to generate our new AppResources files.

Note: Do not edit the localized AppResources.*.resx files by hand. Only AppResources.resx should be edited.

Editing our resources

Now that we have the xlf files and the default culture AppResources.resx file, we’ll want to start adding some strings.

Open the AppResources.resx file in Visual Studio and add some named strings, the Name being the identifier or key, the Value being the string to display and we can also add comments which might be useful for somebody who handles the subsequent translations.

So I’m going to create a basic login page, hence we’ll add the following

  • Name: Welcome, Value: Welcome to the application
  • Name: Login, Value: Login
  • Name: Username, Value: Username or email address
  • Name: Password, Value: Enter your password

Now build your application before we look to create some translations.

There’s a couple of ways to proceed with this, the simplest is as follows

  • From Visual Studio. Select you MultilingualResources folder or each .xlf in turn.
  • Right mouse click on the folder or file then select Multilingual App Toolkit | Generate Machine Translations.

You may find that some values are not translated, for example in my case Welcome to the application was not translated, we can edit the de.xlf file directly. In this case I change the target element to Willkommen bei der Anwendung and changed the target state to needs-review-translation

Once you’ve made your changes then build the project and MAT will generate the AppResources.*.resx files.

The second way to handle the translations and probably one that would be useful for people who are working on translations of your application. In this case we use the Multilingual Editor that was installed earlier. Open each of your xlf files in turn. For each one we’ll see a list of the strings as entered into the AppResources.rex file. So let’s concentrate on editing the .de.xlf German translation file.

  • Having opened the .de.xlf file, select the Strings tab at the bottom of the screen to ensure all the strings were added, now here we could manually translate each row by selecting the each row in turn, then changing the Translation in the editor in the middle of the editor UI.
  • If you edit the translation yourself then the State on the right of the screen will switch to Translated. This state will tell the MAT editor whether it should try to translate the value. If the user has marked the state as Translated we can assume this is correct and the editor will not attempt to translate the string using it’s generate translation option. You can change this State back to New if you want the auto-translation to take place.
  • If you prefer or like me you’re simply going to use something like Bing or Google to do the translations, i.e. https://www.bing.com/translator/. Then the Editor offers the Translate button. Clicking this will generate translations for all the text and mark them with the State Needs Review which is basically saying that the translation was made but needs somebody to review whether this makes sense in each language. You can leave this State as is or change to Translated if you’re happy with these translations.
  • Once completed, save the file(s) and build your solution to get the AppResources.*.rexr updated.

Displaying our translations in an application

Note: This post has been updated as the previously used Multilingual plugin is no longer required.

We can display translations is XAML using the AppResources generated code, for example

Title="{x:Static resources:AppResources.Settings}

and in code just as easily we use

var title = AppResources.Settings;

To test your translations you can set things up in code, i.e.

In your App.xaml.cx, after the InitializeComponent you can place the following code to set the culture to that of the device

var culture = CrossMultilingual.Current.DeviceCultureInfo;
AppResources.Culture = culture;

If you want to test your German translation, for example, replace these two lines with

var culture = new CultureInfo("de");
AppResources.Culture = culture;
CrossMultilingual.Current.CurrentCultureInfo = culture;

See https://github.com/putridparrot/blog-projects/tree/master/MatTestMobile for a sample application.

If you prefer to use the Android Emulator to set your language – which ofcourse makes a lot of sense, then go to Android Settings | System | Languages & input | Languages then Add a language if the one you want is not listed, then drag and drop that language to the top of the Languages list and Android will switch to that language.

Application lifecycle within Xamarin Forms

You’ve got your Xamarin Forms (or native Android/iOS) application up and running and now you need to start thinking about what happens when your application hibernates.

An application can go into hibernation (or sleep mode) and then resume at some point. The OS hibernates an application in response to events, such as power off or lock screen but also if it’s running low on memory. Therefore, so that our application “places nicely” on the OS, we need to think about how we will persist state and restore state during this hibernation phases.

Let’s look at the various methods in Xamarin Forms for handling different aspects of the application’s life cycle…

Xamarin Forms

Initialization/Starting

By default a Xamarin Forms application will create an OnInitialized method which is basically where the InitializeComponent method is called. It’s a good place to set up any initialization for your UI elements etc.

Assuming we’re starting our application from cold (i.e. first start) Then the following lifecycle methods are called in order

  1. OnInitialized
  2. OnStart

According to the App Lifecycle documentation “On Android, the OnStart method will be called on rotation as well as when the application first starts, if the main activity lacks ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation in the [Activity()] attribute”.

So OnInitialized remains the best place to set defaults up, but OnStart may be the best place to make any UI changes based upon orientation etc.

Entering sleep mode

If the device goes into sleep mode (we can simulate easily by hitting the power button on our emulator or device). The following is called

  1. OnSleep

This is our opportunity to persist state from the device so that when we resume the application it’ll appear in the same state as when it went into sleep mode.

There’s various ways to achieve this, if we’re using a pure MVVM approach with Prism (for example) we might use the EventAggregator to send a sleep message to all listening view models etc., which would then persist their data, or maybe we hold a cache (or similar) as a single data store and we persist this. Whichever way we go, the intention is that everything that is required to get the application back to the state pre-sleep, needs persisting. This also includes things such as which view (in a multiple view application) is displayed along with things like the view stack – well you get the idea, it depends how far you want to go to recreate the state of your application.

Note: another useful way to deal with view model data etc. is to actually persist it automatically when it changes, I don’t mean for every change of an entry control, but for example if you get data from a service, then you might store this in a cache and persist at the same time – obviously it depends on your specific scenarios and design.

Resuming from sleep mode

When an application is resumed, the following is called

  1. OnResume

At this point we need to read any persisted data, hydrate our data/view models with this previously stored data and then get the application back into the state it was when it went into sleep mode. As mentioned for OnSleep, this includes any changes to the UI to put the correct view in place. Basically the user should not even realise that the application was, essentially, closed and restarted.

To test OnResume we simply click the power button on the emulator or unlock the device at which point OnResume will be called.

References

Xamarin.Forms App Lifecycle
Android Activity Lifecycle
UIApplicationDelegate Class