Binding Flurry Analytics with Xamarin.Android

This week, I needed to use Flurry Analytics in my Xamarin.iOS and my Xamarin.Android apps, but there was no .NET SDK for these platforms. Flurry did provide a SDK for each platform, but it was the native libraries, which cannot be used directly in .NET. Given this, I decided to bind those native libraries using Xamarin.iOS and Xamarin.Android.

I have split this project up into four parts:

  1. Introduction and Pre-requisites
  2. Xamarin.iOS binding
  3. Xamarin.Android binding
  4. Flurry.Analytics in the wild

After binding the iOS SDK for Flurry Analytics, we are going to move onto the Android release. This task needs only one thing from the downloaded SDK:

  • [Android-sdk-path]/Android 4.1.0/FlurryAnalytics/FlurryAnalytics-4.1.0.jar

Of course, the version numbers may change for later releases. The java archive file (.jar) is going to be used to generate the .NET interfaces and enums, and then be embedded in the resulting assembly.

Just before we do the real binding, we should just create our C# solution for the Xamarin.Android binding. Just create a new project/solution and select the Android “Bindings Library” template. For my project name I used Flurry.Analytics.Android, but you could use anything.

The default project has a few files and directories in it, we will have a look at each one in depth as we go through the binding steps:

  • /Additions/ (this allows you to add arbitrary C# to the generated classes
    before they are compiled)
  • /Properties/AssemblyInfo.cs (the usual assembly information attributes)
  • /Jars/ (this directory is for Android .jars)
  • /Transforms/EnumFields.xml (this allows you to map Java int constants to C# enums)
  • /Transforms/EnumMethods.xml (this allows changes to method parameters and return types from Java int constants to C# enums)
  • /Transforms/Metadata.xml (this allows changes to be made to the final API)

Creating the Initial Binding

This step will involve just adding the jar to the project, and letting the compiler do it’s thing, but we will almost always have to go in and tweak a few things in the Metadata.xml.

So, first things first, add the jar file to the project and compile. The build will probably fail with error messages containing single character methods and types. This is because the actual jar file has been obfuscated. However this can easily be fixed.

The way the generation works is that there is a two step process, there is a tool that generates a bunch of xml files from the jar file. These xml files are then used to generate C# code. The Metadata.xml sits in between the two steps and can be used to transform the generated xml before the C# generation.

Tweaking the Generated Binding (Manifest.xml)

As we can see that the build fails on obfuscated types, we can remove these. The removal is safe as we are only preventing the .NET binding from being created, not actually removing the underlying Java members. And, as these items have been obfuscated, we can safely assume that we aren’t supposed to be accessing them anyway.

But, instead of removing each member or type that appears, we can use a great tool that will decompile the jar file and show us exactly what types are internal and what types we should be binding. I use JD-GUI, which is a free Java decompiler. They also have a nice online version, JD-Online. What we can do is to just upload the jar file here and see what’s inside:

  • com.flurry.android.impl.analytics.*
  • com.flurry.android.*
  • com.flurry.sdk.*

As we can see, the impl and sdk branches contain internal and obfuscated types, so we can remove those:

<remove-node path="/api/package[starts-with(@name, 'com.flurry.sdk')]" />
<remove-node path="/api/package[starts-with(@name, 'com.flurry.android.impl')]" />

After this, the build should now succeed and we will have an assembly that we can use. However, there are still some types that we can remove to clean the API a bit: InstallReceiver and Constants. InstallReciever is not used by the consumer, so this is safe to remove, but Constants is still used. If we remove this, then the consumer will not have access to the values on the type. We can see that Constants just contains the values representing male, female and unknown.

To remove the InstallReciever, we can add this line to Metadata.xml:

<remove-node path="/api/package[@name='com.flurry.android']/class[@name='InstallReceiver']" />

For the Constants type, we will do something different.

Managing the Enumerations (Additions & EnumFields.xml)

As we clean up the API, we want to remove the Constants type and replace it with an enum. One way to do this is to use the EnumFields.xml:

<mapping clr-enum-type="Flurry.Analytics.Gender" jni-interface="com/flurry/android/Constants">
    <field clr-name="Male" jni-name="MALE" value="1" />
    <field clr-name="Female" jni-name="FEMALE" value="0" />
    <field clr-name="Unknown" jni-name="UNKNOWN" value="-1" />
</mapping>

This will generate a nice enum for us, but this does leave an unused interface IConstants. As this is a very small library, we can do this mapping slightly differently. First we remove the entire Constants type in the Metadata.xml:

<remove-node path="/api/package[@name='com.flurry.android']/interface[@name='Constants']" />

Then, we can create the enum in the /Additions/ directory. To do this, add a new file (for example called FlurryAgent.cs) under this directory and add the enum:

public enum Gender
{
    Male = 1,
    Female = 0,
    Unknown = -1
}

Now there is one last thing to do before the API definition is complete. There is a SetGender method on the type FlurryAgent, which takes the type sbyte. It is not intuitive to use the Gender enum here, so we can fix this in a two step process. First we will create an overload in the FlurryAgent.cs file that accepts a Gender enum member as an argument:

public partial class FlurryAgent
{
    public static void SetGender(Gender gender)
    {
        FlurryAgent.SetGender ((sbyte)gender);
    }
}

And, what we can do is also hide the original member as the new overload is good enough:

<attr path="/api/package[@name='com.flurry.android']/class[@name='FlurryAgent']/method[@name='setGender']" name="visibility">internal</attr>

And with this, our binding is complete, although we can do a few nice changes to the namespace and parameter names.

Changing Parameter Names

Now that we have the binding complete, we can see that it is using the namespace Com.Flurry.Android, which is no .NET-like at all. We can change this to something better:

<attr path="/api/package[@name='com.flurry.android']" name="managedName">Flurry.Analytics</attr>

This maps the com.flurry.android package name to the neat Flurry.Analytics namespace. One last thing is to fix the parameter names. Sometimes you can use the JavaDocs, but in this case, I couldn’t get it to work. Doing it manually is not hard, but it is boring and time consuming, but here are a few.

This is the usual mapping:

<attr path="/api/package[@name='com.flurry.android']/class[@name='FlurryAgent']/method[@name='onStartSession']/parameter[@name='p0']" name="name">context</attr>
<attr path="/api/package[@name='com.flurry.android']/class[@name='FlurryAgent']/method[@name='onStartSession']/parameter[@name='p1']" name="name">apiKey</attr>
<attr path="/api/package[@name='com.flurry.android']/class[@name='FlurryAgent']/method[@name='onEndSession']/parameter[@name='p0']" name="name">context</attr>

If there are complicated parameter types (note the &lt;):

<attr path="/api/package[@name='com.flurry.android']/class[@name='FlurryAgent']/method[@name='logEvent']/parameter[@name='p1' and @type='java.util.Map<java.lang.String, java.lang.String>']" name="name">parameters</attr>

If there are overloads with different parameter types:

<attr path="/api/package[@name='com.flurry.android']/class[@name='FlurryAgent']/method[@name='onError']/parameter[@name='p2' and @type='java.lang.Throwable']" name="name">exception</attr>
<attr path="/api/package[@name='com.flurry.android']/class[@name='FlurryAgent']/method[@name='onError']/parameter[@name='p2' and @type='java.lang.String']" name="name">errorClass</attr>

After doing this for all the members, the binding is now complete.

Finishing Up

So far we have defined our API, added any additional logic or types, added the native library and added parameter names. This is all that is needed, so our library should build fine now and we should be able to use it in an Xamarin.Android app:

// the methods
FlurryAgent.StartSession(this, "PQSZJRK4B5BW8Q7YQQXF");

// the properties that we changed back into methods
string version = FlurryAgent.ReleaseVersion;

// the extra method that we added
FlurryAgent.SetGender (Gender.Male);

Flurry.Analytics for Xamarin

The Flurry Analytics Agent allows you to track the usage and behavior of your Android, iOS or Windows Phone application on users’ phones for viewing in the Flurry Analytics system. It is designed to be as easy as possible with a basic setup complete in few minutes.

Features

There are many features available in the Flurry Analytics API, such as:

  • Session tracking
  • Event logging, with optional parameters
  • Page View tracking
  • Demographics tracking, such as age, gender and user id
  • Location tracking
  • App version tracking
  • And much more…

Getting Started

The setup for all the platforms is very easy with only a few steps:

Android

  1. Add the INTERNET permission to AndroidManifest.xml.
  2. Add FlurryAgent.OnStartSession(this, "YOUR_API_KEY"); to the OnStart method of the Activity or Service.
  3. Add FlurryAgent.OnEndSession(this); to the OnStop method of the Activity or Service.

iOS

  1. Add FlurryAgent.StartSession("YOUR_API_KEY"); to the FinishedLaunching method of the Application Delegate

Windows Phone

  1. Add ID_CAP_NETWORKING and ID_CAP_IDENTITY_DEVICE capabilities to WMAppManifest.xml.
  2. Add FlurryWP8SDK.Api.StartSession("YOUR_API_KEY"); to Launching and Activated events of the Application.

And that’s it, your mobile app will start sending activity usage statistics to the Flurry servers!

Advanced

Flurry Analytics SDK supported versions:

  • SDK for iOS supports Xcode tools 4.5 and above
  • SDK for Android supports Android API level 10 (Gingerbread) and above
  • SDK for Windows Phone supports Windows Phone 8 and above

Downloading

The Flurry.Analytics API is available on NuGet.org (Flurry.Analytics) and on GitHub (mattleibow/Flurry.Analytics).

It is released under the same license as the native libraries.

The Making Of

You can read up on how the binding was created in my blog:

  1. Introduction and Pre-requisites
  2. Xamarin.iOS binding
  3. Xamarin.Android binding
  4. Flurry.Analytics in the wild

Bing Maps iOS SDK

The Bing Maps iOS SDK is a control for embedding maps directly into native iOS apps. With a rich, gesture-based UI, the SDK provides support for adding pushpins and other overlays to the maps. The SDK also allows your device location to be displayed and provides the ability to retrieve contextual information for a given map location.

This project provides a managed binding of the native library for Xamarin.iOS.

Sadly, after getting all this nice stuff going, I found the actual native library to be very buggy and often caused the app to crash. For example, if the push pins were animated, tapping them caused the app to crash. As a result, I won’t be pushing this to the stores.

Getting Started

Before you can use the map control, you will need a Bing Maps Key from the Bing Maps Portal. The process is described in the MSDN documentation, Getting a Bing Maps Key, and is very simple with only four steps.

A map key is not required for the maps to appear, but will display a popup reminder every time a map view is displayed.

Using the Map View

Once you have obtained a key, the next step is to add the map view to your app. You can obtain the control from the 3.

Once you have added the assembly to your app, you then need to add your Bing Maps Key to the Info.plist file in your project. This is a string key-value item with the key, BingMapsKey, with the value being the key you obtained from the portal.

Now, all that is left to do is to add the map view to your view. This can be done in the code or in the designers (storyboards or interface files).

If we are going to use the designers, then you can just add a UIView to your app, and then change the Class to be BMMapView. When the app is launched, a map should appear. If the code is used, then this snippet is all that is needed:

    // create the map view
    BMMapView mapView = new BMMapView (UIScreen.MainScreen.Bounds);
    // add to some View
    View.AddSubview (mapView);
    // show the user's location on the map (optional)
    mapView.ShowsUserLocation = true;

XNA Content Compiler

Compile to .xnb your texture files, audio files and SpriteFont files without needing Visual Studio 2010 or having to install the XNA Game Studio.

XNA Content Compiler

You can use this tool co compile your game content for XNA or MonoGame without having to create and use the Game Content Project in Visual Studio 2010.

For more information on how to use the tool, check out this blog post.

The source code is on github and you can download the latest version of the compiled project directly here.

Content Types

XNA Content Compiler supports all the types of the XNA Content Pipeline.

Currently supported types:

  • Image Files: *.bmp, *.jpg, *.png, *.tga, *.dds
  • Audio Files: *.wav, *.mp3, *.wma
  • SpriteFont Files: *.spritefont

There are more types that are supported by the XNA Content Pipeline, but they do not have all the UI features yet. If you need a new type, just create an issue or pull request.

Features

  • Advanced UI
  • Supports all features of the pipeline
  • Add individual files or entire folders
  • In-memory project files
  • (soon) Import *.contentproj files
  • (soon) Save compiler project files
  • (soon) All content types

This work is based on XNA 4.0 Content Compiler

MonoGame Content without Visual Studio

MonoGame is free software used by game developers to create games for many different platforms. It is almost a Write Once, Play Anywhere!

Unfortunately, the content processing pipeline is not yet available for all platforms or even the later versions of Visual Studio. Here I will show you a way to build the content for any version of Windows, without Visual Studio.

Platforms

Currently supported platforms for MonoGame:

  • iOS (including Retina displays)
  • Android
  • Windows (OpenGL & DirectX)
  • Mac OS X
  • Linux
  • Windows Store Apps (for Windows 8 and Windows RT)
  • Windows Phone 8
  • PlayStation Mobile (currently 2D only)
  • OUYA, an Android-based gaming console

Currently Supported platforms for XNA:

  • Windows Phone 7
  • Xbox 360
  • Microsoft Windows

Support for Xbox One is currently under way with both Microsoft and the MonoGame teams. Microsoft is adding .NET support to the Xbox One and the MonoGame team is adding Xbox One support to MonoGame.

Content Processors

When creating games using MonoGame, there are 2 main parts to any game: the Content and the Code. The content is usually the textures, sounds and fonts in the game. The code is what you write, the logic.

At the current time MonoGame does not have its own content processors, so we will make use of the original XNA build tools. The MonoGame team is working on their tools, but it is not yet complete.

In order to process the content, we need two things: the processor tools and some sort of UI.

Installing the Content Pipeline

We will start off by setting up our content tools before we actually do anything. First we need the assemblies that come with XNA Game Studio. This is the toolset used for building the content that will appear in our game. The actual studio does not install on without Visual Studio 2010, so we have to cheat a bit.

First of all, we need to download XNA Game Studio 4.0 Refresh from Microsoft’s Download Center. Once this is complete, we will load the framework installers out of the studio setup file:

  1. Using 7-zip (or any other compression tool), open the newly downloaded XNAGS40_setup.exe.
  2. Inside the installer, there should be a redists.msi file, open it using “Open Inside” as we don’t want it to start installing.
  3. Extract the files named SharedFilesInstaller_File, XNAFXRedist40Setup_File and XNAPlatformToolsInstaller_File into a directory.
  4. Rename the three extracted files by adding a .msi extension in Windows Explorer, this “turns” them into installers.
  5. Install each of them one at a time.

Once this is done, we would have installed all the build tools required to package the content.

Installing the Interface

Next, we need to install the XNA Content Compiler. This allows the building of the content packages when not using Visual Studio 2010.

You can do this by downloading the XNA 4.0 Content Compiler source code from my fork. I have added some extra features that allow for more advanced content processing, such as, Compression and MipMap generation.

Once you have this, you should be able to open the solution in Visual Studio and build the application. Currently the compiler can only be used on Windows as the tooling is only available on Windows.

Xamarin Has Options

Have you ever wanted to try out creating a mobile app for either iOS or Android using Xamarin? You went to their website, clicked pricing and then reeled at the cost? You are new. You are unsure. You want a taste. You don’t want to spend all your money and then maybe be a little unhappy.

Well, don’t worry, there is an pricing option for you! There are a couple of good ones that can fit your needs as someone stepping into a whole new world of magic.

You can check out the pricing and comparison charts at the Xamarin Store.

The Free ($0/m or R0/m)

Xamarin provides a free, zero cost, no cash option. Starter Edition! You may think that this is too limited. Only small apps. No native library interaction.

You are right. But. How small is small? Also, what are you measuring? The limit is only the size of the compiled source code, not the whole app. Chances are you aren’t going to hit any limit in your first week. The small app limit is almost a myth!

No native library interaction? What if I want to use… Is it a big no? No! With Starter you can use third party libraries that are available in the Component Store or on NuGet. And again, the chances are you aren’t going to be using some obscure framework on the first go. Both iOS and Android are mature platforms with many features, so probably what you need is already there.

The Indie ($25/m or R260/m)

But… Let’s say you need to write some custom native bindings or you have this massive app… There is a version for you still. But, if this is the case, how about giving the Indie Edition version a shot?

You recall looking at the price for this one… $299, or if you are with me in South Africa, R3200 at the current exchange rate. Pricey! Very much so…

But, Xamarin marketing to the rescue! They sat down and had a chat… What can Xamarin do so that the company makes a profit, but make sure the developer also can get a profit? So they came up with a subscription plan. A pay-as-you-go, or pay-for-what-you-use.

This new model, just out this week, provides you with a monthly subscription that can be started and stopped at your hearts content.

Lets say for example you are a student… You are studying hard like all students and don’t have much free time. But, you want to write an app in the holidays. It is going to be a big app. Starter ain’t gonna cut it. I’ll just note here that Starter probably would be fine for a case like this, but just to continue… You want Indie for one, maybe two months at most. Are you going to spend thousands of Rands? No. So you sign up for the Subscription Indie package.

What this does for you is that you will pay a small amount, and then get that month of development time. So in the example of the student, you sign up in June, pay your fee and do some dev. Then in July, you pay the next bit, and do some more dev. Then you release your app and go back to the books. August comes, you get a bill from Xamarin, and you just ignore it! They will suspend your account, so no more dev, but your app is out there and will is good.

Then after your exams, near the year end, you decide to do an update. All you need to do is pay that month’s bill and all is working again. Writing code until the sun comes up again.

So how’s much does this cost? Is it going to break the bank? Nope, it works out well. Each month costs $25, or for those in South Africa, R260. This cost is for either Xamarin.iOS or Xamarin.Android platforms. And not only that, you get access to some Xamarin exclusives, such as the new Xamarin.Forms. You can also subscribe to both platforms and get a 10% discount!

The Student ($99/y or R1000/y)

And, after mentioning students, remember they do have a special Student Discount for you. All you have to do is send student@xamarin.com an email from your student email address and they will send you a discount code. For as little as $99, or R1000, you get access to the Business Edition of either Xamarin.iOS, Xamarin.Mac or Xamarin.Android. And remember the business edition has even more features. My personal favorite is Visual Studio support! This allows you to build not only Android apps in Visual Studio, but also iOS apps! With a drag-and-drop designer!

If you are part of an Open Source project you can also get a complimentary license! All you need to do is fill in the Open Source Contributor Form and someone will get back to you!

Be sure to check out the new pricing options as well as the student and open source discounts!

The Xamarin User Group (XUG)

If you haven’t had a chance to meet your neighborhood Xamarin developers in person yet, Xamarin User Groups provide a perfect venue for connecting with like-minded developers and local experts.

If you are in Cape Town, South Africa, be sure to pop in to our monthly Cape Town Xamarin User Group, I’ll be there!

And also download the iCalendar.

The University ($1995/y or R2100/y)

Have you ever wanted to be better, do better, know more, finish first? Well you can get there by learning from the Xamarin cross-platform expert lecturers at the Xamarin University.

After taking a few classes, you can become a Xamarin Certified Developer, which shows that you have demonstrated expertise in cross-platform mobile development in iOS, Android, and Windows using the Xamarin platform.

Why would you want to get this certification? Well…

  • It is a premiere badge of achievement in Enterprise Mobile Development and an outward illustration that you’ve met a high bar of demonstrated expertise as a Xamarin Developer.
  • You are eligible to be included in the Official Xamarin Certified Developer LinkedIn Group: a curated professional network that only includes currently certified developers that get special access to mobile development jobs and other benefits.
  • You can proudly display the Xamarin Certified Developer Badges on your website or resume.

Xamarin University allows you to study at your own pace and at your own times. All you do is take a yearly subscription for $1995, or for us South Africans, R21000. This is a high price as it stands, but it does give you a certification, live web lectures and one-on-one feedback and discussions. This is often things that other recorded-video courses can’t provide.

Be sure to check out Xamarin University or contact them for more information.