다음을 통해 공유


Introducing Windows 8 for Android Developers - Part 2

Part 1 covered a few fundamental aspects of Android and Windows 8 development from the perspective of applications that are self-contained. In part 2 we will focus on the application integration with external services through the platform’s built-in networking capabilities.

Internet Integration

No application runs in its own silo and hence remote data and storage API is a fundamental requirement of any mobile application platform. Both Android and Windows 8 offers multitude of networking options with varying degrees of abstraction levels. We will break this down into two fundamental categories: networking capabilities for internet content and web service capabilities for remote data access.

Remote Content access through Networking

HTTP is the most widely accepted protocol for accessing content from remote networking locations like internet hosted web sites. Both Android and Windows offer HTTP client API for content download and upload functionality.

Android: HTTP Client API

Developers can program to DefaultHttpClient or AndroidHttpClient which are the extensions of Apache HttpClient implementation. HttpUrlConnection is lightweight HTTP client suitable for most Android applications. Per the Android’s HTTP Clients blog, HttpUrlConnection seems to be the recommended way of programming HTTP interaction in an application. The following code sample shows the usage of various Android HTTP clients:

try {

  HttpClient httpClient = new DefaultHttpClient();

  HttpGet httpGet = new HttpGet("https://www.bing.com/");

  HttpResponse httpResp = httpClient.execute(httpGet);

  HttpEntity bingPage = httpResp.getEntity();

  if (bingPage != null) {

    //read the content using bingPage.getEntity();

  }

}

catch (Exception e) {//do something with the exception}

AndroidHttpClient can be used by replacing the “new DefaultHttpClient()” with “AndroidHttpClient.newInatance(“test-app”)” in the above snippet. Please note that AndroidHttpClient can’t be used from the UI thread; so, make sure to execute the code on a background thread.

HttpUrlConnection is the light weight HTTP client that is recommended in the latest versions of the Android API. Here is the code snippet for HttpUrlConnection usage:

try{

  URL url = new URL("https://www.bing.com");

  HttpURLConnection huc = (HttpURLConnection)url.openConnection();

  InputStream inStream = new BufferedInputStream(huc.getInputStream());

  //read the stream and process the content

}

catch (Exception e) {

  //process exception

}

Windows 8: HTTP Client API

Windows Store applications written for .NET can use .NET framework’s network classes from System.Net and System.Net.Http namepsaces. The class HttpWebRequest is present in all the .NET versions starting from version 1.1. HttpClient is the modern version of the HTTP client that started in .NET 4.5 and hence supports pure asynchronous programming. So, it is recommended to use HttpClient in Windows Store applications.

Here is the code snippet for HttpClient for retrieving Customer objects from a service:

 class Customer

 {

   public Name {get; set;}

   public City {get; set;}

 }

    

 //snippet for retrieving customer objects

 using (var httpClient = new HttpClient()) {

   var resp = await httpClient.GetAsync(new Uri(ApiRoot));

   using (var stream = await resp.Content.ReadAsStreamAsync()){

   var djs = new DataContractJsonSerializer(typeof (List<Customer>));

   var customerList = new ObservableCollection<Customer>((IEnumerable<Customer>)

                     djs.ReadObject(stream));

   }

 }

The customerList so retrieved can be bound to the UI list widgets directly. Given that the .NET framework requires minimal code in translating HTTP responses to business objects, developers are saved from writing lots of parsing code. Also, note the “await” keyword compiler uses to generate the necessary async boilerplate code for scheduling the work on a background thread while at the same time preserving the natural code flow.

Remote Data Access through Web Services

Web service access for application data storage on remote services is a common request for modern applications. Android and Windows 8 platforms have API for accessing web services. There are two types of web services REST and SOAP. REST uses HTTP methods like POST, GET, PUT and DELETE while SOAP web services use a highly descriptive SOAP wire format for HTTP message exchange.

Android: Web Service API

REST web service calls from Android can be made through DefaultHttpClient or HttpURLConnection objects which were discussed previously. A code snippet calling REST web service using DefaultHttpClient is shown below:

 //Calling REST web service from Android

 String restRequestURL ="https://www.contoso.com?produttype=2";

 HttpClient httpClient = new DefaultHttpClient();

 HttpGet httpGetRequest = new HttpGet(restRequestURL);

 ResponseHandler<String> stringHandler = new BasicResponseHandler();

 String productList;

 try {

    productListJson = httpClient.execute(httpGetRequest,stringHandler);

    JSONObject productListJObject = JSONObject(productListJson);

    //leverage JSONObject in further processing

 }

 catch (Exception e) {}

JSONObject is not a strongly typed domain object which will require the object state access through property name literals as shown below:

 

 productJObject = productListJObject.getJSONObject(“93495”);

 productJOBject.getString(“description”);

Google’s Gson and similar open source libraries ,even through they are not part of the Android SDK, they can help with the conversion of JSON strings to strongly typed Java objects.

JAX-WS is a moniker for a collection of Java classes that will help the creation of WS-* compliant SOAP web service on the server as well as bindings on the client. Open source packages like KSOAP2 for Android can be used for calling SOAP based web services from Android applications.

Windows 8: Web Service API

REST web services for Windows 8 applications can be implemented on the server using ASP.NET Web API and WCF (Windows Communications Foundation). Out of these technologies, ASP.NET Web API is modern and is recommended compared to WCF for REST web services. ASP.NET Web API only supports HTTP protocol while WCF supports TCP as well as HTTP and can be used for both REST as well as SOAP based web services.

Here is the code snippet for creating and calling ASP.NET Web API based web services on Windows platform:

//REST Web Services with ASP.NET Web API

//Server code

public class CustomerController : ApiController

{

  // GET /api/person

  public IEnumerable<Customer> Get()

  {

   return new List<Customer>(){

     new Customer {Name="John", Company="Seattle"},

     new Customer {Name="Jim", Company="New York"}};

  }

}

//Windows 8 Client code

 private const string ApiRoot = "https://localhost:18088/api/customer";

 public async void Load() {

  using (var httpClient = new HttpClient()) {

    var resp = await httpClient.GetAsync(new Uri(ApiRoot));

    using (var stream = await resp.Content.ReadAsStreamAsync()){

      var djs = new DataContractJsonSerializer(typeof (List<Customer>));

      var Customers = new ObservableCollection<Customer>((IEnumerable<Customer>)

                     djs.ReadObject(stream));

      //Customers is a strongly typed C# object that can be data bound to UI controls

    }

  }

 }

Converting HTTP payload into strongly typed domain objects (e.g. Customer in the above snippet) is natively supported in the WinRT platform.

.NET WCF is equivalent to JAX-WS on the Java platform for WS-* compliant SOAP web services. The latest version of WCF also supports REST web services and can be directly called from Windows 8 applications for certain WCF bindings. These bindings are: BasicHttpBinding, NetTcpBinding, NetHttpBinding and CustomBinding. WCF uses the concept of binding to configure messaging behavior, wire format and wire protocols declaratively.

Here is a code snippet for creating WCF services on the server and calling them from Windows 8 client:

//Server Code

 [DataContract]

 public class Customer

 {

   [DataMember]

   public string Name;

   [DataMember]

   public string Address;

 }

[ServiceContract]

 public class Customers {

  [OperationContract]

  public List<Customer> GetAllCustomers()

  {

     return new List<Customer>()

      { new Customer { Name = "john", Address="seattle" },

        new Customer { Name = "ken", Address = "Chicago" }};

  }

}

//Windows 8 Client Code

 async void GetCustomers()

 {

    //Adding a service reference to the project will generate proxy automatically

    CustomerProxy.CustomersClient client = new CustomerProxy.CustomersClient();

    ObservableCollection<CustomerProxy.Customer> customers =

                                              await client.GetAllCustomersAsync();

    //customers object collection can be data bound to a UI grid directly

 }

Visual Studio 2012 helps with the strongly typed proxy generation from a WSDL endpoint or a WSDL file. Visual Studio only generates asynchronous proxies to be used in Windows Store applications which requires the usage of the “await” keyword in front of the async methods as shown by the call to GetAllCustomersAsync() in the above snippet. The output is a strongly typed Customer object collection which can directly be databound to a UI control that can display a list of customers to the end user.

On the server, WCF uses DataContract annotation for payload and ServiceContract for endpoint generation. All the messaging and serialization logic is generated by Visual Studio tools and hence no boiler plate coding is required in parsing and calling the WCF web services.

Cloud Service Integration

In a highly distributed and interconnected application ecosystem, mobile platforms need to provide their own respective cloud services but also should be able to interoperate with each other’s and 3rd party cloud services. Application’s typical cloud integration requirements include security, state management, push notifications, social networking integration and other domain specific application services. Domain specific services are out of scope for this article and hence will not be discussed here.

Authentication
Android Authentication with OAuth Providers

Android applications can integrate with cloud based OAuth providers for discretionary sharing of social graph and implementing application security features. Figure 8 shows the popular OAuth providers which Android applications can leverage for application log in as well as information sharing. There may be other OAuth providers not listed here that may work with Android applications.

Figure 10 - Android Interoperability with OAuth Providers

Figure 10: Android Interoperability with OAuth Providers

The picture only shows a handful of OAuth providers and it is possible that Android will work with any OAuth provider through custom code or with provider specific client bindings. Adding a new OAuth provider to the application’s authenticator list includes working with the respective SDK and integrating that into the Android Activity workflow.

Windows 8 Authentication with OAuth Providers

Windows Store applications in Windows 8 supports authenticating against OAuth providers including the popular providers shown in Figure 9. Windows 8 supports OAuth authentication at a platform level though a single encapsulation in WebAuthenticationBroker.

Figure 11 - Windows 8 Interoperability with OAuth Providers

Figure 11: Windows 8 Interoperability with OAuth Providers

Authenticating with Facebook as an example, the following snippet shows the C# code for requesting an authentication token from Facebook OAuth service.

string clientID = "App_API_ID";

 string oauthDialogUrl = @"https://www.facebook.com/dialog/oauth";

 string returnUrl = @"https://www.facebook.com/connect/login_success.html";

 string error = string.Empty;

 try

 {

   String facebookURL =

           string.Format(@"{0}/?client_id={1}&redirect_uri={2}&response_type=token",

                        oauthDialogUrl, clientID, Uri.EscapeDataString(returnUrl));

   Uri oauthDialogUri = new Uri(facebookURL);

   Uri returnUri = new Uri(returnUrl);

 

 

   WebAuthenticationResult WebAuthenticationResult =

       await WebAuthenticationBroker.AuthenticateAsync(WebAuthenticationOptions.None,

                                                oauthDialogUri,

                                                returnUri);

   if (WebAuthenticationResult.ResponseStatus == WebAuthenticationStatus.Success)

   {

     string authResponse = WebAuthenticationResult.ResponseData.ToString();

   }

  else

   {

       //handle the error

   }

   catch (Exception e)

   {

       //handle the exception

   }

 

This uses the OAuth dialog URI as required by Facebook in the format:

https://www.facebook.com/dialog/oauth?client_id=YOUR_APP_ID

  &redirect_uri=https://www.facebook.com/connect/login_success.html

   &response_type=token

Since Facebook expects a web browser to issue token requests, WebAuthenticationBroker hosts the dialog inside a WebView control that renders web content with capabilities equivalent to IE 10. The token response from Facebook will be available through WebAuthenticationResult.ResponseData in the following format:

https://www.facebook.com/connect/login_success.html#access_token=YOUR_TOKEN&expires_in=4094

The token can be extracted and reused as a proof of authentication as well as for subsequent social graph requests either on the client side or from the application server.

The WebAuthenticationBroker requires custom code for working with the likes of Twitter while it works out of the box for Facebook.

State Management

Reading and modifying application data on the server is a common requirement if the data needs to be shared with other devices/users or requires some kind of a server side processing. Examples of such requirements include the game leaderboard, ecommerce, news reading, microblogging, social networking and numerous other server interactions. If needed an applications can host its own application specific services in the cloud through the techniques discussed in the Internet Integration section previously.

Custom State Management

Both Android and Windows 8 can use the respective HTTP client capabilities (e.g. Android: HttpClient and HttpUrlConnection, Windows 8: HttpClient, WCF proxies) to connect with custom web services hosted on the cloud or one’s own infrastructure, if available. The developer can use any of the server side technologies like ASP.NET Web API, Java, JAX-WS, PHP, Ruby, etc. for building hosted web services both on Windows and Linux platforms.

Various open source frame works and .NET accelerate the creation of web services targeting Android and Windows 8 platforms easy through the preservation of server side object model on the client for state and public behavior. However, developers still have to find infrastructure to host the service, manage the infrastructure and watch the service for availability and scalability.

State Management through Pre-Built Cloud Services

Both Android and Windows 8 are backend agnostic as both can consume industry standard web services. To accelerate the development and deployment of web services on the server, several service providers offer pre-built services for state management and device notifications. Microsoft also offers one such service called Windows Azure Mobile Services (WAMS) for saving application data through simple API calls. WAMS is hosted on Windows Azure (Microsoft cloud application platform) and simplifies server-side web service creation, hosting and operations through a managed services infrastructure.

The developer prepares the service through configuration and plugs in Javascript code for typical server side CRUD (Create/Read/Update/Delete) activities on business data entities. WAMS which is in a public preview mode as of this writing can be used by both Windows 8 and Android clients for saving data on the server.

For getting started on WAMS, see the tutorial: https://www.windowsazure.com/en-us/develop/mobile/tutorials/get-started/.

Following is a WAMS pseudo code snippet for Android applications:

//Server – a one-time setup with no coding

 1. Create a Mobile Service on windowsazure.com through UI.

 2. Create the Customer table; no column information necessary

 

//WAMS code for inserting a record from Android client

public class Customer {

  @com.google.gson.annotations.SerializedName("name")

  Private String Name;

  @com.google.gson.annotations.SerializedName("city")

  Private String City;

}

public class Acvitiy1 extends Activity {

  //other code

  private void testWAMS() {

   MobileServiceClient mobileClient = new MobileServiceClient(WAMS_URL, this);

   MobileServiceTable<Customer> customerTable = mobileClient.getTable(Customer.class);

 

   //insert the customer

   Customer customer = new Customer("John","Seattle");

   customerTable.Insert(customer, callback);

 

   //update the customer

   customer.setCity("Houston");

   customerTable.Update(customer,callback);

 

   //Get a list of customers

   customerTable.execute(callback);

 }

  //other code

}

Here is the similar C# pseudo code for Windows 8:

public class Customer {

  public string Name {get; set;}

  public string City {get; set;}

}

 

//WAMS code for inserting a record from Windows 8 client

public partial class MainPage: Page

{

   //other code

   private testWAMS()

   {

   MobileServicesClient msc = new MobileServicesClient(WAMS_URL);

     IMobileServiceTable<Customer> customerTable =

            App.MobileService.GetTable<Customer>();

 

     //insert the customer

     Customer customer = new Customer{Name="John",City="Seattle"};

     await customerTable.InsertAsync(customer);

 

     //update the customer

     customer.City = "Houston";

   await customerTable.UpdateAsync(customer);

     //Retrieve the list of customers that can be data bound to a UI control

     MobileServiceCollectionView<Customer> customers =

                                        customerTable.ToCollectionView();

   }

   // other code

}

With Windows Azure Mobile Services the developer can implement CRUD on a schema-less table in a matter of minutes targeting both Windows 8 and Android platforms. The scalability and availability management of the service instance is taken care of by the Windows Azure application hosting platform. WAMS is a highly interoperable service with standards compliant HTTP request/response formats; client bindings for Windows Phone 8, Windows 8, Android and iOS are available to download from https://www.windowsazure.com/en-us/develop/mobile/.

Push Notification

Push notification is one of the fundamental requirement of a modern mobile operating system that will help with the proactive notification of the devices with application state changes on the server. Examples of the state changes may include news updates, social network updates, new email messages in the mailbox and weather alerts. Both Android and Windows 8 support delivery of push notifications through a cloud hosted infrastructure which is discussed below:

Android: Google Cloud Messaging (GCM)

The process flow for GCM is shown in Figure 10. GCM requires a Google account through which the application obtains a Project Number and API key. The application registers for notifications by sending a com.google.android.c2dm.intent.REGISTER intent along with the project number obtained by logging into the Google API Console. GCM broadcasts com.google.android.c2dm.intent.REGISTRATION intent to the device which will include the Registration ID. Typically the application will forward the Registration ID to the server which will record it in its database. The server will compose the notification message and contacts GCM by supplying the registration ID and the API key along with the message. The GCM service will store and forward the message to the devices.

Figure 12 - GCM Push Notification Flow

Figure 12: Google Cloud Messaging (GCM) Push Notification Flow

Windows 8: Windows Notification Service (WNS)

Windows Notification Service is the equivalent of GCM for Windows 8; WNS implements similar process for device registration and sending notifications. The GCM Registration ID equivalent on WNS is the Channel URI which is used by the server (in this case Windows Azure Mobile Services) along with the API key when contacting WNS with the notification message. Figure 11 uses Windows Azure Mobile Services (WAMS) as it makes implementing push notifications a lot easier and as previously described offers a completely managed service from the availability and scalability perspective.

Figure 13 - WNS Push Notification Flow

Figure 13: Windows Notification Service (WNS) Push Notification Flow

WAMS can be replaced with any custom web services infrastructure of the developer’s choice. Following code snippets show the work involved in implementing the registration on the client sending notifications with WAMS on the server:

//Client code: Channel Registration pseudo code

public class Channel

{

  public int? Id {get;set;}

  public string Uri {get;set;}

}

sealed partial class App:Application {

  protected override void OnLaunched(LaunchActivatedEventArgs args){

      ... ... ...

  //get the push channel URI using the info from the app manifest

  var channel = await PushNotificationChannelManager.

                     

  CreatePushNotificationChannelForApplicationAsync();

  Channel channelRow = new Channel(){Uri = channel.Uri;}

  await MobileService.GetTable<Channel>.InsertAsync(channelRow);

  //save channelRow.Id returned by Mobile Services for future use

     ... ... ...

 }

}

In the above code, when the application is launched a channel URI is acquired and sent to the server to be saved into a Channel table. Prior to the execution of the code it requires the schema-less Channel table to be crated on WAMS. When the InsertAsync() is called with channel object as the payload WAMS will automatically create the column definitions and insert the row in the Channel table. Subsequently WAMS will use this channel URI and the API key to send notifications through WNS.

//WAMS Server code: Javascript code on the serer

//service authentication with LiveConnect and channel

//retrieval from the storage is removed for brevity

function sendNotifications(message, channel){

  push.wns.sendToastText04(channel.Uri, {

     text1:item.text, text2: “value1", text3: “value2"}, {

  success: function(response){

        console.log(response);

  }, error: function(err){ console.error(err); } });

}

WAMS implements a Javascript programming model on the server and provides default handlers (default handler code merely executes request.execute() method) INSERT, UPDATE, DELETE and READ requests in Javascript. If required, developers can replace the default handlers with custom Javacript code as shown in the snippet below for sending push notifications:

//WAMS - default insert handler is replaced for push notifications

function insert(item, user, request) {

  request.execute({

  success: function() {

     // Write to the response and then send the notification in the background

     request.respond();

     push.wns.sendToastText04(item.channel, {

         text1: item.text

        }, {

          success: function(pushResponse) {

              console.log("Sent push:", pushResponse);

           }

        });

     }

  });

}

As mentioned previously Windows Azure Mobile Services can be used for state management as well as for push notifications for the following major mobile platforms: Android,iOS, Windows Phone 8 and Windows 8.

Conclusion

Both Android and Windows 8 platforms offer similar fundamental capabilities, development tools and SDKs to accomplish the necessary programming tasks for publishing the applications to the respective stores. These developer tasks include, screen design, code processing logic, debugging, saving data to the local and remote storage and push notifications. Given the similarities outlined in this article, Android developers will feel right at home with Windows 8 development. Information for getting started on Windows 8 development can be obtained from https://dev.windows.com.

Technorati Tags: Android,Windows8,Windows Store,Windows,Azure Mobile Services

Comments

  • Anonymous
    April 18, 2013
    I love Microsoft technologies and hop that it could beat the Android!