If you try to access a Windows Azure Mobile Service using the Android SDK from a device running Android version 2.2 (also known as Froyo), you’ll get an error in all requests. The issue is that that version of Android doesn’t accept the SSL certificate used in Azure Mobile Services, and you end up getting the following exception:
Error: com.microsoft.windowsazure.mobileservices.MobileServiceException: Error while processing request.
Cause: javax.net.ssl.SSLException: Not trusted server certificate
Cause: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: TrustAnchor for CertPath not found.
Cause: java.security.cert.CertPathValidatorException: TrustAnchor for CertPath not found.
The number of Froyo Android devices is rapidly declining (2.2% in the date I wrote this post, according to the Android dashboard), but there are scenarios where you need to target up to that platform. This post will show one way to work around that limitation, created by Pablo Zaidenvoren and committed to the test project for the Android platform in the Android Mobile Services GitHub repository. The solution is to register a new SSL socket factory to be used by the mobile service client with a key store which accepts the certificate used by the Azure Mobile Service.
In a TDD-like fashion, I’ll first write a program which will fail, then walk through the steps required to make it pass. Here’s the onCreate method in the main activity, whose layout has nothing but a button (btnClickMe) and a text view (txtResult). If you’re going to copy this code, remember to replace the application URL / key with yours, since I’ll delete this mobile service which I created right before I publish this post.
If you run this code in a Froyo emulator (or a device), you’ll see printed out the error shown before.
On to the workaround
First, add a new folder under the res (resources) folder for the solution, by right-clicking it, and selecting New –> Folder:
Let’s call it ‘raw’, and click Finish:
Now, download the mobile service store file from https://github.com/WindowsAzure/azure-mobile-services/blob/dev/test/Android/ZumoE2ETestApp/res/raw/mobileservicestore.bks, and save it into the <project>/res/raw folder which you just created (in the GitHub page, clicking “View Raw” should prompt you to save the file). Back in Eclipse, select the ‘raw’ folder and hit F5 (Refresh), and you should see the file under the folder.
That file will need to be read in the new SSL socket factory, and to read that resource we’ll need a reference to the main activity. So we’ll add a static method (along with a new static field) which returns the instance of the main activity. And in the onCreate method, we set the (global) instance.
Now we can start by adding the Froyo support to the application. The snippet below shows only the beginning of the class – it doesn’t show the entire SSL factory with the additional certificate store (for Azure Mobile Services). You can find the whole code (may need to update the imports for the main activity and the resources) in the GitHub project.
Now that we have that support, we need to create a new instance of the factory used to create the AndroidHttpClient instances – which is defined in the Azure Mobile Services Android SDK (version 1.0.1 and later). The SDK already includes a default implementation of the class, so extending it to use the fix support is fairly straightforward. Add a new class (I’ll call it FroyoAndroidHttpClientFactory) which extends that default implementation:
Now all we need to do is to hook up that AndroidHttpClientFactory with the MobileServiceClient, which can be done with the setAndroidHttpClientFactory method, as shown below.
And that’s it. If you execute the application again and click the button, the item should be correctly inserted (and other operations should work as well).
If you want to download the code for this example, you can find it in my GitHub repository at https://github.com/carlosfigueira/blogsamples/tree/master/AzureMobileServices/FroyoAndWAMS.