Tuesday, March 30, 2010

How To Take Android Screenshots on a Mac

If you have ever wondered how to take screenshots for applications running on an Android phone, you can do it for free if you have Java on your machine and have downloaded the Android SDK.

  1. Download the Android SDK
  2. On your Android phone, select Settings ->Applications -> Development
  3. Select Enable USB Debugging by placing a check box next to it
  4. Connect your Android device via USB to your Mac
  5. Run android-sdk-mac_86/tools/ddms (Dalvik Debug Monitor) (Note: it may be easier to add the tools directory in your path)
  6. Select the device in the Dalvik Debug Monitor as illustrated above
  7. Type Control + S or go to Dalvik Debug Monitor --> Device --> Screen Capture
  8. Voila!  
If you found this article useful, please retweet it.  Feel free to send me any comments.

Thursday, January 14, 2010

Web Runtime (WRT) Tools Open Source Release for Symbian Platform

This week, we are making available a preliminary version of the Web Runtime (WRT)  Tools Package under an EPL license.  As mentioned in my earlier posting on Web 2.0 Apps on Symbian, there are several million web application developers.  In fact, according to Gartner, by 2013, mobile phones will overtake PCs as the most common Web access device worldwide.

According to Gartner's PC installed base forecast, the total number of PCs in use will reach 1.78 billion units in 2013. By 2013, the combined installed base of smartphones and browser-equipped enhanced phones will exceed 1.82 billion units and will be greater than the installed base for PCs thereafter.

As the proliferation of mobile devices continues to grow at an astounding pace, there is an ever-increasing need for better mobile Web development tools. We are open sourcing the Web Runtime (WRT) Tools to provide an open eco-system to foster greater collaboration within the Symbian Tools  Developers community.



The WRT Tools package  includes a set of Web Runtime Plug-ins based on the Eclipse Plug-in Development Environment (PDE), and enables the development of WRT applications utilizing Web Technologies such as HTML, CSS, JavaScript and AJAX.

The WRT plug-in(s) provide features such as enabling the creation, editing, testing and debugging of  basic WRT applications. The WRT applications require the creation, editing and saving of JavaScript, XML and HTML files. The WRT editor plug-ins are based on the Eclipse JavaScript Developer Toolkit (JSDT). JSDT is part of the Eclipse Web Tools Platform (WTP) Project.

The WRT Plug-in allows the creation of a Web Runtime (WRT) project that contains a basic widget project (i.e. an empty project with a minimal Info.plist, html, css and JavaScript files). The Info.plist is an XML template with settings of a basic widget already defined. Similarly, an index.html file is defined with an HTML template. It is also possible to import existing WRT project(s) which include a WRT Previewer for previewing a WRT widget in a conventional desktop browser.

Note that this preliminary version of the WRT Tools package uses the WRT Previewer from an Aptana WRT project due to a pending Nokia WRT license issue, but the next release will include a fully integrated WRT Previewer. An application developer can also add additional JavaScript, HTML and XML files as necessary into the existing WRT project.

The WRT Plug-in also includes a WRT Debugger component to enable debugging of  WRT applications.  The WRT Debugger component consists of a general purpose JavaScript Debugger based on the Eclipse Platform framework and the Chrome Developer Tools Project.

It should be noted that this WRT Tools package is an incremental code drop for Eclipse internal tool developers as we are planning a subsequent release in March 2010 to introduce the WRT Tools to Web Runtime (WRT) developers.

The March 2010 release will include support for a variety of WRT project templates (i.e. WRT Twitter Widget, WRTKit project, etc) as well as support for packaging, deployment, a fully integrated WRT Previewer, and more. Furthermore, there is still planning in progress for the future WRT Tools Roadmap, and among the items under discussion is a plan to integrate with other open standards, Symbian Common Web Runtime, and to support UI Designer features.

If you are interested to know more about the WRT Tools package, please see the WRT Tools Wiki Page.  For detailed instructions for installing the WRT Tools Plug-ins, and related packages or for trying out its features, please refer to the WRT Tools Developers Guide.

If you have any questions or if you are interested in engaging or collaborating with us, please feel free to leave me a comment, or contact me at tasneems at symbian.org.  You can also follow me on Twitter for further developments.  There is also a general Tools Developers mailing list for general comments.

Friday, January 8, 2010

Ovi Maps Racing Game Lets You Speed Around Your Neighborhood

A sneak preview of the Ovi Maps Racing game (coming soon to the Ovi Store) was unveiled at the 2010 Consumer Electronics Show in Las Vegas by Nokia earlier Thursday.  

In a truly unique experience, you use the GPS in your device to find your location (or use Ovi Maps to choose any location in the world), then customize a track around your neighborhood, and finally fire up those engines! --Nokia Conversations 

As pictures are better than a thousand words, check it out below!   Enjoy!  Retweet, and/or leave me a comment.


ovi-maps-racing-5
ovi-maps-racing-5
ovi-maps-racing-5
ovi-maps-racing-5
ovi-maps-racing-5

Wednesday, January 6, 2010

Was the Google Nexus One Announcement Really About Another Google Android Phone or iPhone Killer?

Was the biggest Google announcement really about another Google Android phone or the iPhone killer as some have suggested? As expected, Google announced its Google Android Nexus One at a press conference Tuesday morning.


Nexus One is a new Google Android phone that offers software internals designed by Google and the device hardware is manufactured by HTC. According to Google's Mario Queiroz, the Nexus One is a "super phone" where the Web meets the cell phone. "It's an example of what mobile phones can do with Android" says Mario. It is indeed slim, sleek, and light-weight (4.58 oz). It offers a 1 GHz Snapdragon processor. The primary interface is a 3.7 inch AMOLED display with five customizable home screens. It runs the Android 2.1 OS and the WVGA display is capable of displaying 3G graphics.

According to Google's Senior Product Manager for the Nexus One, Erick Tseng, the feature set includes everything you'd expect from an Android phone and adds a couple of unique goodies.

The Nexus One may or may not be an iPhone killer, but it doesn't really matter as the biggest Google announcement was not really about another Google Android phone. The real news at the Google event was about its online store at http://www.google.com/phone - the news that could shake up the mobile industry as it had happened during the initial iPhone announcement.  The real news was about an online storefront offering that, if successful, could revolutionize the much reviled US carrier model - offering much faster, cheaper and more flexible services for mobile users. So what is really the significance of the Google announcement?

Well, Google confirmed that Nexus One, and all subsequent Google phones sold via the company's online store will be available unlocked for use on every participating carrier. By offering a lineup of phones that is essentially carrier-independent (with the radio compatibility caveat), Google has broken the two previously interlocked parts of the phone/plan-buying—phone selection and carrier selection—and has done so in a way that threatens one of the most important enablers of carrier lock-in.

In short, what Google announced today wasn't just the Nexus One, but the world's first carrier-independent smartphone store; the Google store is now the only smartphone store in the US where, for every phone on offer, you first pick which phone you want, and then you pick a network and a plan on that network. So you can comparison shop among networks based purely on plan price and network quality, because you already have your phone picked out.

Thursday, November 5, 2009

Build Your Own Tweets Widget for the Symbian Platform

If you are a Web developer interested in developing a social networking application such as a Twitter app that can retrieve tweets on a Series 60 Symbian phone, then here are code snippets to demonstrate how easy it is to implement it using Nokia Web Runtime using Javascript, and HTML.  If you are new to mobile Web development on Symbian, take a look at the Web Runtime Quickstart tutorial.

Now to retrieve tweets on a Series 60 Symbian phone, you can implement the index.html (see slide 11 in the presentation attached below), which will invoke init() function within main.js.  The init() function will simply instantiate the UIManager and set up the views (see slides 12 and 13). Then, if the user selects the 'Tweetz' icon, then Twitter.Update() will be invoked as listed below.  The function Twitter.Update() will simply initialize the twitter buttons including adding the separator, and will display "Loading twitter feed" as it waits for the twitter feed to download.

Twitter.prototype.Update= function(numToShow){
    this.numToShow= numToShow;
    if ( this.buttons== null ) {

       // add the separator
       var separator = new NavigationButton(null, 
                           "tweetz-icon.png","");
       separator.setEnabled(false);
       this.parentView.addControl(separator);
       // create buttons
       this.buttons= new Array();
       for( var i = 0 ; i < this.numToShow; i++ ) {
           var button = 

           new NavigationButton("twitter_button_"+i, 
                                 null ,"");
           this.parentView.addControl(button);

           this.buttons.push(button);
       }
       this.buttons[0].setText(

           "Loading twitter feed...");
    }


Next, initialize the twitter URL for getting a user's RSS feed. In this case, it is initialized to the TwitMyMobile user account. Then, you can get the RSS feed by instantiating the AJAX request. The http.open() API is passed, "GET" for retrieving the data, the second parameter is the twitter URL, and the third parameter is set to true to indicate that this is an asynchronous request. The http.onreadstatechange is set when the request state changes, then the Twitter.DoUpdate() function is invoked for parsing the returned data. The code fragment for getting the user's tweets will look as follows:



 // Twitter API for getting a user’s RSS feed 
var twitterurl= "http://twitter.com/statuses/user_timeline/TwitMyMobile.rss"; 


// Get the rss feed 
// Prepare for asynchronous download 
this.http= new Ajax(); // true means asynchronous request this.http.open("GET", twitterurl, true); 
// When the AJAX request is done, it will call self.DoUpdate() this.http.onreadystatechange= function() { self.DoUpdate(); }; 


// send the AJAX request 
this.http.send(null);


Now, the Twitter.DoUpdate() method can easily parse the data. Use the DOMParser API to parse through the response XML. If the content type is not set correctly, we get the response as text. Next, we loop through traversing the elements, creating buttons and gathering tweets. The while loop traverses through the child nodes, and retrieves the title, and publishing date for each of the tweets. The tweet image is set to tweet.png for simplicity. If we get any exceptions and get no data, then we display "Tweetz not tweeting right now" message and intialize the title and date fields accordingly.


Twitter.prototype.DoUpdate= function() {
    if (this.http.readyState== 4) {
        try {
            // Get parsed Doc 
            var xmlDoc= this.http.responseXML;
            if (xmlDoc== null)
            { // if the content type is not set  
              // correctly, we get the response 
              // as text 
              var xmlparser= new DOMParser(); 
              xmlDoc = xmlparser.parseFromString(
                       this.http.responseText, 
                       "text/xml");
              var itemElements =
                  xmlDoc.getElementsByTagName("item");
              var loopEnd =
                     Math.min(this.numToShow,
                              itemElements.length);
              // traverse elements & create buttons 
              for (var i = 0; i < loopEnd; i++) { 
                 // iterate through child nodes of 
                 // this item and gather tweets
                 var title = null; 
                 var date = null; 
                 node = itemElements[i].firstChild; 
                 while (node != null) { 
                    if (node.nodeType == 
                         Node.ELEMENT_NODE) {
                       if (node.nodeName == "title") { 
                          // item title 
                          title = getTextOfNode(node); 
                       }else if 
                         (node.nodeName== "pubDate" ||
                          node.nodeName== "dc:date") { 
                          // item publishing date 
                          date = getTextOfNode(node); 
                       } 
                 } end while  


                 node = node.nextSibling; 
             } // end for  
             this.buttons[i].setText("
                 + date + " " + title + "");
             this.buttons[i].setImage("tweet.png");
          } // end if (xmldoc== null
      } // end try
      catch (x) {
         this.buttons[0].setText(
           "Uh-Oh! Tweetz not tweeting right now.");
         for (var i = 0; i < this.numToShow; i++) {

            this.buttons[i].setText("");
            this.buttons[i].setImage(null); 
         } // end for  
      } // end catch
  } // if (this.http.readyState== 4) {} 


 For a complete listing of the code, take a look at the slides I had presented at SEE 2009 on Improving the Mobile Web Developer Experience illustrated below.  If you find this article useful, please feel free to retweet and forward me any comments.

Monday, October 19, 2009

Mobile 2.0: Developer Pitfalls & Strategies for Improving Mobile Web Developer Experience

Last Friday, I gave a presentation on Developer Pitfalls & Strategies for Improving Mobile Web Developer Experience at Mobile 2.0 in Silicon Valley (Mountain View, California).  It started out by defining the mobile Web, then provided an overview on the mobile device constraints that led to mobile development challenges. I briefly talked about the "Tool Trends" then took an in-depth look at strategies for improving performance when utilizing web technologies (i.e. JavaScript, CSS and HTML) based on Yahoo's 14 Performance Rules. It concluded highlighting the activities of the Symbian Foundation Tools team including a roadmap of how the Symbian tools are being evolved to further improve and enhance the mobile web developer experience.
In case you were not able to attend Mobile 2.0 or would like to take a closer look at the slides presented, it is attached below.

Monday, September 14, 2009

Implementing Incremental Project Builder for an Eclipse Web Runtime Plugin

In order to develop an Eclipse Plugin, you will need to install the Eclipse Plugin Development Environment (PDE) and for web development, you will need to install Eclipse Web Tools Platform (WTP).
This article discusses two major mechanisms that are associated with projects in an Eclipse workspace. The first of these is incremental project builders, which create a built state based on the project contents, and then keep that built state synchronized as the project contents change. The second is project natures, which define and manage the association between a given project and a particular plug-in or feature.



  • Builder - Builders take raw materials and produce some output based on those materials. In Eclipse, both the raw materials and the output of builders are resources in the Eclipse workspace.
  • Incremental - It would be inefficient if builders rebuilt their entire output from scratch every time they were invoked. Instead, builders in Eclipse are incremental. This means that after the first build, subsequent builds should only rebuild based on what has changed since the last build.
  • Project - A builder operates on the resources in a single project in the Eclipse workspace. If there are many projects in the workspace, builders need to be installed on each one separately.
How does the JavaScript compiler know which files need to be recompiled?

The Eclipse builder maintains a built state that includes a list of all types (classes or interfaces) that are referenced by each type in the workspace. This information is returned by the compiler each time a source file is compiled. This state is computed from scratch on a full build, and updated incrementally on each subsequent build.

Whenever files are modified, the builder receives a resource delta that describes which files were added, removed, or changed.

For deleted JavaScript source files, the corresponding class files are deleted. Added and changed source files are added to a queue of files that need to be compiled.

The builder then processes this queue as follows:  
  • Remove a file from the queue, and compile it.  
  • Compare the resulting type to the old class file, and see if the type has structural changes
  • Structural changes are changes that can affect the compilation of a referencing type: added or removed methods, fields or types, or changed method signatures. 
  • If the type has structural changes, find all types in the project that references the changed type, and add them to the queue. 
  • If the type has changed at all, write it to disk in the builder's output folder. Update the built state with the new reference information for the compiled type.  
  • Repeat until the queue is empty.  
  • As a final step, the builder generates problem markers for each compiled type that had compilation problems.
What are Project Natures?
Create an association between a project and a given tool, plug-in or feature set.  By adding a nature to a project, you indicate that your plug-in is configured to use that project.


Natures also provide a way of handling the lifecycle of a tool's interaction with a project.  When a nature is added to a project, the project nature's configure() method is called.  This gives the tool an opportunity to initialize its state for that project and install any incremental project builders that are needed for that project.  When a nature is removed from a project, the nature's deconfigure() method is called.  This gives the tool an opportunity to remove or clean up any meta-data it has created for that project, and to remove any listeners and builders associated with that tool.


How do we implement an Incremental Project Builder?  To implement an incremental project builder, you first have to create an extension: org.eclipse.core.resources.builders.  Next, create a Builder class that must extend the abstract IncrementalProjectBuilder superclass.

<extension
id="Builder"
name="eScript Builder"
point="org.eclipse.core.resources.builders">
<builder>
<run class="org.eclipse.escript.builder.Builder">
<parameter name="optimize" value="true"/>
<parameter name="comment" value="escriptBuilder"/>
</run>
</builder>
</extension>

public class Builder extends IncrementalProjectBuilder {

protected IProject[] build(int kind, Map args, IProgressMonitor monitor) { 
if (kind == IncrementalProjectBuilder.FULL_BUILD) { fullBuild(monitor);
} else { 
   IResourceDelta delta = getDelta(getProject()); 

if (delta == null) { 
   fullBuild(monitor); }
else { 
   incrementalBuild(delta, monitor); 
}

return null;
}

private void incrementalBuild(IResourceDelta delta, IProgressMonitor monitor) {
System.out.println("incremental build on "+delta);
try {

delta.accept(new IResourceDeltaVisitor()
{ public boolean visit(IResourceDelta delta) {
System.out.println("changed: "+
delta.getResource().getRawLocation());
return true; // visit children too
}
});
} catch (CoreException e) { e.printStackTrace(); }
}

private void fullBuild(IProgressMonitor monitor) {
    System.out.println("full build");
}
}

If you are interested in seeing a Web Runtime (WRT) Plugin demo in action, then come to the Symbian Silicon Valley SIG event on September 16.  If you found this article useful, please retweet it!