Wednesday, 20 June 2012

NFC Basics - Android


NFC Basics

This document describes the basic NFC tasks you perform in Android. It explains how to send and receive NFC data in the form of NDEF messages and describes the Android framework APIs that support these features.
There are two major uses cases when working with NDEF data and Android:
  • Reading NDEF data from an NFC tag
  • Beaming NDEF messages from one device to another with Android Beam™
Reading NDEF data from an NFC tag is handled with the tag dispatch system, which analyzes discovered NFC tags, appropriately categorizes the data, and starts an application that is interested in the categorized data. An application that wants to handle the scanned NFC tag can declare an intent filter and request to handle the data.
The Android Beam™ feature allows a device to push an NDEF message onto another device by physically tapping the devices together. This interaction provides an easier way to send data than other wireless technologies like Bluetooth, because with NFC, no manual device discovery or pairing is required. The connection is automatically started when two devices come into range. Android Beam is available through a set of NFC APIs, so any application can transmit information between devices. For example, the Contacts, Browser, and YouTube applications use Android Beam to share contacts, web pages, and videos with other devices.

The Tag Dispatch System

Android-powered devices are usually looking for NFC tags when the screen is unlocked, unless NFC is disabled in the device's Settings menu. When an Android-powered device discovers an NFC tag, the desired behavior is to have the most appropriate activity handle the intent without asking the user what application to use. Because devices scan NFC tags at a very short range, it is likely that making users manually select an activity would force them to move the device away from the tag and break the connection. You should develop your activity to only handle the NFC tags that your activity cares about to prevent the Activity Chooser from appearing.
To help you with this goal, Android provides a special tag dispatch system that analyzes scanned NFC tags, parses them, and tries to locate applications that are interested in the scanned data. It does this by:
  1. Parsing the NFC tag and figuring out the MIME type or a URI that identifies the data payload in the tag.
  2. Encapsulating the MIME type or URI and the payload into an intent. These first two steps are described in How NFC tags are mapped to MIME types and URIs.
  3. Starts an activity based on the intent. This is described in How NFC Tags are Dispatched to Applications.

How NFC tags are mapped to MIME types and URIs

Before you begin writing your NFC applications, it is important to understand the different types of NFC tags, how the tag dispatch system parses NFC tags, and the special work that the tag dispatch system does when it detects an NDEF message. NFC tags come in a wide array of technologies and can also have data written to them in many different ways. Android has the most support for the NDEF standard, which is defined by the NFC Forum.
NDEF data is encapsulated inside a message (NdefMessage) that contains one or more records (NdefRecord). Each NDEF record must be well-formed according to the specification of the type of record that you want to create. Android also supports other types of tags that do not contain NDEF data, which you can work with by using the classes in the android.nfc.tech package. To learn more about these technologies, see the Advanced NFC topic. Working with these other types of tags involves writing your own protocol stack to communicate with the tags, so we recommend using NDEF when possible for ease of development and maximum support for Android-powered devices.
Note: To download complete NDEF specifications, go to the NFC Forum Specification Download site and see Creating common types of NDEF records for examples of how to construct NDEF records.
Now that you have some background in NFC tags, the following sections describe in more detail how Android handles NDEF formatted tags. When an Android-powered device scans an NFC tag containing NDEF formatted data, it parses the message and tries to figure out the data's MIME type or identifying URI. To do this, the system reads the first NdefRecord inside the NdefMessage to determine how to interpret the entire NDEF message (an NDEF message can have multiple NDEF records). In a well-formed NDEF message, the first NdefRecord contains the following fields:
3-bit TNF (Type Name Format)
Indicates how to interpret the variable length type field. Valid values are described in described in Table 1.
Variable length type
Describes the type of the record. If using TNF_WELL_KNOWN, use this field to specify the Record Type Definition (RTD). Valid RTD values are described in Table 2.
Variable length ID
A unique identifier for the record. This field is not used often, but if you need to uniquely identify a tag, you can create an ID for it.
Variable length payload
The actual data payload that you want to read or write. An NDEF message can contain multiple NDEF records, so don't assume the full payload is in the first NDEF record of the NDEF message.
The tag dispatch system uses the TNF and type fields to try to map a MIME type or URI to the NDEF message. If successful, it encapsulates that information inside of aACTION_NDEF_DISCOVERED intent along with the actual payload. However, there are cases when the tag dispatch system cannot determine the type of data based on the first NDEF record. This happens when the NDEF data cannot be mapped to a MIME type or URI, or when the NFC tag does not contain NDEF data to begin with. In such cases, a Tag object that has information about the tag's technologies and the payload are encapsulated inside of a ACTION_TECH_DISCOVERED intent instead.
Table 1. describes how the tag dispatch system maps TNF and type fields to MIME types or URIs. It also describes which TNFs cannot be mapped to a MIME type or URI. In these cases, the tag dispatch system falls back to ACTION_TECH_DISCOVERED.
For example, if the tag dispatch system encounters a record of type TNF_ABSOLUTE_URI, it maps the variable length type field of that record into a URI. The tag dispatch system encapsulates that URI in the data field of an ACTION_NDEF_DISCOVERED intent along with other information about the tag, such as the payload. On the other hand, if it encounters a record of type TNF_UNKNOWN, it creates an intent that encapsulates the tag's technologies instead.
Table 1. Supported TNFs and their mappings
Type Name Format (TNF)Mapping
TNF_ABSOLUTE_URIURI based on the type field.
TNF_EMPTYFalls back to ACTION_TECH_DISCOVERED.
TNF_EXTERNAL_TYPEURI based on the URN in the type field. The URN is encoded into the NDEF type field in a shortened form: <domain_name>:<service_name>. Android maps this to a URI in the form: vnd.android.nfc://ext/<domain_name>:<service_name>.
TNF_MIME_MEDIAMIME type based on the type field.
TNF_UNCHANGEDInvalid in the first record, so falls back to ACTION_TECH_DISCOVERED.
TNF_UNKNOWNFalls back to ACTION_TECH_DISCOVERED.
TNF_WELL_KNOWNMIME type or URI depending on the Record Type Definition (RTD), which you set in the type field. See Table 2. for more information on available RTDs and their mappings.
Table 2. Supported RTDs for TNF_WELL_KNOWN and their mappings
Record Type Definition (RTD)Mapping
RTD_ALTERNATIVE_CARRIERFalls back to ACTION_TECH_DISCOVERED.
RTD_HANDOVER_CARRIERFalls back to ACTION_TECH_DISCOVERED.
RTD_HANDOVER_REQUESTFalls back to ACTION_TECH_DISCOVERED.
RTD_HANDOVER_SELECTFalls back to ACTION_TECH_DISCOVERED.
RTD_SMART_POSTERURI based on parsing the payload.
RTD_TEXTMIME type of text/plain.
RTD_URIURI based on payload.

How NFC Tags are Dispatched to Applications

When the tag dispatch system is done creating an intent that encapsulates the NFC tag and its identifying information, it sends the intent to an interested application that filters for the intent. If more than one application can handle the intent, the Activity Chooser is presented so the user can select the Activity. The tag dispatch system defines three intents, which are listed in order of highest to lowest priority:
  1. ACTION_NDEF_DISCOVERED: This intent is used to start an Activity when a tag that contains an NDEF payload is scanned and is of a recognized type. This is the highest priority intent, and the tag dispatch system tries to start an Activity with this intent before any other intent, whenever possible.
  2. ACTION_TECH_DISCOVERED: If no activities register to handle the ACTION_NDEF_DISCOVERED intent, the tag dispatch system tries to start an application with this intent. This intent is also directly started (without starting ACTION_NDEF_DISCOVERED first) if the tag that is scanned contains NDEF data that cannot be mapped to a MIME type or URI, or if the tag does not contain NDEF data but is of a known tag technology.
  3. ACTION_TAG_DISCOVERED: This intent is started if no activities handle the ACTION_NDEF_DISCOVERED or ACTION_TECH_DISCOVERED intents.
The basic way the tag dispatch system works is as follows:
  1. Try to start an Activity with the intent that was created by the tag dispatch system when parsing the NFC tag (either ACTION_NDEF_DISCOVERED orACTION_TECH_DISCOVERED).
  2. If no activities filter for that intent, try to start an Activity with the next lowest priority intent (either ACTION_TECH_DISCOVERED or ACTION_TAG_DISCOVERED) until an application filters for the intent or until the tag dispatch system tries all possible intents.
  3. If no applications filter for any of the intents, do nothing.
Figure 1. Tag Dispatch System
Whenever possible, work with NDEF messages and the ACTION_NDEF_DISCOVERED intent, because it is the most specific out of the three. This intent allows you to start your application at a more appropriate time than the other two intents, giving the user a better experience.

Requesting NFC Access in the Android Manifest

Before you can access a device's NFC hardware and properly handle NFC intents, declare these items in your AndroidManifest.xml file:
  • The NFC <uses-permission> element to access the NFC hardware:
    <uses-permission android:name="android.permission.NFC" />
  • The minimum SDK version that your application can support. API level 9 only supports limited tag dispatch via ACTION_TAG_DISCOVERED, and only gives access to NDEF messages via the EXTRA_NDEF_MESSAGES extra. No other tag properties or I/O operations are accessible. API level 10 includes comprehensive reader/writer support as well as foreground NDEF pushing, and API level 14 provides an easier way to push NDEF messages to other devices with Android Beam and extra convenience methods to create NDEF records.
    <uses-sdk android:minSdkVersion="10"/>
  • The uses-feature element so that your application shows up in Google Play only for devices that have NFC hardware:
    <uses-feature android:name="android.hardware.nfc" android:required="true" />
    If your application uses NFC functionality, but that functionality is not crucial to your application, you can omit the uses-feature element and check for NFC avalailbility at runtime by checking to see if getDefaultAdapter() is null.

Filtering for NFC Intents

To start your application when an NFC tag that you want to handle is scanned, your application can filter for one, two, or all three of the NFC intents in the Android manifest. However, you usually want to filter for the ACTION_NDEF_DISCOVERED intent for the most control of when your application starts. TheACTION_TECH_DISCOVERED intent is a fallback for ACTION_NDEF_DISCOVERED when no applications filter for ACTION_NDEF_DISCOVERED or for when the payload is not NDEF. Filtering for ACTION_TAG_DISCOVERED is usually too general of a category to filter on. Many applications will filter for ACTION_NDEF_DISCOVERED orACTION_TECH_DISCOVERED before ACTION_TAG_DISCOVERED, so your application has a low probability of starting. ACTION_TAG_DISCOVERED is only available as a last resort for applications to filter for in the cases where no other applications are installed to handle the ACTION_NDEF_DISCOVERED orACTION_TECH_DISCOVEREDintent.
Because NFC tag deployments vary and are many times not under your control, this is not always possible, which is why you can fallback to the other two intents when necessary. When you have control over the types of tags and data written, it is recommended that you use NDEF to format your tags. The following sections describe how to filter for each type of intent.

ACTION_NDEF_DISCOVERED

To filter for ACTION_NDEF_DISCOVERED intents, declare the intent filter along with the type of data that you want to filter for. The following example filters forACTION_NDEF_DISCOVERED intents with a MIME type of text/plain:
<intent-filter>
    <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
    <category android:name="android.intent.category.DEFAULT"/>
    <data android:mimeType="text/plain" />
</intent-filter>
The following example filters for a URI in the form of http://developer.android.com/index.html.
<intent-filter>
    <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
    <category android:name="android.intent.category.DEFAULT"/>
   <data android:scheme="http"
              android:host="developer.android.com"
              android:pathPrefix="/index.html" />
</intent-filter>

ACTION_TECH_DISCOVERED

If your activity filters for the ACTION_TECH_DISCOVERED intent, you must create an XML resource file that specifies the technologies that your activity supports within atech-list set. Your activity is considered a match if a tech-list set is a subset of the technologies that are supported by the tag, which you can obtain by callinggetTechList().
For example, if the tag that is scanned supports MifareClassic, NdefFormatable, and NfcA, your tech-list set must specify all three, two, or one of the technologies (and nothing else) in order for your activity to be matched.
The following sample defines all of the technologies. You can remove the ones that you do not need. Save this file (you can name it anything you wish) in the <project-root>/res/xml folder.
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <tech-list>
        <tech>android.nfc.tech.IsoDep</tech>
        <tech>android.nfc.tech.NfcA</tech>
        <tech>android.nfc.tech.NfcB</tech>
        <tech>android.nfc.tech.NfcF</tech>
        <tech>android.nfc.tech.NfcV</tech>
        <tech>android.nfc.tech.Ndef</tech>
        <tech>android.nfc.tech.NdefFormatable</tech>
        <tech>android.nfc.tech.MifareClassic</tech>
        <tech>android.nfc.tech.MifareUltralight</tech>
    </tech-list>
</resources>
You can also specify multiple tech-list sets. Each of the tech-list sets is considered independently, and your activity is considered a match if any single tech-list set is a subset of the technologies that are returned by getTechList(). This provides AND and OR semantics for matching technologies. The following example matches tags that can support the NfcA and Ndef technologies or can support the NfcB and Ndef technologies:
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <tech-list>
        <tech>android.nfc.tech.NfcA</tech>
        <tech>android.nfc.tech.Ndef</tech>
    </tech-list>
</resources>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <tech-list>
        <tech>android.nfc.tech.NfcB</tech>
        <tech>android.nfc.tech.Ndef</tech>
    </tech-list>
</resources>
In your AndroidManifest.xml file, specify the resource file that you just created in the <meta-data> element inside the <activity> element like in the following example:
<activity>
...<intent-filter>
    <action android:name="android.nfc.action.TECH_DISCOVERED"/>
</intent-filter>
<meta-data android:name="android.nfc.action.TECH_DISCOVERED"
    android:resource="@xml/nfc_tech_filter" />
...</activity>
For more information about working with tag technologies and the ACTION_TECH_DISCOVERED intent, see Working with Supported Tag Technologies in the Advanced NFC document.

ACTION_TAG_DISCOVERED

To filter for ACTION_TAG_DISCOVERED use the following intent filter:
<intent-filter>
    <action android:name="android.nfc.action.TAG_DISCOVERED"/>
</intent-filter>

Obtaining information from intents

If an activity starts because of an NFC intent, you can obtain information about the scanned NFC tag from the intent. Intents can contain the following extras depending on the tag that was scanned:
To obtain these extras, check to see if your activity was launched with one of the NFC intents to ensure that a tag was scanned, and then obtain the extras out of the intent. The following example checks for the ACTION_NDEF_DISCOVERED intent and gets the NDEF messages from an intent extra.
public void onResume() {
    super.onResume();
    ...
    if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
        Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
        if (rawMsgs != null) {
            msgs = new NdefMessage[rawMsgs.length];
            for (int i = 0; i < rawMsgs.length; i++) {
                msgs[i] = (NdefMessage) rawMsgs[i];
            }
        }
    }
    //process the msgs array
}
Alternatively, you can obtain a Tag object from the intent, which will contain the payload and allow you to enumerate the tag's technologies:
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);

Creating Common Types of NDEF Records

This section describes how to create common types of NDEF records to help you when writing to NFC tags or sending data with Android Beam. It also describes how to create the corresponding intent filter for the record. All of these NDEF record examples should be in the first NDEF record of the NDEF message that you are writing to a tag or beaming.

TNF_ABSOLUTE_URI

Given the following TNF_ABSOLUTE_URI NDEF record, which is stored as the first record inside of an NdefMessage:
NdefRecord uriRecord = new NdefRecord(
    NdefRecord.TNF_ABSOLUTE_URI ,
    "http://developer.android.com/index.html".getBytes(Charset.forName("US-ASCII")),
    new byte[0], new byte[0]);
the intent filter would look like this:
<intent-filter>
    <action android:name="android.nfc.action.NDEF_DISCOVERED" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:scheme="http"
        android:host="developer.android.com"
        android:pathPrefix="/index.html" />
</intent-filter>

TNF_MIME_MEDIA

Given the following TNF_MIME_MEDIA NDEF record, which is stored as the first record inside of an NdefMessage:
NdefRecord mimeRecord = new NdefRecord(
    NdefRecord.TNF_MIME_MEDIA ,
    "application/com.example.android.beam".getBytes(Charset.forName("US-ASCII")),
    new byte[0], "Beam me up, Android!".getBytes(Charset.forName("US-ASCII")));
the intent filter would look like this:
<intent-filter>
    <action android:name="android.nfc.action.NDEF_DISCOVERED" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:mimeType="application/com.example.android.beam" />
</intent-filter>

TNF_WELL_KNOWN with RTD_TEXT

Given the following TNF_WELL_KNOWN NDEF record, which is stored as the first record inside of an NdefMessage:
public NdefRecord createTextRecord(String payload, Locale locale, boolean encodeInUtf8) {
    byte[] langBytes = locale.getLanguage().getBytes(Charset.forName("US-ASCII"));
    Charset utfEncoding = encodeInUtf8 ? Charset.forName("UTF-8") : Charset.forName("UTF-16");
    byte[] textBytes = payload.getBytes(utfEncoding);
    int utfBit = encodeInUtf8 ? 0 : (1 << 7);
    char status = (char) (utfBit + langBytes.length);
    byte[] data = new byte[1 + langBytes.length + textBytes.length];
    data[0] = (byte) status;
    System.arraycopy(langBytes, 0, data, 1, langBytes.length);
    System.arraycopy(textBytes, 0, data, 1 + langBytes.length, textBytes.length);
    NdefRecord record = new NdefRecord(NdefRecord.TNF_WELL_KNOWN,
    NdefRecord.RTD_TEXT, new byte[0], data);
    return record;
}
the intent filter would look like this:
<intent-filter>
    <action android:name="android.nfc.action.NDEF_DISCOVERED" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:mimeType="text/plain" />
</intent-filter>

TNF_WELL_KNOWN with RTD_URI

Given the following TNF_WELL_KNOWN NDEF record, which is stored as the first record inside of an NdefMessage:
byte[] uriField = "example.com".getBytes(Charset.forName("US-ASCII"));
byte[] payload = new byte[uriField.length + 1];              //add 1 for the URI Prefix
byte payload[0] = 0x01;                                      //prefixes http://www. to the URI
System.arraycopy(uriField, 0, payload, 1, uriField.length);  //appends URI to payload
NdefRecord rtdUriRecord = new NdefRecord(
    NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_URI, new byte[0], payload);
the intent filter would look like this:
<intent-filter>
    <action android:name="android.nfc.action.NDEF_DISCOVERED" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:scheme="http"
        android:host="example.com"
        android:pathPrefix="" />
</intent-filter>

TNF_EXTERNAL_TYPE

Given the following TNF_EXTERNAL_TYPE NDEF record, which is stored as the first record inside of an NdefMessage:
byte[] payload;
...
NdefRecord mimeRecord = new NdefRecord(
    NdefRecord.TNF_EXTERNAL_TYPE, "example.com:externalType", new byte[0], payload);
the intent filter would look like this:
<intent-filter>
    <action android:name="android.nfc.action.NDEF_DISCOVERED" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:scheme="vnd.android.nfc"
        android:host="ext"
        android:pathPrefix="/example.com:externalType"/>
</intent-filter>
Use TNF_EXTERNAL_TYPE for more generic NFC tag deployments to better support both Android-powered and non-Android-powered devices.
Note: URNs for TNF_EXTERNAL_TYPE have a canonical format of: urn:nfc:ext:example.com:externalType, however the NFC Forum RTD specification declares that the urn:nfc:ext: portion of the URN must be ommitted from the NDEF record. So all you need to provide is the domain (example.com in the example) and type (externalType in the example) separated by a colon. When dispatching TNF_EXTERNAL_TYPE, Android converts theurn:nfc:ext:example.com:externalType URN to a vnd.android.nfc://ext/example.com:externalType URI, which is what the intent filter in the example declares.

Android Application Records

Introduced in Android 4.0 (API level 14), an Android Application Record (AAR) provides a stronger certainty that your application is started when an NFC tag is scanned. An AAR has the package name of an application embedded inside an NDEF record. You can add an AAR to any NDEF record of your NDEF message, because Android searches the entire NDEF message for AARs. If it finds an AAR, it starts the application based on the package name inside the AAR. If the application is not present on the device, Google Play is launched to download the application.
AARs are useful if you want to prevent other applications from filtering for the same intent and potentially handling specific tags that you have deployed. AARs are only supported at the application level, because of the package name constraint, and not at the Activity level as with intent filtering. If you want to handle an intent at the Activity level, use intent filters.
If a tag contains an AAR, the tag dispatch system dispatches in the following manner:
  1. Try to start an Activity using an intent filter as normal. If the Activity that matches the intent also matches the AAR, start the Activity.
  2. If the Activity that filters for the intent does not match the AAR, if multiple Activities can handle the intent, or if no Activity handles the intent, start the application specified by the AAR.
  3. If no application can start with the AAR, go to Google Play to download the application based on the AAR.
Note: You can override AARs and the intent dispatch system with the foreground dispatch system, which allows a foreground activity to have priority when an NFC tag is discovered. With this method, the activity must be in the foreground to override AARs and the intent dispatch system.
If you still want to filter for scanned tags that do not contain an AAR, you can declare intent filters as normal. This is useful if your application is interested in other tags that do not contain an AAR. For example, maybe you want to guarantee that your application handles proprietary tags that you deploy as well as general tags deployed by third parties. Keep in mind that AARs are specific to Android 4.0 devices or later, so when deploying tags, you most likely want to use a combination of AARs and MIME types/URIs to support the widest range of devices. In addition, when you deploy NFC tags, think about how you want to write your NFC tags to enable support for the most devices (Android-powered and other devices). You can do this by defining a relatively unique MIME type or URI to make it easier for applications to distinguish.
Android provides a simple API to create an AAR, createApplicationRecord(). All you need to do is embed the AAR anywhere in your NdefMessage. You do not want to use the first record of your NdefMessage, unless the AAR is the only record in the NdefMessage. This is because the Android system checks the first record of an NdefMessage to determine the MIME type or URI of the tag, which is used to create an intent for applications to filter. The following code shows you how to create an AAR:
NdefMessage msg = new NdefMessage(
        new NdefRecord[] {
            ...,
            NdefRecord.createApplicationRecord("com.example.android.beam")}

Beaming NDEF Messages to Other Devices

Android Beam allows simple peer-to-peer data exchange between two Android-powered devices. The application that wants to beam data to another device must be in the foreground and the device receiving the data must not be locked. When the beaming device comes in close enough contact with a receiving device, the beaming device displays the "Touch to Beam" UI. The user can then choose whether or not to beam the message to the receiving device.
Note: Foreground NDEF pushing was available at API level 10, which provides similar functionality to Android Beam. These APIs have since been deprecated, but are available to support older devices. See enableForegroundNdefPush() for more information.
You can enable Android Beam for your application by calling one of the two methods:
An activity can only push one NDEF message at a time, so setNdefPushMessageCallback() takes precedence over setNdefPushMessage() if both are set. To use Android Beam, the following general guidelines must be met:
  • The activity that is beaming the data must be in the foreground. Both devices must have their screens unlocked.
  • You must encapsulate the data that you are beaming in an NdefMessage object.
  • The NFC device that is receiving the beamed data must support the com.android.npp NDEF push protocol or NFC Forum's SNEP (Simple NDEF Exchange Protocol). The com.android.npp protocol is required for devices on API level 9 (Android 2.3) to API level 13 (Android 3.2). com.android.npp and SNEP are both required on API level 14 (Android 4.0) and later.
Note: If your activity enables Android Beam and is in the foreground, the standard intent dispatch system is disabled. However, if your activity also enablesforeground dispatching, then it can still scan tags that match the intent filters set in the foreground dispatching.
To enable Android Beam:
  1. Create an NdefMessage that contains the NdefRecords that you want to push onto the other device.
  2. Call setNdefPushMessage() with a NdefMessage or call setNdefPushMessageCallback passing in a NfcAdapter.CreateNdefMessageCallbackobject in the onCreate() method of your activity. These methods require at least one activity that you want to enable with Android Beam, along with an optional list of other activities to activate.
    In general, you normally use setNdefPushMessage() if your Activity only needs to push the same NDEF message at all times, when two devices are in range to communicate. You use setNdefPushMessageCallback when your application cares about the current context of the application and wants to push an NDEF message depending on what the user is doing in your application.
The following sample shows how a simple activity calls NfcAdapter.CreateNdefMessageCallback in the onCreate() method of an activity (seeAndroidBeamDemo for the complete sample). This example also has methods to help you create a MIME record:
package com.example.android.beam;
import android.app.Activity;
import android.content.Intent;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.NfcAdapter.CreateNdefMessageCallback;
import android.nfc.NfcEvent;
import android.os.Bundle;
import android.os.Parcelable;
import android.widget.TextView;
import android.widget.Toast;
import java.nio.charset.Charset;

public class Beam extends Activity implements CreateNdefMessageCallback {
    NfcAdapter mNfcAdapter;
    TextView textView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        TextView textView = (TextView) findViewById(R.id.textView);
        // Check for available NFC Adapter
        mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
        if (mNfcAdapter == null) {
            Toast.makeText(this, "NFC is not available", Toast.LENGTH_LONG).show();
            finish();
            return;
        }
        // Register callback
        mNfcAdapter.setNdefPushMessageCallback(this, this);
    }

    @Override
    public NdefMessage createNdefMessage(NfcEvent event) {
        String text = ("Beam me up, Android!\n\n" +
                "Beam Time: " + System.currentTimeMillis());
        NdefMessage msg = new NdefMessage(
                new NdefRecord[] { createMimeRecord(
                        "application/com.example.android.beam", text.getBytes())
         /**
          * The Android Application Record (AAR) is commented out. When a device
          * receives a push with an AAR in it, the application specified in the AAR
          * is guaranteed to run. The AAR overrides the tag dispatch system.
          * You can add it back in to guarantee that this
          * activity starts when receiving a beamed message. For now, this code
          * uses the tag dispatch system.
          */
          //,NdefRecord.createApplicationRecord("com.example.android.beam")
        });
        return msg;
    }

    @Override
    public void onResume() {
        super.onResume();
        // Check to see that the Activity started due to an Android Beam
        if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
            processIntent(getIntent());
        }
    }

    @Override
    public void onNewIntent(Intent intent) {
        // onResume gets called after this to handle the intent
        setIntent(intent);
    }

    /**
     * Parses the NDEF Message from the intent and prints to the TextView
     */
    void processIntent(Intent intent) {
        textView = (TextView) findViewById(R.id.textView);
        Parcelable[] rawMsgs = intent.getParcelableArrayExtra(
                NfcAdapter.EXTRA_NDEF_MESSAGES);
        // only one message sent during the beam
        NdefMessage msg = (NdefMessage) rawMsgs[0];
        // record 0 contains the MIME type, record 1 is the AAR, if present
        textView.setText(new String(msg.getRecords()[0].getPayload()));
    }

    /**
     * Creates a custom MIME type encapsulated in an NDEF record
     */
    public NdefRecord createMimeRecord(String mimeType, byte[] payload) {
        byte[] mimeBytes = mimeType.getBytes(Charset.forName("US-ASCII"));
        NdefRecord mimeRecord = new NdefRecord(
                NdefRecord.TNF_MIME_MEDIA, mimeBytes, new byte[0], payload);
        return mimeRecord;
    }
}
Note that this code comments out an AAR, which you can remove. If you enable the AAR, the application specified in the AAR always receives the Android Beam message. If the application is not present, Google Play launches to download the application. Therefore, the following intent filter is not technically necessary for Android 4.0 devices or later if the AAR is used:
<intent-filter>
  <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
  <category android:name="android.intent.category.DEFAULT"/>
  <data android:mimeType="application/com.example.android.beam"/>
</intent-filter>
With this intent filter, the com.example.android.beam application now can be started when it scans an NFC tag or receives an Android Beam with an AAR of typecom.example.android.beam, or when an NDEF formatted message contains a MIME record of type application/com.example.android.beam.
Even though AARs guarantee an application is started or downloaded, intent filters are recommended, because they let you start an Activity of your choice in your application instead of always starting the main Activity within the package specified by an AAR. AARs do not have Activity level granularity. Also, because some Android-powered devices do not support AARs, you should also embed identifying information in the first NDEF record of your NDEF messages and filter for that as well, just in case. See Creating Common Types of NDEF records for more information on how to create records.

Monday, 18 June 2012

Testing Fundamentals for Android

Now I know this is a little of topic from recent posts, however I have recently taken a strong interest in Testing. Mobile devices are coming at us from all angles at the moment, I don’t think there has been a day that has gone by where I have not read about some sort of mobile application that has been created or bought out by a big name. That is why below I have skipped past the development stage of creating an Android Application and gone straight to the testing phase.
This is mainly for my pleasure however I just wanted to share the type of stuff I am currently reading.

The Android testing framework, an integral part of the development environment, provides an architecture and powerful tools that help you test every aspect of your application at every level from unit to framework.
The testing framework has these key features:
  • Android test suites are based on JUnit. You can use plain JUnit to test a class that doesn't call the Android API, or Android's JUnit extensions to test Android components. If you're new to Android testing, you can start with general-purpose test case classes such as AndroidTestCase and then go on to use more sophisticated classes.
  • The Android JUnit extensions provide component-specific test case classes. These classes provide helper methods for creating mock objects and methods that help you control the lifecycle of a component.
  • Test suites are contained in test packages that are similar to main application packages, so you don't need to learn a new set of tools or techniques for designing and building tests.
  • The SDK tools for building and tests are available in Eclipse with ADT, and also in command-line form for use with other IDES. These tools get information from the project of the application under test and use this information to automatically create the build files, manifest file, and directory structure for the test package.
  • The SDK also provides monkeyrunner, an API testing devices with Python programs, and UI/Application Exerciser Monkey, a command-line tool for stress-testing UIs by sending pseudo-random events to a device.
This document describes the fundamentals of the Android testing framework, including the structure of tests, the APIs that you use to develop tests, and the tools that you use to run tests and view results. The document assumes you have a basic knowledge of Android application programming and JUnit testing methodology.
The following diagram summarizes the testing framework:

 

Test Structure

Android's build and test tools assume that test projects are organized into a standard structure of tests, test case classes, test packages, and test projects.
Android testing is based on JUnit. In general, a JUnit test is a method whose statements test a part of the application under test. You organize test methods into classes called test cases (or test suites). Each test is an isolated test of an individual module in the application under test. Each class is a container for related test methods, although it often provides helper methods as well.
In JUnit, you build one or more test source files into a class file. Similarly, in Android you use the SDK's build tools to build one or more test source files into class files in an Android test package. In JUnit, you use a test runner to execute test classes. In Android, you use test tools to load the test package and the application under test, and the tools then execute an Android-specific test runner.

 

Test Projects

Tests, like Android applications, are organized into projects.
A test project is a directory or Eclipse project in which you create the source code, manifest file, and other files for a test package. The Android SDK contains tools for Eclipse with ADT and for the command line that create and update test projects for you. The tools create the directories you use for source code and resources and the manifest file for the test package. The command-line tools also create the Ant build files you need.
You should always use Android tools to create a test project. Among other benefits, the tools:
  • Automatically set up your test package to use InstrumentationTestRunner as the test case runner. You must use InstrumentationTestRunner (or a subclass) to run JUnit tests.
  • Create an appropriate name for the test package. If the application under test has a package name of com.mydomain.myapp, then the Android tools set the test package name to com.mydomain.myapp.test. This helps you identify their relationship, while preventing conflicts within the system.
  • Automatically create the proper build files, manifest file, and directory structure for the test project. This helps you to build the test package without having to modify build files and sets up the linkage between your test package and the application under test. The
You can create a test project anywhere in your file system, but the best approach is to add the test project so that its root directory tests/ is at the same level as the src/ directory of the main application's project. This helps you find the tests associated with an application. For example, if your application project's root directory is MyProject, then you should use the following directory structure:
  MyProject/
      AndroidManifest.xml
      res/
          ... (resources for main application)
      src/
          ... (source code for main application) ...
      tests/
          AndroidManifest.xml
          res/
              ... (resources for tests)
          src/
              ... (source code for tests)

 

The Testing API

The Android testing API is based on the JUnit API and extended with a instrumentation framework and Android-specific testing classes.

JUnit

You can use the JUnit TestCase class to do unit testing on a plain Java object. TestCase is also the base class for AndroidTestCase, which you can use to test Android-dependent objects. Besides providing the JUnit framework, AndroidTestCase offers Android-specific setup, teardown, and helper methods.
You use the JUnit Assert class to display test results. The assert methods compare values you expect from a test to the actual results and throw an exception if the comparison fails. Android also provides a class of assertions that extend the possible types of comparisons, and another class of assertions for testing the UI. These are described in more detail in the section Assertion classes
To learn more about JUnit, you can read the documentation on the junit.org home page. Note that the Android testing API supports JUnit 3 code style, but not JUnit 4. Also, you must use Android's instrumented test runner InstrumentationTestRunner to run your test case classes. This test runner is described in the section Running Tests.

Instrumentation

Android instrumentation is a set of control methods or "hooks" in the Android system. These hooks control an Android component independently of its normal lifecycle. They also control how Android loads applications.
Normally, an Android component runs in a lifecycle determined by the system. For example, an Activity object's lifecycle starts when the Activity is activated by an Intent. The object's onCreate() method is called, followed by onResume(). When the user starts another application, the onPause() method is called. If the Activity code calls the finish() method, the onDestroy() method is called. The Android framework API does not provide a way for your code to invoke these callback methods directly, but you can do so using instrumentation.
Also, the system runs all the components of an application into the same process. You can allow some components, such as content providers, to run in a separate process, but you can't force an application to run in the same process as another application that is already running.
With Android instrumentation, though, you can invoke callback methods in your test code. This allows you to run through the lifecycle of a component step by step, as if you were debugging the component. The following test code snippet demonstrates how to use this to test that an Activity saves and restores its state:
    // Start the main activity of the application under test
    mActivity = getActivity();

    // Get a handle to the Activity object's main UI widget, a Spinner
    mSpinner = (Spinner)mActivity.findViewById(com.android.example.spinner.R.id.Spinner01);

    // Set the Spinner to a known position
    mActivity.setSpinnerPosition(TEST_STATE_DESTROY_POSITION);

    // Stop the activity - The onDestroy() method should save the state of the Spinner
    mActivity.finish();

    // Re-start the Activity - the onResume() method should restore the state of the Spinner
    mActivity = getActivity();

    // Get the Spinner's current position
    int currentPosition = mActivity.getSpinnerPosition();

    // Assert that the current position is the same as the starting position
    assertEquals(TEST_STATE_DESTROY_POSITION, currentPosition);
The key method used here is getActivity(), which is a part of the instrumentation API. The Activity under test is not started until you call this method. You can set up the test fixture in advance, and then call this method to start the Activity.
Also, instrumentation can load both a test package and the application under test into the same process. Since the application components and their tests are in the same process, the tests can invoke methods in the components, and modify and examine fields in the components.

Test case classes

Android provides several test case classes that extend TestCase and Assert with Android-specific setup, teardown, and helper methods.

AndroidTestCase

A useful general test case class, especially if you are just starting out with Android testing, is AndroidTestCase. It extends both TestCase and Assert. It provides the JUnit-standard setUp() and tearDown() methods, as well as all of JUnit's Assert methods. In addition, it provides methods for testing permissions, and a method that guards against memory leaks by clearing out certain class references.

Component-specific test cases

A key feature of the Android testing framework is its component-specific test case classes. These address specific component testing needs with methods for fixture setup and teardown and component lifecycle control. They also provide methods for setting up mock objects. These classes are described in the component-specific testing topics:
Android does not provide a separate test case class for BroadcastReceiver. Instead, test a BroadcastReceiver by testing the component that sends it Intent objects, to verify that the BroadcastReceiver responds correctly.

ApplicationTestCase

You use the ApplicationTestCase test case class to test the setup and teardown of Application objects. These objects maintain the global state of information that applies to all the components in an application package. The test case can be useful in verifying that the <application> element in the manifest file is correctly set up. Note, however, that this test case does not allow you to control testing of the components within your application package.

InstrumentationTestCase

If you want to use instrumentation methods in a test case class, you must use InstrumentationTestCase or one of its subclasses. The Activity test cases extend this base class with other functionality that assists in Activity testing.

Assertion classes

Because Android test case classes extend JUnit, you can use assertion methods to display the results of tests. An assertion method compares an actual value returned by a test to an expected value, and throws an AssertionException if the comparison test fails. Using assertions is more convenient than doing logging, and provides better test performance.
Besides the JUnit Assert class methods, the testing API also provides the MoreAsserts and ViewAsserts classes:

Mock object classes

To facilitate dependency injection in testing, Android provides classes that create mock system objects such as Context objects, ContentProvider objects, ContentResolver objects, and Service objects. Some test cases also provide mock Intent objects. You use these mocks both to isolate tests from the rest of the system and to facilitate dependency injection for testing. These classes are found in the Java packages android.test and android.test.mock.
Mock objects isolate tests from a running system by stubbing out or overriding normal operations. For example, a MockContentResolver replaces the normal resolver framework with its own local framework, which is isolated from the rest of the system. MockContentResolver also stubs out the notifyChange(Uri, ContentObserver, boolean) method so that observer objects outside the test environment are not accidentally triggered.
Mock object classes also facilitate dependency injection by providing a subclass of the normal object that is non-functional except for overrides you define. For example, the MockResources object provides a subclass of Resources in which all the methods throw Exceptions when called. To use it, you override only those methods that must provide information.
These are the mock object classes available in Android:

Simple mock object classes

MockApplication, MockContext, MockContentProvider, MockCursor, MockDialogInterface, MockPackageManager, and MockResources provide a simple and useful mock strategy. They are stubbed-out versions of the corresponding system object class, and all of their methods throw an UnsupportedOperationException exception if called. To use them, you override the methods you need in order to provide mock dependencies.
Note: MockContentProvider and MockCursor are new as of API level 8.

Resolver mock objects

MockContentResolver provides isolated testing of content providers by masking out the normal system resolver framework. Instead of looking in the system to find a content provider given an authority string, MockContentResolver uses its own internal table. You must explicitly add providers to this table using addProvider(String, ContentProvider).
With this feature, you can associate a mock content provider with an authority. You can create an instance of a real provider but use test data in it. You can even set the provider for an authority to null. In effect, a MockContentResolver object isolates your test from providers that contain real data. You can control the function of the provider, and you can prevent your test from affecting real data.

Contexts for testing

Android provides two Context classes that are useful for testing:
  • IsolatedContext provides an isolated Context, File, directory, and database operations that use this Context take place in a test area. Though its functionality is limited, this Context has enough stub code to respond to system calls. This class allows you to test an application's data operations without affecting real data that may be present on the device.
  • RenamingDelegatingContext provides a Context in which most functions are handled by an existing Context, but file and database operations are handled by a IsolatedContext. The isolated part uses a test directory and creates special file and directory names. You can control the naming yourself, or let the constructor determine it automatically. This object provides a quick way to set up an isolated area for data operations, while keeping normal functionality for all other Context operations.

Running Tests

Test cases are run by a test runner class that loads the test case class, set ups, runs, and tears down each test. An Android test runner must also be instrumented, so that the system utility for starting applications can control how the test package loads test cases and the application under test. You tell the Android platform which instrumented test runner to use by setting a value in the test package's manifest file.
InstrumentationTestRunner is the primary Android test runner class. It extends the JUnit test runner framework and is also instrumented. It can run any of the test case classes provided by Android and supports all possible types of testing.
You specify InstrumentationTestRunner or a subclass in your test package's manifest file, in the instrumentation element. Also, InstrumentationTestRunner code resides in the shared library android.test.runner, which is not normally linked to Android code. To include it, you must specify it in a uses-library element. You do not have to set up these elements yourself. Both Eclipse with ADT and the android command-line tool construct them automatically and add them to your test package's manifest file.
Note: If you use a test runner other than InstrumentationTestRunner, you must change the <instrumentation> element to point to the class you want to use.
To run InstrumentationTestRunner, you use internal system classes called by Android tools. When you run a test in Eclipse with ADT, the classes are called automatically. When you run a test from the command line, you run these classes with Android Debug Bridge (adb).
The system classes load and start the test package, kill any processes that are running an instance of the application under test, and then load a new instance of the application under test. They then pass control to InstrumentationTestRunner, which runs each test case class in the test package. You can also control which test cases and methods are run using settings in Eclipse with ADT, or using flags with the command-line tools.
Neither the system classes nor InstrumentationTestRunner run the application under test. Instead, the test case does this directly. It either calls methods in the application under test, or it calls its own methods that trigger lifecycle events in the application under test. The application is under the complete control of the test case, which allows it to set up the test environment (the test fixture) before running a test. This is demonstrated in the previous code snippet that tests an Activity that displays a Spinner widget.
To learn more about running tests, please read the topics Testing in Eclipse, with ADT or Testing in Other IDes.

Seeing Test Results

The Android testing framework returns test results back to the tool that started the test. If you run a test in Eclipse with ADT, the results are displayed in a new JUnit view pane. If you run a test from the command line, the results are displayed in STDOUT. In both cases, you see a test summary that displays the name of each test case and method that was run. You also see all the assertion failures that occurred. These include pointers to the line in the test code where the failure occurred. Assertion failures also list the expected value and actual value.
The test results have a format that is specific to the IDE that you are using. The test results format for Eclipse with ADT is described in Testing in Eclipse, with ADT. The test results format for tests run from the command line is described in Testing in Other IDEs.

monkey and monkeyrunner

The SDK provides two tools for functional-level application testing:
  • The UI/Application Exerciser Monkey, usually called "monkey", is a command-line tool that sends pseudo-random streams of keystrokes, touches, and gestures to a device. You run it with the Android Debug Bridge (adb) tool. You use it to stress-test your application and report back errors that are encountered. You can repeat a stream of events by running the tool each time with the same random number seed.
  • The monkeyrunner tool is an API and execution environment for test programs written in Python. The API includes functions for connecting to a device, installing and uninstalling packages, taking screenshots, comparing two images, and running a test package against an application. Using the API, you can write a wide range of large, powerful, and complex tests. You run programs that use the API with the monkeyrunner command-line tool.

Working With Package names

In the test environment, you work with both Android application package names and Java package identifiers. Both use the same naming format, but they represent substantially different entities. You need to know the difference to set up your tests correctly.
An Android package name is a unique system name for a .apk file, set by the "android:package" attribute of the <manifest> element in the package's manifest. The Android package name of your test package must be different from the Android package name of the application under test. By default, Android tools create the test package name by appending ".test" to the package name of the application under test.
The test package also uses an Android package name to target the application package it tests. This is set in the "android:targetPackage" attribute of the <instrumentation> element in the test package's manifest.
A Java package identifier applies to a source file. This package name reflects the directory path of the source file. It also affects the visibility of classes and members to each other.
Android tools that create test projects set up an Android test package name for you. From your input, the tools set up the test package name and the target package name for the application under test. For these tools to work, the application project must already exist.
By default, these tools set the Java package identifier for the test class to be the same as the Android package identifier. You may want to change this if you want to expose members in the application under test by giving them package visibility. If you do this, change only the Java package identifier, not the Android package names, and change only the test case source files. Do not change the Java package name of the generated R.java class in your test package, because it will then conflict with the R.java class in the application under test. Do not change the Android package name of your test package to be the same as the application it tests, because then their names will no longer be unique in the system.

What to Test

The topic What To Test describes the key functionality you should test in an Android application, and the key situations that might affect that functionality.
Most unit testing is specific to the Android component you are testing. The topics Activity Testing, Content Provider Testing, and Service Testing each have a section entitled "What To Test" that lists possible testing areas.
When possible, you should run these tests on an actual device. If this is not possible, you can use the Android Emulator with Android Virtual Devices configured for the hardware, screens, and versions you want to test.

Next Steps

To learn how to set up and run tests in Eclipse, please refer to Testing in Eclipse, with ADT. If you're not working in Eclipse, refer to Testing in Other IDEs.
If you want a step-by-step introduction to Android testing, try one of the testing tutorials or sample test packages:
  • The Hello, Testing tutorial introduces basic testing concepts and procedures in the context of the Hello, World application.
  • The Activity Testing tutorial is an excellent follow-up to the Hello, Testing tutorial. It guides you through a more complex testing scenario that you develop against a more realistic application.

Thursday, 14 June 2012

Getting Started with Mobile Web Development Using HTML5, jQuery Mobile and ASP.NET MVC 4

Getting Started with Mobile Web Development Using HTML5, jQuery Mobile and ASP.NET MVC 4

As you probably know, software development is shifting toward the mobile space. Mobile devices have become ubiquitous in the consumer landscape, and the demand for mobile software is increasing. Businesses want to carve their niche in the mobile marketplace with native mobile applications and mobile Web sites – the two types of applications available for mobile devices.
Creating native applications with native code means developing separate software that targets each platform of interest (e.g., one XAML app for Windows Phone 7 and one Objective-C app for iOS). Maintaining and supporting multiple code bases is challenging, in part because most software developer teams don’t have the resources to do so, especially across a large number of customers. Independent contractors often have to focus on only one or two platforms, limiting their prospects.
By creating mobile Web applications that take advantage of HTML5, jQuery Mobile and ASP.NET MVC 4, you can effectively target multiple platforms with a single code base. Any browser, including mobile Web browsers, can render the HTML pages created with these technologies. You’ll still need to consider dealing with different browsers, but overall, Web applications are much easier to develop and maintain than multiple native applications in different languages.

Enter jQuery Mobile

jQuery Mobile is a lightweight library, built with the popular jQuery library, that can be used with any Web platform. It leverages semantic markup in HTML5, HTML5 data-* attributes and CSS to manage page elements such as page layout and navigation, allowing you to support the widest array of devices with a smaller set of code. jQuery mobile supports Windows Phone 7, iOS, Android, Blackberry, Symbian and many more devices. Click here to see a comprehensive list of supported platforms.
JQuery Mobile is also part of the MVC 4 Mobile Web Application template in Visual Studio 2010. With the MVC 4 template, you can develop mobile Web sites with a consistent look and feel by using prebuilt themes, navigation and widgets. Additional features include built-in accessibility, touch and an API, so you can easily customize your applications.
Before the jQuery .ready function loads, jQuery Mobile is already making changes to the Document Object Model (DOM) that will enhance DOM elements at run time. You can direct which elements to enhance by using a set of predefined HTML5 data-* attributes. The library locates the elements with the data-* attributes and modifies them with mobile-friendly CSS and markup. Using data-* attributes with the W3C HTML5 Web standards produces Web pages that work in any browser.

Creating an MVC 4 Mobile Web Project with jQuery Mobile

After visiting the ASP.NET MVC 4 Web site to download and install MVC 4 for Visual Studio 2010, you can use the new ASP.NET MVC 4 Web Application project type. To start a new project, select New from the File menu, and then begin working from the New Project dialog box. The MVC 4 project types allow you to target a Mobile Application in addition to the currently available MVC templates. As the name indicates, the Mobile Application template contains the necessary jQuery and jQuery Mobile scripts as well as other necessary markup, such as semantic elements and the data-* attributes.
After creating the new project, you can immediately examine the modifications the jQuery Mobile library made by taking the following steps:
  1. Launch a Web page from within Visual Studio (F5/Ctrl + F5).
  2. Open the browser’s developer tools to expose the runtime source (F12 in most browsers).
  3. Use the View Source command to expose the originally rendered source.
You can then compare the DOM at run time, as shown in Figure 1.

Comparing jQuery Mobile DOM modifications

Figure 1 Comparing jQuery Mobile DOM modifications
As you can see, the runtime DOM contains many more attributes than the original markup in the <body> and <div> elements.
The image in Figure 1 uses Internet Explorer 9 on a desktop. You’ll want to test the page with something closer to an actual mobile device. I recommend using the Windows Phone Emulator. You can download and install the Windows Phone SDK 7.1 to get all the tools you need to create mobile applications targeting Windows Phone 7.
To start the Windows Phone Emulator, press the Windows key and type “Emulator” at the Windows Start Menu prompt. Choose the Windows Phone Emulator program from the results list, and run it separately from Visual Studio. Once in the emulator, you can enter the URL http://localhost:port into the address bar and browse the page. If you want to type using your physical keyboard rather than the on-screen keyboard, press the Page Up key after clicking in the browser’s address bar in the emulator window.
The results should look similar to the image in Figure 2.

A mobile Web page in the Windows Phone Emulator

Figure 2 A mobile Web page in the Windows Phone Emulator
Common layouts, sets of behaviors and navigation are also built-in components of jQuery Mobile, and you can immediately test them by navigating to the About or Contact pages in the emulator. Just click on the links as you would in a regular Web page, and the results should be similar to those in Figure 3.

Consistent layout and navigation by default in jQuery Mobile


Figure 3  Consistent layout and navigation by default in jQuery Mobile
Although jQuery Mobile and HTML5 work seamlessly to create a small code base that produces consistent output, they are companion technologies alongside ASP.NET MVC, so you also need to dig into the server-side code.

Investigating MVC 4 Mobile Web Projects

The MVC 4 Mobile Web application template contains all the files you need to start creating mobile Web sites. Several useful scripts (not covered in this article) are located in the \Scripts folder, including:
  • Other jQuery libraries; jQuery UI, jQuery core
  • Modernizr for feature detection
  • Knockout JS as an MVVM library
The MVC Mobile Web template also includes the models, views and controllers for managing user accounts with ASP.NET Forms Authentication, along with default configuration, error and layout pages.
Models and controllers in mobile Web applications don’t differ much from models or controllers in non-mobile MVC projects. One difference, however, is that the layout page has additional script references to the necessary jQuery Mobile libraries.
You can inspect the layout page by referring to the code sample in Figure 4 or by opening and investigating the _Layout.cshtml file in the \Views\Shared folder.

  1. <!DOCTYPE html> 
  2.  
  3. <html> 
  4.  
  5. <head> 
  6.  
  7.     <meta charset="utf-8" />
  8.  
  9.     <title>@ViewBag.Title</title> 
  10.  
  11.     <meta name="viewport" content="width=device-width" />
  12.  
  13.     <link rel="stylesheet" href="@Url.Content("~/Content/jquery.mobile-1.0b2.min.css")" />
  14.  
  15.     <link rel="stylesheet" href="@Url.Content("~/Content/Site.css")" />
  16.  
  17.     <script type="text/javascript" src="@Url.Content("~/Scripts/jquery-1.6.2.min.js")"></script>
  18.  
  19.     <!-- ... -->
  20.  
  21.     <script type="text/javascript" src="@Url.Content("~/Scripts/jquery.mobile-1.0b2.min.js")"></script>
  22.  
  23. </head>

Figure 4 An MVC Mobile–enabled layout header
Located further in the layout page is the contents of the <body> and main <div> tags. Figure 5 shows the data-* role attributes for the page, header and content <div> elements. Additionally, the data-theme=”b” attribute sets a theme from jQuery Mobile ThemeRoller.

  1. <body> 
  2.  
  3.     <div data-role="page" data-theme="b">
  4.  
  5.         <div data-role="header">
  6.  
  7.             @if (IsSectionDefined("Header")) {
  8.  
  9.                 @RenderSection("Header")
  10.  
  11.             } else {
  12.  
  13.                 <h1>@ViewBag.Title</h1>
  14.  
  15.                 @Html.Partial("_LogOnPartial")
  16.  
  17.             }
  18.  
  19.         </div>
  20.  
  21.  
  22.  
  23.         <div data-role="content">    
  24.  
  25.             @RenderBody()
  26.  
  27.         </div>
  28.  
  29.     </div>
  30.  
  31. </body>
  32.  
  33. </html>

Figure 5 An MVC Mobile–enabled layout page
The default layout page in MVC 4 is a single-page interface because only one <div> exists that has the data-role=”page” attribute. Multiple page interfaces require multiple sibling <div> elements with data-roles set to “page” along with unique ID attributes for each sibling <div>.
The data-* attributes in jQuery Mobile aren’t just for managing page layouts. They play an important role in everything jQuery Mobile does, especially navigation.

Navigation on Mobile Devices with jQuery Mobile and ASP.NET MVC

Creating navigational links in jQuery Mobile is easy—as in the previous examples, all you need are data-* attributes. Just add the data-role=”listview” to a <ul> element so jQuery Mobile can look for those attributes and enhance the DOM elements at run time.
Figure 6 shows mobile-friendly navigation with MVC Html Helpers that create the hyperlinks that link to controller actions. The <ul> tag surrounding the links uses data-* attributes to denote a listview and two list-dividers.

  1. <ul data-role="listview" data-inset="true">
  2.  
  3.     <li data-role="list-divider">Group 1</li>
  4.  
  5.     <li>@Html.ActionLink("Link1", "Link1", "Link1")</li>
  6.  
  7.     <li>@Html.ActionLink("Link2", "Link2", "Link2")</li>
  8.  
  9.     <li data-role="list-divider">Group 2</li>
  10.  
  11.     <li>@Html.ActionLink("Link3", "Link3", "Link3")</li>
  12.  
  13.     <li>@Html.ActionLink("Link4", "Link4", "Link4")</li>
  14.  
  15. </ul>

Figure 6 Navigation with data-role elements
The listview is a container for the navigation, and the list-divider renders as a horizontal bar to separate groups of links. Figure 7 illustrates the use of grouped links.

Groups of navigation links

Figure 7 Groups of navigation links
Without the mobile enhancements, the links render as standard <a> elements. The link at the top of the image in Figure 7 links to http://asp.net/mvc and is an example of a standard anchor rendered in a mobile device.
Outside of layout and navigation, jQuery Mobile exposes many attributes, and an API, for working with HTML forms, CSS themes and the like. It uses the same notations and syntax featured in the samples in this article.

Summary

jQuery Mobile is a light yet elegant library that takes full advantage of HTML5 and CSS so that you can have a smaller, more maintainable code base. In addition to these benefits, you can continue development with advanced mobile features found at the jQuery Mobile Resources page.

Friday, 8 June 2012

Meet the New Windows Azure (by ScottGu)


The information below has been taken from ScottGu's blog; however I found it so interesting I wanted to share it with my community.

Enjoy...

Meet the New Windows Azure

Today we are releasing a major set of improvements to Windows Azure.  Below is a short-summary of just a few of them:

New Admin Portal and Command Line Tools

Today’s release comes with a new Windows Azure portal that will enable you to manage all features and services offered on Windows Azure in a seamless, integrated way.  It is very fast and fluid, supports filtering and sorting (making it much easier to use for large deployments), works on all browsers, and offers a lot of great new features – including built-in VM, Web site, Storage, and Cloud Service monitoring support.
image
The new portal is built on top of a REST-based management API within Windows Azure – and everything you can do through the portal can also be programmed directly against this Web API.
We are also today releasing command-line tools (which like the portal call the REST Management APIs) to make it even easier to script and automate your administration tasks.  We are offering both a Powershell (for Windows) and Bash (for Mac and Linux) set of tools to download.  Like our SDKs, the code for these tools is hosted on GitHub under an Apache 2 license.

Virtual Machines

Windows Azure now supports the ability to deploy and run durable VMs in the cloud.  You can easily create these VMs using a new Image Gallery built-into the new Windows Azure Portal, or alternatively upload and run your own custom-built VHD images.
Virtual Machines are durable (meaning anything you install within them persists across reboots) and you can use any OS with them.  Our built-in image gallery includes both Windows Server images (including the new Windows Server 2012 RC) as well as Linux images (including Ubuntu, CentOS, and SUSE distributions).  Once you create a VM instance you can easily Terminal Server or SSH into it in order to configure and customize the VM however you want (and optionally capture your own image snapshot of it to use when creating new VM instances).  This provides you with the flexibility to run pretty much any workload within Windows Azure.
image
The new Windows Azure Portal provides a rich set of management features for Virtual Machines – including the ability to monitor and track resource utilization within them. 
image
Our new Virtual Machine support also enables the ability to easily attach multiple data-disks to VMs (which you can then mount and format as drives).  You can optionally enable geo-replication support on these – which will cause Windows Azure to continuously replicate your storage to a secondary data-center at least 400 miles away from your primary data-center as a backup.
image
We use the same VHD format that is supported with Windows virtualization today (and which we’ve released as an open spec), which enables you to easily migrate existing workloads you might already have virtualized into Windows Azure.  We also make it easy to download VHDs from Windows Azure, which also provides the flexibility to easily migrate cloud-based VM workloads to an on-premise environment.  All you need to do is download the VHD file and boot it up locally, no import/export steps required.

Web Sites

Windows Azure now supports the ability to quickly and easily deploy ASP.NET, Node.js and PHP web-sites to a highly scalable cloud environment that allows you to start small (and for free) and then scale up as your traffic grows.  You can create a new web site in Azure and have it ready to deploy to in under 10 seconds:
image
The new Windows Azure Portal provides built-in administration support for Web sites – including the ability to monitor and track resource utilization in real-time:
image
You can deploy to web-sites in seconds using FTP, Git, TFS and Web Deploy.  We are also releasing tooling updates today for both Visual Studio and Web Matrix that enable developers to seamlessly deploy ASP.NET applications to this new offering.  The VS and Web Matrix publishing support includes the ability to deploy SQL databases as part of web site deployment – as well as the ability to incrementally update database schema with a later deployment.
You can integrate web application publishing with source control by selecting the “Set up TFS publishing” or “Set up Git publishing” links on a web-site’s dashboard:
image
Doing do will enable integration with our new TFS online service (which enables a full TFS workflow – including elastic build and testing support), or create a Git repository that you can reference as a remote and push deployments to.  Once you push a deployment using TFS or Git, the deployments tab will keep track of the deployments you make, and enable you to select an older (or newer) deployment and quickly redeploy your site to that snapshot of the code.  This provides a very powerful DevOps workflow experience.
image
Windows Azure now allows you to deploy up to 10 web-sites into a free, shared/multi-tenant hosting environment (where a site you deploy will be one of multiple sites running on a shared set of server resources).  This provides an easy way to get started on projects at no cost.
image
You can then optionally upgrade your sites to run in a “reserved mode” that isolates them so that you are the only customer within a virtual machine:
image
And you can elastically scale the amount of resources your sites use – allowing you to increase your reserved instance capacity as your traffic scales:
image
Windows Azure automatically handles load balancing traffic across VM instances, and you get the same, super fast, deployment options (FTP, Git, TFS and Web Deploy) regardless of how many reserved instances you use.
With Windows Azure you pay for compute capacity on a per-hour basis – which allows you to scale up and down your resources to match only what you need.

Cloud Services and Distributed Caching

Windows Azure also supports the ability to build cloud services that support rich multi-tier architectures, automated application management, and scale to extremely large deployments.  Previously we referred to this capability as “hosted services” – with this week’s release we are now referring to this capability as “cloud services”.  We are also enabling a bunch of new features with them.
Distributed Cache
One of the really cool new features being enabled with cloud services is a new distributed cache capability that enables you to use and setup a low-latency, in-memory distributed cache within your applications.  This cache is isolated for use just by your applications, and does not have any throttling limits.
This cache can dynamically grow and shrink elastically (without you have to redeploy your app or make code changes), and supports the full richness of the AppFabric Cache Server API (including regions, high availability, notifications, local cache and more).  In addition to supporting the AppFabric Cache Server API, it also now supports the Memcached protocol – allowing you to point code written against Memcached at it (no code changes required).
The new distributed cache can be setup to run in one of two ways:
1) Using a co-located approach.  In this option you allocate a percentage of memory in your existing web and worker roles to be used by the cache, and then the cache joins the memory into one large distributed cache.  Any data put into the cache by one role instance can be accessed by other role instances in your application – regardless of whether the cached data is stored on it or another role.  The big benefit with the “co-located” option is that it is free (you don’t have to pay anything to enable it) and it allows you to use what might have been otherwise unused memory within your application VMs.
image
2) Alternatively, you can add “cache worker roles” to your cloud service that are used solely for caching.  These will also be joined into one large distributed cache ring that other roles within your application can access.  You can use these roles to cache 10s or 100s of GBs of data in-memory very effectively – and the cache can be elastically increased or decreased at runtime within your application:
image

New SDKs and Tooling Support

We have updated all of the Windows Azure SDKs with today’s release to include new features and capabilities.  Our SDKs are now available for multiple languages, and all of the source in them is published under an Apache 2 license and and maintained in GitHub repositories.
image
The .NET SDK for Azure has in particular seen a bunch of great improvements with today’s release, and now includes tooling support for both VS 2010 and the VS 2012 RC.
We are also now shipping Windows, Mac and Linux SDK downloads for languages that are offered on all of these systems – allowing developers to develop Windows Azure applications using any development operating system.
image

Much, Much More

The above is just a short list of some of the improvements that are shipping in either preview or final form today – there is a LOT more in today’s release.  These include new Virtual Private Networking capabilities, new Service Bus runtime and tooling support, the public preview of the new Azure Media Services, new Data Centers, significantly upgraded network and storage hardware, SQL Reporting Services, new Identity features, support within 40+ new countries and territories, and much, much more.
You can learn more about Windows Azure and sign-up to try it for free at http://windowsazure.com/
You can also watch a live keynote I’m giving at 1pm June 7th (later today) where I’ll walk through all of the new features.  We will be opening up the new features I discussed above for public usage a few hours after the keynote concludes.  We are really excited to see the great applications you build with them.