Dev Stories

Xamarin: Resources of an Android app project

As I mentioned already in my first blog post about Xamarin, Android has a different project structure – even if you use Xamarin.

A very important part of this structure are resources. We have different kind of resources in an Android app:

  • Icons & Images
  • Layout (XML files)
  • Values (string resource files)

Let’s start with Icons & Images.

As you can see in the solution window, there is a folder called ‘Resources’. Here you will put all kind of resources, like images, icons, layouts and so on.

The corresponding class for images in Android is called ‘drawable’, that holds a reference to’ Icon.png’. The project structure is based on that, that’s why the resources folder has all images inside the folder ‘drawable’. As Android has various screen sizes, you may have a folder for structure like ‘drawable’, ‘drawable-hdpi, ‘drawable-ldpi’ and so on. Android scales your image resources to match the screen automatically if you do not define alternate layouts.

To make your files available in your app, you need to set the Build Action to ‘Android Resource’:

Screenshot (278)

Let’s have a look to the Layout files:

Layout files are XML files that contain the UI of a page, control or a view. You can use these XML files for example to define items of a ListView or simply the application page. Every new project has a ‘Main.axml’ file.

There are two ways to create a layout. The first one is using the visual designer:

Screenshot (280)

This works for basic layouts like adding the button above. Also, if you don’t know the properties of a control you added, you will be able to add it here to get started.

If you are familiar with writing your UI in code (like XAML)  and want to do so in your Android app, just click the ‘Source’ tab at the bottom in the visual designer. You will see something like this:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Button
android:id="@+id/myButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />
</LinearLayout>

If you want to add and modify a control, but don’t know how the properties are, this page has a list of all controls, which are called ‘widgets’ in Android. That’s also the corresponding namespace: android.widget.

Like in an Windows Phone app, you also have a string resource file in Android projects. This file is once again a XML file, but with a different structure:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, Click Me!</string>
<string name="app_name">gettingstarted</string>
</resources>

All strings need to be declared inside the <resources> tag. The definition is always like <string name=”yourstringname”>stringcontent</string>. Empty strings are not supported and will throw an error at building your project.

Let’s have a look on how we can work with our resources, based on our gettingstarted project. We have the following code inside our MainActivity class:

int count = 1;

		protected override void OnCreate (Bundle bundle)
		{
			base.OnCreate (bundle);

			// Set our view from the "main" layout resource
			SetContentView (Resource.Layout.Main);

			// Get our button from the layout resource,
			// and attach an event to it
			Button button = FindViewById<Button> (Resource.Id.myButton);
			button.Text = GetString (Resource.String.hello);

			button.Click += delegate {
				button.Text = string.Format ("{0} clicks!", count++);
			};
		}

As you can see, the we are defining our view from our Layout file ‘Main.axml’ by using the SetContentView() method. The file is added to our resources list as Layout with the name we defined.

Our MainActivity does not know that we have a button inside our layout. To make the button visible to our MainActivity, we need to reference it. This is done by declaring a Button instance and using the FindViewById<T>(ResourceName) method.

If you have not given your button a name, now is the right time to do so. In our example the button has the name “myButton”.  The syntax is very important, make sure you add “@+id/” to the name.

android:id="@+id/myButton"

Now our button is visible to our MainActivity code page and can be accessed. The sample project references the button content in the Layout file:

android:text="@string/hello"

After referencing our button, we could also use the following code to get the button content from the resource file:

button.Text = GetString (Resource.String.hello);

Whenever your want to get a string from the resource file in an Activity, the GetString() method is used.

I hope this post helps you to understand how resources are used in an Android app and how to handle it a Xamarin project.

Happy coding everyone!

Posted by msicc in Android, Dev Stories, Xamarin, 0 comments

Xamarin: how to set up an Android device for Debugging

Xamarin comes with some emulators for development of an Android app. While these emulators are working and are also available in all supported screen sizes, the performance of them is really bad.

That’s why I chose debugging via device, which is a lot faster than the emulators once you have the required Xamarin extensions installed.

Here is how to set up an Android device for debugging. First thing you need to know is which OS version is running. On most Android devices, you will find this information under Settings/About (or Info)/Software information. If you don’t have the result there, you should check the manual where to find this information on your device.

Screenshot_2013-12-29-07-03-31

Activate Debugging until Android 3.2

  • go to Settings from your Application Menu
  • choose Applications
  • open the Development item
  • you will see now the option to activate USB debugging:

Android_debug_until_32

Activate Debugging on Android 4.0, 4.1

  • go to the Settings Menu
  • choose Developer options and activate USB debugging:

Android_debug_until_32

Activate Debugging on Android 4.2 and higher

  • go to the Settings Menu
  • select About
  • tap the Build Number 7 times (after the 4th tap a notification will appear that counts down the required taps)

Screenshot_2013-12-29-07-04-36

 

Installing drivers

Now our devices are ready to be connected to our PC, where we need to install the corresponding USB drivers. Normally you just need to plug in your Android device, Windows will search for the right driver and install it for you. If you want to install the driver manually, here is a list of OEM driver packages: http://developer.android.com/tools/extras/oem-usb.html#Drivers

Deploying an App for debugging

After the drivers have been installed, your device should now be recognized by Windows and also by Xamarin Studio.

Using our gettingstarted project from my first blog post, you should have now two options to deploy the application to your device:

Run With…

Screenshot (273)

Just hit ‘Debug’…

Screenshot (275)

Xamarin Studio installs now the required packages for debugging, and after that, you will be able to debug you application.

Speeding up re-deployments

Xamarin will install all developing packages including your app from scratch every time you deploy the app. To speed things up, there is an option to speed things a little up.

To activate/check if this option is already activated, click on the ‘options’ button of your project and select ‘Options’ in the context menu:

Screenshot (276)

Select ‘Android Build’ and activate these two options:

Screenshot (276)

 

This way, Xamarin will deploy only changes that have been made to your code, while keeping the required packages on your device. Xamarin Studio will detect if an update to those packages is required.

However, sometimes you will need to clean your solution and do a complete re-deploy (like you are doing with a Windows Phone project sometimes, too).

In very seldom cases (happened 3 times to me by now), you will need to uninstall your app and all of the Xamarin packages from your device. To do so, go to Settings/Apps on your device. In the application list, you will find some apps that start with ‘Mono’:

Screenshot_2013-12-29-07-57-13

To uninstall them, tap the items and select ‘Uninstall’ in the App info screen:

Screenshot_2013-12-29-07-58-43

 

Xamarin Studio will now re-deploy all required packages to your device, and your app should run again for debugging.

Like always, I hope this post is helpful for some of you.

Happy coding!

Posted by msicc in Android, Dev Stories, Xamarin, 2 comments

New Series: developing for Android with Xamarin

xamandroid

Prolog

In the last few month I was developing not only my personal projects, but also on my daily 9to5 job. I am working on an internal app that will help to improve the customer experience amongst the customers of my employer Telefónica.

The project has a simple setup in phase I, with collecting data and sending them via mail. The challenge for me was how to get the Windows Phone app (yes, Windows Phone was first!) to Android.

I knew it would take some time to get started with Android development, and was searching for possible solutions to speed things up. I knew from Xamarin already, and was able to obtain a 1-year license for Android (maybe iOS will follow later).

Some of my fellow WinPhans and WinPhanDevs will scream out very loud at the moment. I understand that. But honestly, I could not let go away this huge opportunity for me – as it touches both my daily job and my private developer story. To calm you down: I will always love Windows Phone and Windows and develop for it first. I will always remain a WinPhanDev. But I need to go forward, and this is a big step.

Let’s go back to the topic.

With this blog post, I am kicking off a new blogging series for Android development with Xamarin. The huge advantage of using Xamarin is that I am able to use my C# knowledge to develop apps for other platforms – which makes it a little easier to get things done.

However, if you start with another platform, you still have to learn the platform structure. Without knowing or be willing to learn it, you will be lost very fast. Every OS has its own specific UI rules, save handling and so on. This is what I will blog about.

The Windows Phone app I ported to Android has a item Pivot, which I ported over to Android. It has a little different appearance, but it works in a similar way with tapping the header or a swiping gesture to move between the items/pages.

To get there, I had to learn a lot about Android – and I will share it all with you out there.

My series will cover the following topics:

Installing Xamarin

Installing Xamarin is pretty easy – but will take some time. Click on this link to download the Xamarin IDE. The IDE will ask you for which platform you want to develop for (let’s choose only Android for the moment) and then download a huge amount of additional SDKs like the Java and the Android SDK (Android apps are Java based, if you didn’t knew).

Screenshot (267)

On the screenshot above you can see the starting page of Xamarin Studio. On the left side you have the list of recent solutions, in the middle you see Xamarin news and finally the pre-built apps section.

Xamarin Studio has a lot together with Visual Studio, and you also can take a lot of settings to adjust the appearance for your needs. Let’s start a new project by clicking on the ‘New’ button

Screenshot (270)

Xamarin will set up a .sln file with everything we need for the moment. After creating the project has been created, you’ll see these lines of code:

using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;

namespace gettingstarted
{
	[Activity (Label = "gettingstarted", MainLauncher = true)]
	public class MainActivity : Activity
	{
		int count = 1;

		protected override void OnCreate (Bundle bundle)
		{
			base.OnCreate (bundle);

			// Set our view from the "main" layout resource
			SetContentView (Resource.Layout.Main);

			// Get our button from the layout resource,
			// and attach an event to it
			Button button = FindViewById<Button> (Resource.Id.myButton);

			button.Click += delegate {
				button.Text = string.Format ("{0} clicks!", count++);
			};
		}
	}
}

 

These few lines should help to get started with the basic structure of an Android App.

Android has Activities. Activities can be seen as the code behind files in a C# project. Here begins all the action of an Android app. Xamarin automatically ads the Label (project name) and in this case, also the MainLauncher property, which will run this code on app start up.

To get something displayed in our app, we need to load a Layout or create the view from the code. This is what the SetContentView() method is about. Without this, the app will compile but displays nothing. In this demo app, a basic layout with a button inside is created:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <Button
        android:id="@+id/myButton"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />
</LinearLayout>

 

We already have the first difference to other C# projects here. In order to make the button visible for our code in the Activity, we need to search our resources for the button. This is done by the FindViewById<T>() method. As soon as it is visible to our code, we are able to create a delegate for our button Click event.

The button counts then the clicks on it and changes the text based on the number of clicks.

To understand more about the structure of an Android App, I highly recommend to read the documentation. For me, especially these links were helpful:

There are some more resources that are helpful, but for getting started those four links should be enough. I will cover some of the topics above also with my upcoming posts and link additional resources as well.

As with the Windows Phone development, also StackOverflow is a big help as well as the Xamarin  Android forums.

Until the next post, happy coding!

Posted by msicc in Android, Dev Stories, Xamarin, 0 comments

Getting productive with WAMS: How to handle erroneous push channels

WAMS

As I wrote already in my former article ‘Getting productive with WAMS- about the mpns object (push data to the user’s Windows Phone)’, I needed to add some more detailed error handling to the mpns object on my Mobile Service.

There are two error codes that appear frequently: 404 (Not Found) and 412 (Precondition Failed).

The 404 error code

happens when the push channel gets invalid. Reasons for that can be uninstall or reinstall of the app, or also a hard reset of the users device. In this case, we are following the recommendation of Microsoft to stop sending push notifications via this channel.

There might be several ways, but I prefer to work with SQL queries.  This is how I delete those channels within error: function(error):

if (error.statusCode === 404)
{
 var sqlDelInvalidChannel = "DELETE from pushChannel WHERE id = " + channel.id;
 mssql.query(sqlDelInvalidChannel, {
 success: function(){
	console.log("deleted invalid push channel with id: " + channel.id);
	},
	error: function(err)
	 {
           console.log("there was a problem deleting push channel with id: " + channel.id + ", " + err)
         }
});

As you can see, this is a very simple approach to get rid of those invalid channels.

The 412 error code

needs some more advanced handling. Microsoft recommends to send the push notification as normal, but the code recommends a delay of 61 minutes to resend. Also, with some research on the web, I found out that often the 412 will turn into a 404 after those 61 minutes (at least I found a lot of developers stating this). This is why I went with a different approach. I am going to wait those 61 minutes, and do not send a push notification to those devices.

For that, I do a simple trick. I am saving the time the error shows up in my push channel table, as well as the  time after those 61 minutes. On top, I use a Boolean to determine if the channel is in the delay phase.

Here is the simple code for that, again within error: function(error):

if (error.statusCode === 412)
{
	var t = new Date();
	var tnow = t.getTime();
	var tnow61 = tnow + 3660000;

	var sqlSave412TimeStamp = "UPDATE pushChannel SET Found412Time=" +  tnow + ", EndOf412Hour=" + tnow61 + ", IsPushDelayed = 'true' WHERE id=" + channel.id;

	mssql.query(sqlSave412TimeStamp);
}

Now if my script runs the next time over this push channel, I need to check if the push channel is within the delay phase. Here’s the code:

if (channel.IsPushDelayed === true)
{
	var t = new Date();
	var tnow = t.getTime();
	var EndofHour = channel.EndOf412Hour;
	var tdelay = EndofHour - tnow;

	if (tdelay > 0)
	{
	 console.log("push delivery on id: " + channel.id + " is delayed for: " + (Math.floor(tdelay/1000/60)) + " minutes");
	}
	else if (tdelay < 0)
	{
	 var sqlDelete412TimeStamp = "UPDATE pushChannel SET Found412Time=0 , EndOf412Hour= 0, IsPushDelayed = 'false' WHERE id=" + channel.id;
	 mssql.query(sqlDelete412TimeStamp);
	}
}

As you can see, I am checking my Boolean that I added before. If it is still true, I am writing a log entry. If the time has passed already, I am resetting those time values to 0 respective the Boolean to false.

The script will now check if the push channel is still a 412 or turned in to a 404, and so everything starts over again.

Other error codes

There might be other error codes as well. I did not see any other than those two in my logs, but for the case there would be another, I simply added this code to report them:

else
{
 console.error("error in Toast Push Channel: " + channel.twitterScreenName, channel.id, error)
}

This way, you can easily handle push channel errors in your Mobile Service.

If you have other error codes in your logs, check this list from Microsoft to determine what you should do: http://msdn.microsoft.com/en-us/library/windowsphone/develop/ff941100(v=vs.105).aspx#BKMK_PushNotificationServiceResponseCodes

Note: there might be better ways to handle those errors. If you are using such a way, feel free to leave a comment with your approach.

Otherwise, I hope this post will be helpful for some of you.

Happy coding!

Posted by msicc in Azure, Dev Stories, 0 comments

Getting productive with WAMS: How to call Twitter REST API 1.1 from a scheduled script

WAMS.png

Like I promised in my first post about Windows Azure Mobile Services, I will show you how to call the Twitter Rest API 1.1 from a scheduled script. The documentation of the http request object does only use Twitter API 1.0 (which is no longer available).

First, you will need a Consumer key and a Consumer secret for your app. Just go to dev.twitter.com, register with your Twitter account and then add a new application.

The second thing you will need, is the so called Access token and Access token secret. Both are user dependent, without them Twitter will give you an error that your app is not authorized to use this account for anything on Twitter.

There are several ways to obtain these values. As I am registering the user within my phone app, I am uploading these values from phone and store it in my Mobile Services database.

To generate the requested data, we need several additional data for our request to Twitter:

  • a timestamp for the oAuth Header and the signature string
  • a random number to secure the request (= nonce)
  • an oAuth signature (signed array of the user’s data)
  • a HMAC encoded Hash string

These data is used for our request to Twitter.

Let’s start with the “simple” things:

generate Timestamp:

//generating the timestamp for the OAuth Header and signature string
var timestamp  = new Date() / 1000;
timestamp = Math.round(timestamp);

generate nonce

function generateNonce() {
    var code = "";
    for (var i = 0; i < 20; i++) {
        code += Math.floor(Math.random() * 9).toString();
    }
    return code;
}

oAuth signature

//generating the oAuth signatured array for the Twitter request
function generateOAuthSignature(method, url, data) {
    //remove query string parameters
    var index = url.indexOf('?');
    if (index > 0)
        url = url.substring(0, url.indexOf('?'));

    var signingToken = encodeURIComponent(ConsumerSecret) + "&" + encodeURIComponent(twitterAccessTokenSecret);

    var keys = [];
    for (var d in data) {
        if (d != 'oauth_signature') {
            //console.log('data:', d);
            keys.push(d);
        }
    }

    keys.sort();
    var output = "GET&" + encodeURIComponent(url) + "&";
    var params = "";
    keys.forEach(function (k) {
        params += "&" + encodeURIComponent(k) + "=" + encodeURIComponent(data[k]);
    });
    params = encodeURIComponent(params.substring(1));

    return hashString(signingToken, output + params, "base64");
}

generate the HMAC encoded hash string

//generate Hash-string, encoded in HMAC-SHA1 as required by Twitter's API v1.1
function hashString(key, str, encoding) {
    //console.log('basestring:', str);
    var hmac = crypto.createHmac("sha1", key);
    hmac.update(str);
    return hmac.digest(encoding);
}

Now we have prepared all of these functions, we are well prepared to call the Twitter API. In this example we are calling the user’s profile data:

function requestToTwitter()
{

    //the url declaration has to be in this function to make the request working!
    //declaring it in another function would cause an error 401 from Twitter's API
    url = 'https://api.twitter.com/1.1/users/show.json?user_id=' + twitterId;

    //generate data for sending the request to Twitter
    //this is the data used in the signature string as well as in the Authorization header
    var oAuthData = {oauth_consumer_key: ConsumerKey, oauth_nonce: nonce, oauth_signature: null, oauth_signature_method: "HMAC-SHA1", oauth_timestamp: timestamp, oauth_token: twitterAccessToken, oauth_version: "1.0"};
    var sigData = {};
    for (var k in oAuthData) {
        sigData[k] = oAuthData[k];
    }
    sigData['user_id'] = twitterId;

    var sig = generateOAuthSignature('GET', url, sigData);
    oAuthData.oauth_signature = sig;

    var oAuthHeader = "";
    for (k in oAuthData) {
        oAuthHeader += "," + encodeURIComponent(k) + "=\"" + encodeURIComponent(oAuthData[k]) + "\"";
    }
    oAuthHeader = oAuthHeader.substring(1);
    //very important to not miss the space after OAuth!
    authHeader = 'OAuth '+oAuthHeader;

    var reqOptions = {
            uri: url,
            headers: { 'Accept': 'application/json', 'Authorization': authHeader }
    };

    var httpRequest = require('request');
        httpRequest(reqOptions,callback );

}

var callback = function(err, response, body) {
    //console.log("in requestToTwitter = callback"); 
            if (err) {
            console.log(err)
            } else if (response.statusCode !== 200) {
                console.log("from twitter callback " + response.statusCode + " response: " + response.body);
            } else {
                var userProfile = JSON.parse(body);
                UserIdFromTwitter = userProfile.id;
                twitterScreenName = userProfile.screen_name;

}
}

You may have noticed that there are several variables that are not declared within these functions. Just declare them globally in your scheduled script.

You can read more about the oAuth authorization process at http://oauth.net/.

There are more services out there that use the oAuth process, so you should be able to convert this for other requests, like getPocket.com (formerly Read It later) and others.

As always, I hope this post was helpful for some of you.

Happy coding!

Posted by msicc in Azure, Dev Stories, 0 comments

Getting productive with WAMS: how to set up a timeout before running code in an interval

WAMS

I truly love Windows Azure Mobile Services, as it provides an easy way to connect Windows Phone apps to the cloud and also manages Live Tiles and Toast Notifications via Push. This way, we don’t have an impact on the users battery life by running background agents.

However, scheduled scripts are only able to run in predefined time windows, with 15 minutes at lowest.

It may happen that you want to run your script in shorter intervals, as I am currently implementing into mine.

The functions:  setTimeout() and setInterval()

The difference between those two is pretty simple:

  • setTimeout() is running the function included only once after the time in milliseconds has passed
  • setInterval() is running the function included in an interval set up in milliseconds until it gets stopped

Knowing this, it is pretty simple to set up those two functions each for itself:

setTimeout(function() { 
//code to run 
}, time in milliseconds);

setInterval(function() {
//code to run
}, time in milliseconds);

I highly recommend to declare an interval as a variable. If you won’t do that, the interval will run forever as you never can stop it!

But what if we need first a timeout and then an interval?

That is the problem I was trying to solve over the last two days. I was playing around with all kinds of code constellations to achieve this goal. And I found a solution.

We need to set up a few things to achieve that goal:

  • global variables for the number of runs and the interval
  • a function that only proves if the interval is still valid to run or needs to be stopped
  • our function that should be run in an interval

In my example, I want the code to be executed five times, then the interval should be stopped (cleared). I achieve this goal with a pretty simple if/else clause, like you can see:

if (NumberOfRuns < 6)
{
        console.log("interval ran " + NumberOfRuns + " times");
        doSomething();
        }
        else
        {
        //stoping the interval       
        clearInterval(Interval);
        console.log("interval stopped!");
}

As this is a sample script, I use the function doSomething() to be executed. This represents your code that should be executed if the interval is still valid. Only important thing: counting up the number of runs every time the function is hit.

    //counting up the number of runs with every call of the function
    NumberOfRuns++;

    //your code runs here

And in our starting point (the function that has the same name like your script), we finally declare the the timeout as well as we start to count:

   //setting the NumberofRuns to 1 as after timeout the first run starts
   NumberOfRuns = 1;
   console.log("start")

   //settings timeout to call the function that proves if the interval is still valid
   setTimeout(function(){
       //interval has to be defined in this scope, otherwise it will not be accepted
       //we also need a variable for the interval to be able to stop the interval
       Interval = setInterval(RunInterval, 5000);
       console.log("timeout is over");
   },15000);

First, we start our counter with 1, as after the timeout the code will be executed for the first time. I added also some logging functions, so you can prove everything is running fine.

The content of the global variable “Interval” has to be declared within the timeout, otherwise we will not be able to set the interval for our function.

Once you figured all the points above, it is pretty easy to implement this into your running script.

If you want to play around with this and see what the log looks like, here is the full WAMS scheduler script:

//declaring global variables
var NumberOfRuns;
var Interval;

//function to execute in interval
function doSomething()
{
    //counting up the number of runs with every call of the function
    NumberOfRuns++;

    //your code runs here
}

//this function proves if the the interval is still valid
function RunInterval()
{
     if (NumberOfRuns < 6)
        {
        console.log("interval ran " + NumberOfRuns + " times");
        doSomething();
        }
        else
        {
        //stoping the interval       
        clearInterval(Interval);
        console.log("interval stopped!");
        }
}

//main script function (start)
function TestIntervalScript() 
{
   //setting the NumberofRuns to 1 as after timeout the first run starts
   NumberOfRuns = 1;
   console.log("start")

   //settings timeout to call the function that proves if the interval is still valid
   setTimeout(function(){
       //interval has to be defined in this scope, otherwise it will not be accepted
       //we also need a variable for the interval to be able to stop the interval
       Interval = setInterval(RunInterval, 5000);
       console.log("timeout is over");
   },15000);
}

And here is a screen shot from the desired log file:

Screenshot (192)

As I am still pretty new to JavaScript,  there might be also other ways to achieve this. Feel free to leave a comment if you have anything to add/improve on this code.

And as always, I hope this is helpful for some of you when playing around with Windows Azure Mobile Services.

Happy coding!

Posted by msicc in Azure, Dev Stories, 0 comments

Getting productive with WAMS: respect time zone offset for every single user

time_Azure

In my second post about WAMS I will show you how to respect the time zone of every user.

If you have users that are from all over the world, they have all different time zones. Your Mobile Service script runs always at UTC time, and every user gets the same date & time if you send them push notifications or update a live tile for example. Users don’t want to calculate the time zone differences, so we need to handle that for them.

UTC time is the time since 01/01/1970 00:00 in milliseconds. If we know this, it is somewhat easy to show users their local date and time.

Let’s have a look at the Windows Phone code.

To get the local time zone in our Windows Phone app, we only need three lines of code:

TimeZoneInfo localZone = TimeZoneInfo.Local;
DateTime localTime = DateTime.Now;
TimeSpan offsetToUTC = localZone.GetUtcOffset(localTime);

As you can see, we are getting the local time zone first. This is essential as this one is UTC based. Then we are creating a TimeSpan on our actual DateTime object to get the offset. To make this TimeSpan working on our Azure Mobile Service, which uses JavaScript, we need to convert it to milliseconds. That is the value that has an equal value on all programming languages.

useritemLookUp.TimezoneOffset = offsetToUTC.TotalMilliseconds;

This is the final line of code, which is used to update our user’s item in our SQL table row (for example).

Let’s have a look at the Azure code.

The code is similar to our Windows Phone part. First, we need to fetch the time zone offset from our SQL table:

var sql = "select * from users";

mssql.query(sql, {
        success: function (results) {
            if (results.length > 0) {
                for (var i = 0; i < results.length; i++) {
                    userResult = {
                                        TimeZoneOffset: results[i].TimezoneOffset,
                                        }

TimeZoneOffset = userResult.TimeZoneOffset;

This way, we can run through our whole table on an Azure Script and calculate the correct time, which is pretty easy to achieve:

var d = new Date();
var locald = new Date(d.getTime() + TimeZoneOffset);

These two lines generate the local time in Milliseconds for the specific user entry. You don’t have to worry whether a user is before or after UTC, it will always calculate the correct time.

If you want to use it for example to show the updated time to your users, you can format the time like I described earlier in this post.

That’s all about respecting local time for your users with Windows Azure and Windows Phone.

Happy coding everyone!

Posted by msicc in Azure, Dev Stories, 0 comments

Getting productive with WAMS: how to update data for a specific row in a table

WAMS.png

Like I promised, I will share some of the Azure goodness I learned during creating my last app.

This post is all about how to update a specific table entry (like a user’s data) in a Azure SQL table from an Windows Phone app.

First, we need to make sure that there is some data from the user we want to update. I used the LookupAsync () method to achieve that.

IMobileServiceTable<userItems> TableToUpdate = App.MobileService.GetTable<userItems>();
IMobileServiceTableQuery<userItems> query = TableToUpdate.Where(useritem => useritem.TwitterId == App.TwitterId);

var useritemFromAzure = await query.ToListAsync();
var useritemLookUp = await TableToUpdate.LookupAsync(useritemFromAzure.FirstOrDefault<userItems>().Id);

If we want a specific entry, we need a search criteria to find our user and fetch the id of the user’s table entry. In my case, I used the Twitter Id for the query as every user has this on my project.

Now that we have the table row id, we can easily update the data of this specific row with the UpdateAsync() method.

We need to declare which columns should be updated and asign the values to it first. After that, we simply call the UpdateAsync() method.

useritemLookUp.TwitterId = App.TwitterId;
useritemLookUp.LastCheckedAt = DateTime.Now;
useritemLookUp.OSVersion = "WP8";
useritemLookUp.AppVersion = App.VersionNumber;

await TableToUpdate.UpdateAsync(useritemLookUp);

Please note that you need a items class/model to create the update data (which you should have already before thinking about updating the data).

You should wrap this code in a try{}/catch{} block to be able to react to the Exceptions that possibly can be thrown and display a matching message to the user.

That’s already all about updating a specific row in a WAMS SQL table.

As always I hope this post is helpful for some of you.

Happy coding!

Posted by msicc in Azure, Dev Stories, 1 comment

New Series: Getting productive with Windows Azure Mobile Services (WAMS)

WAMS

Now that my current app project is near to go live, I will start a new series about how to get productive with Windows Azure Mobile Services (WAMS).

I will cover some interesting topics in this series, which are not really documented in the very well written “Getting started” series from the Azure team itself.

These topics are (list is subject to be updated if needed):

First, if you want to get  started, you should check out this link: http://www.windowsazure.com/en-us/develop/mobile/tutorials/get-started-wp8/

The tutorial makes you very easy and fast using WAMS.

What can you expect from this series? As always, I will add some of my personal experiences during my journey of creating my app. There were a lot of small stones in my way, and I will also tell you how to remove them. And of course I hope that my posts will help some of you to get their own WAMS story started.

Happy coding everyone!

Posted by msicc in Azure, Dev Stories, 0 comments

How to format Date and Time on Windows Azure

time_Azure

Phew, my first post about my journey on starting development on Windows Azure. I started a few weeks ago using the Mobile Services from Windows Azure, and I did learn a lot about it.

This post is about formatting Date and Time strings, because Azure uses a different format than my Windows Phone app.

If we upload a DateTime String to Windows Azure from a Windows Phone app, it looks like this: 2013-05-04T06:45:12.042+00:00

If we translate this, you have “YYYY-MM-DD” for the date. The letter “T” declares that the time string  is starting now, formatted “HH:MM:ss.msmsms”. The part “+00:00” is the timezone offset.

So far, probably nothing new for you.

Now let’s get to Azure. Azure by standard uses the GMT time for Date strings (DateTime() in JavaScript = Date()). I have written a scheduler which fetches data from another web service and puts it into my table. Naturally, I wanted to know when the data were last checked, so I added a column for it.

Then I did what everyone that is new to JavaScript has done and added a variable with a new Date(). And now the trouble begins. The output of new Date() is a totally different string: Sat, 04 May 2013 07:02:51 GMT.

Sure, we can parse and convert it within our app, but that would need (although not much) additional resources. So I decided to let to Azure the conversion to a Windows Phone readable string.

How do we  manipulate the Date()-string?

I binged a bit and finally found a very helpful page, that explains all about the JavaScript Date() object: http://www.elated.com/articles/working-with-dates/

I then started off with the following code:

var d = new Date();
var formattedDate = d.getFullYear() + "-" + d.getMonth() + "-" + d.getDate();
var formattedTime  = d.getHours() + ':' d.getMinutes() + ':' + d.getSeconds();
var checkedDateTime = formattedDate + "T" + t;

Those of you that are familiar with JavaScript will immediately see what I did wrong. Let me explain for the newbies:

First thing, date().getMonth is zerobased. So we will always get a result that is one month behind. We have to get it this way for the correct month:

d.getMonth()+1

But that is not all. If you will use the code above, your result will look like this: 2013-5-4T7:2:51

JavaScript does not use leading zeros. If you want to insert it into a date formatted column, you will get the following error from Azure:

Error occurred executing query: Error: [Microsoft][SQL Server Native Client 10.0][SQL Server]Conversion failed when converting date and/or time from character string.

So we need to add the leading zero before inserting it. Luckily we are able to that very easy. Here is my implementation:

var d = new Date();
var formattedDate = d.getFullYear() + "-" + ('0' + (d.getMonth()+1)).slice(-2) + "-" + ('0' + d.getDate()).slice(-2);
var formattedTime  = ('0' + d.getHours()).slice(-2) + ':' + ('0' + d.getMinutes()).slice(-2) + ':' + ('0' + d.getSeconds()).slice(-2);
var checkedDateTime = formattedDate + "T" + t;

What have we done here?

We are adding the leading 0 to each object string. The slice(-2) is for only picking the last two numbers. To make it more clear: if we have 9 as hour, adding the zero in front results in 09. Picking only the last two numbers by .slice(-2) results in still in 09. If we have 10 as hour, adding the leading zero results in 010. But the .slice(-2) operation will cut it back to 10. Easy enough, right?

If we run the code above to get the Date and Time, the result will look like this: 2013-05-04T7:02:51

The timezone offset is automatically added to the date when we update the table. If we now send the data to our Windows Phone or Windows 8 app, no conversion is needed as we already have a correctly formatted string.

I hope this is helpful for some of you and will save you some time.

Happy coding everyone!

Posted by msicc in Azure, Dev Stories, 0 comments