Tuesday, August 15, 2017

LiveXAML and Xamarin.Forms

Full disclosure. This blog post is sponsored by LiveXAML. I was sent a free license to try it out and mention it in a blog post. All opinions are my own and I was not paid to say nice things about the product.
I do not usually work with Xamarin.Forms, but Mihhail from LiveXAML contacted me and asked whether I wanted a license for LiveXAML to test out and mention them in a blog post. I thought "why not", and here are some brief thoughts and experiences with the tool.

First of all, LiveXAML is not the only product on the market. There are other players, such as Continuous, Gorilla Player and now Xamarin also have their Live Player. They all function a little bit different from each other, but their goals are very much the same. To show changes in the UI, while you are writing code.

I tried LiveXAML with the following setup:
  • Visual Studio 2017 15.2
  • Xamarin.Forms 2.3.4.247
  • LiveXAML 1.2.12
  • Android x86 7.1 image running in a Hyper-V VM
The project I worked with LiveXAML in was a sample project, where I have a ListView showing some images and names of cheeses. All the code was contained in a PCL. To get LiveXAML working I simply installed the Visual Studio 2017 extension. I also installed the LiveXAML NuGet into the PCL project.
For projects using Shared projects, you need to install LiveXAML into your application projects, which consume your Shared project.

This is basically it. Once the very small setup is done, you are ready to play around. Just start debugging your application. Fire up a XAML page and start editing. Every time you press save, LiveXAML will pick up the changes and they will quickly be reflected in the UI in the App.


See the video above to see it in action. In this video I edit some simple XAML, where I change the height and width of the images, then apply a transformation to add rounded borders. Every time I press CTRL + S to save, the emulator updates the view, which is super usefull when playing around with UI in XAML.

LiveXAML seems to work pretty well and seems stable, I only tried it in a Xamarin.Forms Android project, but the LiveXAML web page says that iOS projects work as well. There is also some preliminary VS4Mac support for those of you who use that. It installed and ran fine in an emulator, that is not mentioned as supported on the web page, which is great. It ran with external assemblies, in this case FFImageLoading, where images and transformations where shown correctly. To me it seems that any valid XAML will work with LiveXAML and be rendered on the device!

The difference between LiveXAML and Xamarin Live Player, is that with the former, you install a server in your app, which a plugin in Visual Studio can send commands to. So when saving your XAML it sends a payload which then is rendered on the screen.
With Xamarin Live Player, you don't add dependencies to your app. However, instead you install an App on your device you want to run on, then there is a pairing process with the IDE. Running the app, it seems like it is running inside of the Xamarin Live Player app and changes to any part of your code is reflected. This works with coded UI as well.
Like LiveXAML, Gorilla Player seems to be limited to XAML based UI and it would seem it works in a similar fashion, where your project takes a dependency on a Gorilla Player nuget and you need to set up Gorilla Player in your App startup.

All in all I was quite pleased how well LiveXAML works and how easy it is to get started. It just works. I have not tried it on a real device, but given that the device is on the same network as your PC, I think it may work just fine. If I were making Xamarin.Forms applications professionally, I would really consider LiveXAML as a means to create and debug XAML layouts.

Wednesday, June 28, 2017

Upgrade notes for MvvmCross 5.x on iOS

This post is just a couple of notes about some of the changes that affected some of my apps when updating to MvvmCross 5.x on Xamarin.iOS.

IMvxModalIosView or MvxModalNavSupportIosViewPresenter could not be found

MvvmCross has replaced the presenter logic, which before looked for the IMvxModalIosView interface in order to figure out how to present a ViewController. You should instead use the MvxModalPresentation attribute for your ViewController.

Previously you also had to use MvxModalNavSupportIosViewPresenter for it to understand the IMvxModalIosView interface. This is now all baked into the default presenter.

For this attribute you can also give it a couple of hints about how to display itself through a couple of properties.

  • Animated, set this to false to disable animations when presenting your modal ViewController, defaults to true
  • PreferredContentSize, set this to your content size on iPad, since they are not shown full screen default there
  • ModalTransitionStyle, set this to the desired transition style, cover, flip, cross dissolve or curl, this will not work when Animated is set to false, defaults to CoverVertical
  • ModalPresentationStyle, set this to the desired presentation style. This depends on the LayoutSize and in most cases on iPhone will default to FullScreen. This is mostly to change presentation on iPads.
Here is how the changes will reflect in your code:


Changing to the new presenter for Modals is pretty painless.

CreateNavigationController has changed signature

The MvxIosViewPresenter has changed the signature of CreateNavigationController, this is luckily a very simple change.

MvxTabBarViewController is presented as child?

Another thing in the new presenter for iOS, is that some ViewControllers, cannot be presented as children and need to be presented as root instead. This is something that will be fixed in MvvmCross 5.0.4 since this is unwanted behavior. You should be in control of how you want your ViewControllers presented. For now in 5.0.0-5.0.3 you can make a small change to fix this.


MvvmCross.Dialog is gone?

Yes. It was unmaintained and upstream MonoTouch.Dialog has been unmaintained for just as long time. The MvvmCross team does not want to support something that no one wants to fix.

What should you use instead? How about Xamarin.Forms? Or plain iOS Tables and Views? Sorry, no shortcuts here. You could recompile Dialogs from MvvmCross 4.x against 5.x yourself.

What I have opted for is using MvxTableViewController and making my own Adapters for cases where I need to display different kind of cells, groupings etc. It is not that much work and you are not dependent on a 3rd party library here. You can still bind MvxTableViewCells to whatever you want and TwoWay bindings work much better than MonoTouch.Dialogs ever did.


Friday, December 23, 2016

Identifying users with HockeyApp

I use HockeyApp for crashes and App analytics. Most of the time users that are logged into the App have different accounts than what they use with HockeyApp, so most of the time I can't use the LoginManager.

Instead, to Identify users I do the following instead.

Android

Create an implementation of CrashManagerListener, which overrides UserID, Contact and Description.
Then use it as follows when registering the CrashManager

iOS

On iOS you need to implement BITHockeyManagerDelegate where you need to override UserIdForHockeyManager(), UserNameForHockeyManager() and UserEmailForHockeyManager().
Then right before starting the SharedHockeyManager you need to register your Delegate.
Now the User and Contact columns in a crash report on HockeyApp should be filled out with the values you provided.

Friday, November 11, 2016

Firebase Cloud Messaging in Xamarin.Android

I've seen people asking a lot about this lately on XamarinChat Slack. Looking around there does not seem to be much good information on how to get Firebase Cloud Messaging (FCM) to work in a Xamarin.Android project. I made the switch in one of my apps a month or so ago, from Google Cloud Messaging to FCM and I too was lacking the information about how to get this to work. I did get it to work by piecing together information from the Java world. Surprisingly enough it is not that much different in Xamarin.Android.

1. Creating a Firebase Project

If you have not already created a Firebase project you need to do so now. You can either opt to import an existing Google project or Creating a new. Either way the instructions are pretty much the same.

1. Go to the Firebase Console

2. Create a new project or import Google Project


I don't think it is super important what region you choose your project to be in. I just chose the region where I expect the most users to use my App.

2. Registering Application

When you have created your project or imported an existing one you can now add your application. This can be done several places in the console. I just went to Notifications and it prompted me to add an application.
Pressing the Android icon will show you the following dialog
Here you need to enter the details of your Application. Package name is the package name you have set in your AndroidManifest.xml file. You might want to change that to something resembling your namespace in your app. Make sure that it is all lowercase too. Nickname is optional and is just an easy way to identify your app in the Console. Press Add App or optionally do step 2.1 first to add a SHA-1, then press Add App. The browser will now download a google-services.json file, which we will use later, in step 4.

2.1 Creating a keystore (optional)

If you haven't already created a keystore file for your App, you can do so now. For more information refer to the Xamarin Documentation.
You will need it for deploying to Google Play Store anyways. You will need it for Google Play Services, such as Google Maps. Easiest way to do so is through the Archive tool in Visual Studio or Xamrin Studio, which you can trigger by right clicking your Android Application project. Make sure to have selected Release Configuration and your App can build.
At the bottom of the Archive screen, when an Archive is ready, click Distribute... > Ad Hoc > +
A dialog for creating a new keystore will appear, which you will need to fill out with relevant details. Create your keystore and now we need to find it on the computer.
Note: A keystore is used to sign the application, for deployment on the Google Play Store. Many Google Play Services require a SHA-1 entered into the Google Console for your App package
On Windows, Xamarin Archives put the keystore in C:\Users\<username>\AppData\Local\Xamarin\Mono for Android\Keystore you can find the one you just created in a subfolder maching the name of the keystore you just created. To get the SHA-1 from a keystore you run the keytool command line tool. If it isn't in your environment PATH, it is located in the Java SDK folder. In my case C:\Program Files\Java\jdk1.8.0_102\bin lets just assume you don't have it in your environment PATH the command to get the SHA-1 would look something like

"C:\Program Files\Java\jdk1.8.0_102\bin\keytool.exe" -exportcert -list -v -alias yourkeystorealias -keystore C:\Users\<username>\AppData\Local\Xamarin\Mono for Android\Keystore\fcmtest\fcmtest.keystore

yourkeystorealias being the name of your keystore in this case. Although a keystore can contain multiple aliases, which the Xamarin Archive tool does not seem to care about. The output will look like follows
We need the SHA-1, you can enter that in the certificate SHA-1 for your Firebase Project.
You can also grab the one from the debug.keystore in the C:\Users\<username>\AppData\Local\Xamarin\Mono for Android folder and enter that later as an additional fingerprint in the Firebase console.

3. Adding FCM NuGet to your project 

Before we proceed and before we can do 4. where we add the google-services.json to our project. We need to add some NuGet for the FCM stuff, but also for the Build Action needed in 4., which comes with the Google Play Services Nuget.

Add the Xamarin.Firebase.Messaging NuGet to your project. Currently there is only a pre-release version of it. Hence you need to tick the Include Prerelease box in your NuGet package manager.

 

4. Adding google-services.json to the application

We will now add the google-services.json file from 2. to the Android project.

Right click your project, select Add > Exisiting Item find the google-services.json in the folder your browser downloaded it to, then press Add.

Now we need to set the build action of that file to GoogleServicesJson.
Note: If the GoogleServicesJson Build Action is not present, follow the instructions in this GitHub issue which tells you to: 1. clean/rebuild your project. 2. restart Visual Studio/Xamarin Studio. 3. make sure that the csproj file includes Xamarin.GooglePlayServices.Basement.targets
Add the Build Action by right clicking the google-servies.json file you added to your project. Click Properties. In there set the Build Action.

5. Adding FCM receivers to the AndroidManifest

Inside the AndroidManifest.xml we need to add a couple of entries for the FCM BroadcastReceivers, which are not added by the NuGet package.

Locate the <application> tag in your manifest. Inside of that node add the following code

${applicationId} will get replaced at build time, with your App's package name. Make sure your package name conforms to Android's guidelines.

6. Implementing FirebaseInstanceIdService and FirebaseMessagingService

Now we need to add two services in our App. FirebaseInstanceIdService, which gives us the token used to identify the FCM registration of this particular device. This is normally used with a backend to tell it how to send notifications to the device.
FirebaseMessagingService is the service, which will be invoked when we receive a notification in the application. Here you prepare the notification to be displayed with data coming from the FCM.

6.1 FirebaseInstanceIdService

In order to receive the token from the App's registration with FCM, we need to implement FirebaseInstanceIdService. In here you would save the token and communicate it to the backend, which sends the notifications to the App.


What I usually do in step 1. and 2. in the todo comment is to check with the token I saved in SharedPreferences whether it has changed and override it if it has. Then I send a request to my backend with the new token.


6.2 FirebaseMessagingService

The FirebaseMessagingService is where we receive our notifications. Here you will get the data out of the notification sent to you. If you have sent extra stuff with your notification, take a look at the Data property on the RemoteMessage argument we get in OnMessageReceived. This will probably also apply to raw notifications that do not trigger any visual feedback.

In either case here is some sample code to get you started. Here I simply grab the Title and Body sent with the notification and present it with an Intent to start my MainActivity. The Intent accepts extras which you can add to it and when the notification triggers your Activity you can pull that data out and act accordingly.

That should be it! Build and fire up your Application and use the Firebase Console to send some test notifications.





The GooglePlayServicesComponents repository that Xamarin has on GitHub, contains a sample application that you can take a look at if you need a starting point. You can also take a look at the documentation from the Firebase Component not yet in the Xamarin Component store.

Tuesday, November 8, 2016

Face detection on iOS

I've been playing a bit with the Camera on iOS lately and released a photo gallery/camera library called Chafu. iOS provides a fairly easy API to do all sorts of stuff, such as reading bar codes, QR codes and some other types of machine readable codes. It also supports finding faces!

So as a fun feature I decided to figure out how to detect a face and show it live in the preview on screen when taking a photo, or recording a video, then add it in Chafu.

Note: iOS 7 added functionality to AVFoundation to do all the above, so what I describe here is iOS 7 and up, keep that in mind if you intend to do this on earlier versions.
In this blog post I assume you already know how to set up a AVCaptureSession, AVVCaptureDeviceInput and AVCaptureVideoPreviewLayer to preview what is coming from the the Camera.

Setup face detection

First we need to add AVCaptureMetadataOutput to our session, this class is what detects faces and requires IAVCaptureMetadataOutputObjectsDelegate to be implemented in the class, which is where we get a callback when faces are detected.

Setting up a AVCaptureMetadataOuput is simple
  1. Instantiate it an instance of it
  2. Add it to the AVCaptureSession
  3. Find out if faces metadata is available
  4. Setup callback if 3. is OK


Notice this in the callback? That is the implementation of IAVCaptureMetadataOutputObjectsDelegate. I decided to add it directly to my Camera class. The implementation looks somewhat like follows.


The exportis pretty important, as this is how we tell the iOS world that we have implemented the interface, it is how it gets hold of our code.

Now hopefully. When you run this code and set a break point in the DidOutputMetadataObjects method, it would get hit when a face is detected. The argument metadataObjects will contain AVMetadataFaceObjects, which contains all you need to visually show the detected faces. 


Display faces

To display faces I like using iOS layers, which gives us the possibility to do rotations and other transformations pretty easily. I will show this later in this post how to utilize the Roll and Yaw from the AVMetadataFaceObject when drawing the visual indicator for a face.

First we need to set up the CALayer we will add detected faces to. This is the easiest as it will be easier later on just to clear the sublayers when we don't want to show faces anymore.


Now we can add faces to that layer in our DidOutputMetadataObjects method. This is done in a couple of simple steps.

  1. Iterate the metadataObjects array, which we get as argument
  2. Make sure these are indeed AVMetadataFaceObject
  3. Transform the object through AVCaptureVideoPreviewLayer's GetTransformedMetadataObject to get the correct coordinates for the face
  4. Create a new CALayer for the face with a border or the desired effect
  5. Set Bounds of the CALayer to what we got from the transformation
  6. Add it as sublayer in the overlayLayer we created earlier
 Lets start by defining a method for how we want this layer which will show the face to look like.



Here I simply create a new CALayer and set the border color, width and corner radius. So what we will see are white squares with border width 2 and rounded corners. Simple!

Now, lets add this layer to the overlayLayer so we can actually see something on the screen.


That is it! Now you should have some squares showing up for faces. One problem though. This might add a whole bunch of layers. So we need to remove the sublayers before adding the new ones.


Call RemoveFaces() method before you iterate metadataObjects in DidOutputMetadataObjects and this should.
The observant reader, might notice that this seems inefficient. I won't cover this in this article. However, you can see one approach to solve this in BaseCameraView in Chafu, where I keep track of the FaceId from the AVMetadataFaceObject and simply adjust bounds for that face if it has moved.

Adjusting for Yaw and Roll angles

The AVMetadataFaceObject gives us a RollAngle for when you rotate your head around the Z axis. It also gives us a YawAngle for rotations around the Y axis.

Picture from StackOverflow: http://stackoverflow.com/q/16401505/368379
Supporting RollAngle is easy as it does not require that we rotate into the Z plane, but rather around it. However, rotations around the Y axis, will move the rectangle into the Z plane. Per default, CALayer is flat and has no idea of perspective. We can fix that! Back to where we create the overlayLayer we need to add a simple transformation which will gives us this perspective.


What this does is to take the default transformation and add a distance to the 3D projection plane in terms of 1/z. In other words we add depth. Apple does this in reverse. Hence, -1/z is used, where z is the distance, in this case I use 1000. The bigger the value, the bigger the distance. For a more detailed explanation you could start by reading about 3D projection on Wikipedia.

Now we can do our rotations to the face CALayers.

Roll

To make a Roll rotation we simply create a new CATransform3D using the static MakeRotation method, which allows us to rotate around any axis. As shown above roll rotations are around the Z axis. CATransform3D expects the angle in radians. Hence, we need to convert that first.


Pretty simple. We will apply this to the face layer later.

Yaw

The Yaw rotation is a bit more involved. We need to know the orientation of the device as the Y axis changes depending on the orientation, and we need to adjust the angle for that. This means that faces are always detected in the same orientation. However, our preview layer will change along the orientation.


Now we need to make the Yaw transformation and combine with the orientation transformation.


Finally, apply the two transformations to the face CALayer, in the DidOutputMetadataObjects method.


Notice, I add a default transformation to the faceLayer and concatenate the roll and/or yaw transform according to availability. That is it. Now, you should have something like this. Screenshots are taken from Chafu, which demonstrate detection with no rotation, then with roll and then with yaw.

No rotation
Roll
Yaw

Sunday, September 25, 2016

Improving layout performance on Android

I've been working on improving performance of some of my Xamarin Android apps recently. One of the things I've been hunting down and improving on is GPU overdraw. What this means is how many times the same pixels on the screen are drawn per frame. Minimising this improves drawing performance on Android and in the end means smoother scrolling, faster drawing of views and generally makes your app perform more smoothly. The other thing is to hunt down nested layouts and flatten them to improve performance of the view laying itself out on the screen.

Now there are actually quite a lot of things you can do to your app to improve on, to reduce GPU overdraw and how long it takes to layout your views. I will try to cover some of them in this blog post.

Flattening your Layouts

In order to improve how fast your views are laid out on the screen on the device, you can do a very important thing. Flattening your layout. What does this mean? Let me show you an example!

Consider the following page layout, which is very much made out of nested LinearLayouts.



The problem with the nested layout above is the amount of measure passes which has to be done in order to lay it out. For each child with a layout_weight tag, it needs to measure itself twice. Other layouts need to measure themselves too. Imagine having a more complex layout, with a lot of nesting; would resolve in excessive measure passes and make displaying of your layout slow. Especially in cases where you use the layout is used as a row layout. This would hit the app performance quite a lot and there would be noticeable slowdowns in your app.
The layout above, can be flattened using RelativeLayout. You will notice, that layout_weight is quite powerful for layout out equal sized views, so some tricks have to be used to achieve the same with a RelativeLayout. The performance in the end is much better though.


As you see. The above layout employs two additional layouts, which are used to center the other views. An alternative to RelativeLayout to make percentage sized views is PercentRelativeLayout from the Android.Support.Percent package. With it you can set aspect ratios, use percents for widths and heights and more. I would recommend keeping your layouts as simple as possible.

If you simply wish to stack views on top of each other, you can use FrameLayout, which is a real good performer as well.

You can read more about optimizing layouts in the official Android documentation, which also shows how to use the Hierarchy viewer to inspect slow layouts.

GPU Overdraw

GPU overdraw is another problem you may encounter. What is this overdraw? It tells us about how many times the same pixel gets drawn on during a frame. Why is this bad? The more times the same pixels get drawn on, there more time we are wasting. In order to get fluid animations and scrolling etc. you need to have as high a frame rate as possible. A good goal is to try to hit 60 FPS (Frames Per Second) all the time. In order to do this, we need to spend as little as possible time drawing a frame and below 16ms. That is not a long time! Let's explore some things you can do as a developer to improve on this.

Enable showing GPU overdraw

You can enable an overlay on your device or emulator, which will show you the GPU overdraw done by your app. You can find it in developer settings.

 This will give you a funny looking screen with colors laid on top of it. Now these colors actually mean something.
Overdraw chart from Android Documentation
The purple-ish blue means pixels have been over drawn once, green means twice, light red means thrice and dark red 4 times or more. You will also see stuff showing in its original color, this means that the pixels have not been overdrawn. The aim is to have no overdraw at all. However, this can be very hard to accomplish, unless you just have a background drawn on the screen.

Removing backgrounds from views

 A simple thing to reduce overdraw is to just remove backgrounds from views. Let us consider the first layout I showed you, now with everything having a background.

This will gives us this when showing it with GPU overdraw debugging enabled.

Our layout is RED just because we added backgrounds to our layouts. Removing these backgrounds reduce overdraw significantly and in turn improves performance of your app.

Just removing the outermost background reduces overdraw and in this layout the change won't be visible anyways.
The two nested LinearLayouts use the same color, what if we use that as our theme background and remove the color from the layouts?
Again less overdraw. Here is the view without GPU overdraw enabled.
In this case, since the buttons themselves have a background, there will be some overdraw and that can we sometimes cannot do anything to prevent. However, simply reducing a layout from being red all over to green or light blue, means a lot towards performance. Especially in cases where the layout is used in a ListView or RecyclerView or similar Adapter type of view as less time is used to draw the row.

Hence, try to avoid using backgrounds, especially if you can't see them at all. Also a good idea is instead of adding a background to each layout, add that background to your theme, which is pretty simple.

You can also opt to actively remove backgrounds from views with android:background:"@null" for views you don't really care about their background.

As for shadows, borders and the like, which you could do as a background. If you really have to have them use 9-patches with transparency in the areas you don't show anyways. Android will optimize the drawing of these for you and will not overdraw here.

Reducing overdraw in custom views

You might have views that override the OnDraw method where you draw stuff to the Canvas it provides. Here overdraw matters as well. Using OnDraw is what normal views essentially end up using in the end when they draw them selves on the screen. So you have to be careful here as well.

One way to eliminate all overdraw is to draw to a Bitmap first and then draw that to the canvas. This is normally know as double buffering. Be careful with using this, it gives the overhead of first drawing to the Bitmap then to the canvas which draws it to the screen.


The above code shows a simplified version of it. It does indeed result in just 1x overdraw if draw on a background. However, if your draw code is slow, you may encounter flickering if you need to redraw your view a lot.
SurfaceView in Android does it a bit differently. It does all the buffered drawing on a separate thread. You could do this as well. Then call Invalidate() or PostInvalidate() when you need the buffer to be shown on the screen

The technique I ended up using is a modified version, where I delay the drawing until everything is drawn on the Bitmap. Then I signal with PostInvalidate(). It looks something like this the code below.


Now this could probably made a bit simpler. However, what I achieve with this is, whenever I manually signal with Refresh() I cancel any current drawing operations to the buffer as I am not interested in what it provides as it is old data... PostInvalidate() triggers the OnDraw method whenever the GPU is ready. In here I kick off a new Task which draws to the buffer. When that Task is done it calls PostInvalidate() to signal that the buffer has changed and that will be drawn. It is a variation of double buffering, which allows draw operations to take a long time. This has resulted in smooth scrolling of the RecyclerView I am using with these graphs as rows and no overdraw.

Maybe you can use some of these techniques in your app. Let me know what you find out in your application.
In general you want to
  • Flatten your layouts to reduce measure calls
    • Use RelativeLayout instead of LinearLayout with weights
    • Even better FrameLayout for stacked views
  • Remove backgrounds that are not shown anyways
    • Use theme background where applicable
    • android:background:"@null"
  • Use 9-patch for borders and shadows
  • Reduce overdraw in your own OnDraw calls

Resources

https://medium.com/@elifbon/android-application-performance-step-1-rendering-ba820653ad3
https://www.hackerearth.com/practice/notes/rendering-performance-in-android-overdraw/
http://www.xenomachina.com/2011/05/androids-2d-canvas-rendering-pipeline.html
http://developer.android.com/tools/performance/debug-gpu-overdraw/index.html
http://developer.android.com/reference/android/graphics/Canvas.html
https://www.udacity.com/course/android-performance--ud825


Tuesday, April 5, 2016

Installing gapps in Visual Studio Android Emulator (Marshmallow)

29/5/2017: Visual Studio Android Emulator has been discontinued. Microsoft recommends using the Emulator Images that Google provides. The Google images rely on HAXM as described below, so no AMD support and you can't run it with Hyper-V running at the same time.

The images Google provides in the Android SDK are all great and work fine if you have Intel HAXM installed on the machine. However, a lot of developers using Visual Studio, also use Hyper-V to run Windows device emulators. This means Intel HAXM doesn't work and in turn means that the x86 images from Google won't run because there is another hypervisor running.

Microsoft have been so kind to provide the Visual Studio Android Emulator which uses Hyper-V as hypervisor and does not require you to reboot your machine every time you want to switch between using Hyper-V and another hypervisor. Great!

There is one caveat. None of the images included in the Visual Studio Android Emulator tools have Google Play Services installed. Hence, you have to install them yourself. It turned out to be more complicated than I thought it would. Hence, I am documenting it in this blog post.

At first I tried the tried and great OpenGapps, which a lot of custom roms for Android devices recommend using. Picked x86 and the pico package for Android M and tried to install that on a Marshmallow image. It just threw an error telling me that the system/ folder was missing in the zip. Great, what then? I tried adding that folder with an empty file manually to the zip, as it seems it doesn't care whether the zip is signed or not when installing. This made the zip install. Well not really, no Play Store or Play Services where actually installed.

I tried some other GAPPS zips from various sources, none of them seemed to work. I searched around without finding any solution.

Alexandre Chohfi over at the Xamarin Community Slack pointed out that he had the same issues with Genymotion, which runs on VirtualBox and pointed me in the direction of this gist explaining how to do it on Genymotion. Following the instructions from arcao in the comments works! Without installing that Genymotion ARM translation package too.

Steps I used

Prerequisites

1. Install a Marshmallow image in the Visual Studio Emulator for Android tools (can be opened through Tools > Visual Studio Emulator for Android in Visual Studio)


2. Download gapps-L-4-21-15.zip

3. Download benzo-gapps-M-20151011-signed-chroma-r3.zip

Installing

1. Start the Marshmallow image

2. Drag the gapps-L-4-21-15.zip onto the Emulator after it has booted. It will prompt you to install the zip and shutdown the device after that.


3. After having install the gapps boot up your Emulator again, it will show a dialog about optimizing newly installed packages.

4. Go to Settings > Accounts and Add a Google Account. Ignore all crashes.



5. After adding the Account, install the benzo-gapps-M-20151011-signed-chroma-r3.zip by dragging it onto your Emulator, like in step 2.

6. After rebooting after step 5. is done, you should now have working Play Services and Play Store on your Visual Studio Emulator for Android.