Friday, October 9, 2009

[Gd] Support for additional screen resolutions and densities in Android

| More

Android Developers Blog: Support for additional screen resolutions and densities in Android

You may have heard that one of the key changes introduced in Android 1.6 is support for new screen sizes. This is one of the things that has me very excited about Android 1.6 since it means Android will start becoming available on so many more devices. However, as a developer, I know this also means a bit of additional work. That's why we've spent quite a bit of time making it as easy as possible for you to update your apps to work on these new screen sizes.

To date, all Android devices (such as the T-Mobile G1 and Samsung I7500, among others) have had HVGA (320x480) screens. The essential change in Android 1.6 is that we've expanded support to include three different classes of screen sizes:

  • small: devices with a screen size smaller than the T-Mobile G1 or Samsung I7500, for example the recently announced HTC Tattoo
  • normal: devices with a screen size roughly the same as the G1 or I7500.
  • large: devices with a screen size larger than the G1 or I7500 (such as a tablet-style device.)

Any given device will fall into one of those three groups. As a developer, you can control if and how your app appears to devices in each group by using a few tools we've introduced in the Android framework APIs and SDK. The documentation at the developer site describes each of these tools in detail, but here they are in a nutshell:

  • new attributes in AndroidManifest for an application to specify what kind of screens it supports,
  • framework-level support for using image drawables/layouts correctly regardless of screen size,
  • a compatibility mode for existing applications, providing a pseudo-HVGA environment, and descriptions of compatible device resolutions and minimum diagonal sizes.

The documentation also provides a quick checklist and testing tips for developers to ensure their apps will run correctly on devices of any screen size.

Once you've upgraded your app using Android 1.6 SDK, you'll need to make sure your app is only available to users whose phones can properly run it. To help you with that, we've also added some new tools to Android Market.

Until the next time you upload a new version of your app to Android Market, we will assume that it works for normal-class screen sizes. This means users with normal-class and large-class screens will have access to these apps. Devices with "large" screens simply run these apps in a compatibility mode, which simulates an HVGA environment on the larger screen.

Devices with small-class screens, however, will only be shown apps which explicitly declare (via the AndroidManifest) that they will run properly on small screens. In our studies, we found that "squeezing" an app designed for a larger screen onto a smaller screen often produces a bad result. To prevent users with small screens from getting a bad impression of your app (and reviewing it negatively!), Android Market makes sure that they can't see it until you upload a new version that declares itself compatible.

We expect small-class screens, as well as devices with additional resolutions in Table 1 in the developer document to hit the market in time for the holiday season. Note that not all devices will be upgraded to Android 1.6 at the same time. There will be significant number of users still with Android 1.5 devices. To use the same apk to target Android 1.5 devices and Android 1.6 devices, build your apps using Android 1.5 SDK and test your apps on both Android 1.5 and 1.6 system images to make sure they continue to work well on both types of devices. If you want to target small-class devices like HTC Tattoo, please build your app using the Android 1.6 SDK. Note that if your application requires Android 1.6 features, but does not support a screen class, you need to set the appropriate attributes to false. To use optimized assets for normal-class, high density devices like WVGA, or for low density devices please use the Android 1.6 SDK.

URL: http://android-developers.blogspot.com/2009/10/support-for-additional-screen.html

[Gd] Mercurial server-side clone support for Project Hosting on Google Code

| More

Google Code Blog: Mercurial server-side clone support for Project Hosting on Google Code

When we launched Mercurial support our goal was to get to a point where we could enable a social coding experience. Today, I am happy to announce that today we have support for both 'project' clones and 'user' clones.

Project owners can now create multiple repositories for their project, and they can choose to make any of those new repositories a clone of any of the project's other repositories. These project clones share the same commit access permissions as the original project and make it easier for project members to work together on new features. A common pattern in the Mercurial world is to place each "official" branch into a separate repository with naming conventions like "project-crew", "project-stable", and so on.

In addition to project clones, any user can visit any Mercurial repository and create a server-side user clone of that repository, without asking permission from the project owner. These personal user clones can be easily shared with other developers -- who also can make a clone of that clone. Once a user has finished her changes in a user clone, she can coordinate with the canonical project's contributors to review and incorporate her changes.



User clones aren't forks, in the traditional sense, where a fork has little intention to contribute back to the original project. Rather, the entire purpose of a user clone is to allow users to contribute to projects without requiring official commit access permissions. Because mercurial is a distributed (peer-to-peer) version control system, it excels at branching and merging. If the project maintainers like the new code, they just "pull" the changesets from the clone and merge them into an official project repository. It's all much more elegant than emailing patches back and forth, anonymous contributors get to use the same tools as core developers.

The instructions for creating a user clone can be found on the checkout page for any Mercurial project (e.g. twisty) and existing clones for a project can be found under the Clones sub-tab under Source.

Please let us know if you have any feedback or find any issues. Happy cloning!

By Nathaniel Manista and Jacob Lee, Project Hosting on Google Code
URL: http://googlecode.blogspot.com/2009/10/mercurial-server-side-clone-support-for.html

Thursday, October 8, 2009

[Gd] Building Enterprise web apps in the cloud

| More

Google Web Toolkit Blog: Building Enterprise web apps in the cloud

An important decision to make when building a web application is how to coordinate state between client and server. This includes how to create appropriate representations of your data to send over the wire.







There are many possible approaches. I'd like to present a straightforward one from Jerome Breche, CEO of TimZon, who was kind enough to share it with us today.













When we started our first GWT project (TimZon.com), we found out that one of the major benefits of using GWT is its ability to transfer complex object data structure between client and server through the RPC mechanism. So when we initiated our second project (SnapABug.com) combining GWT and Google App Engine, we were very excited by the prospect of passing datastore objects directly though RPC.




We quickly realized that this is not very practical. First one of our
JDO objects includes images binary representation that we wouldn’t want to communicate through RPC. And then while making the JDO class serializable for GWT RPC may seem like a simple task, it created all kind of new problems since the JDO class will have to be configured as transient (using detachable = "false") and we would still need to copy the object when passing it through the RPC.

Instead we decided to simply create intermediary classes for the data objects used only for RPC communication. This way we can exactly control and optimize the data payload used by the RPC both for size and speed. On the JDO side, we simply created a getter and setter function to translate the JDO data into an RPC data format.





Here is an example of how this works in client side code.




1. Employee class: contains JDO objects definition and getter and setter to translate them to GWT RPC serializable format


@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Employee {


@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Long id;

@Persistent
private String name;

@Persistent
private String email;

@Persistent
private Blob image;

/**


* Constructor
* @param name
* @param email
*/
public Employee(String name, String email) {
this.name = name;
this.email = email;
}

/**
* Set Employee from RPCDataEmployee
*/
public void setRPCDataEmployee(RPCDataEmployee employee) {
name = employee.name;
email = employee.email;
}

/**
* @return Employee data in RPC format
*/
public RPCDataEmployee getRPCDataEmployee() {
RPCDataEmployee employee = new RPCDataEmployee();
employee.name = name;
employee.email = email;
return employee;
}
}





2. RPCDataEmployee class used by GWT RPC calls




public class RPCDataEmployee implements IsSerializable {

public String name;
public String email;
// Note: image Blob not included in RPC payload
}








Here is an example of how this works in the server




3. RPCDataEmployee server service implementation


public RPCDataEmployee getEmployee(String email){
RPCDataEmployee employee = new RPCDataEmployee();

// create data store connection
PersistenceManager pm = PMF.get().getPersistenceManager();

// query datastore to get emmployee data
String query = "select from "


+ Employee.class.getName()

+ " where email == "

+ email;


List employees =

(List) pm.newQuery(query).execute();


if (employees.size() == 1) {
// record found
employee = employees.get(0).getRPCDataEmployee();
} else {
// do something else...
}


pm.close();


return employee;
}





While I am sure there are many other ways to achieve a similar result, maybe even avoiding duplicating the data classes, this solution was the easiest for us to get going quickly, keep our code very maintainable and control the amount of data exchanged between client and server.


There is also a very interesting discussion about this subject on the GWT Google Group.








-- Jerome Breche, CEO & Founder of TIMZON, LLC














If you would like to share your experiences with GWT and Google App Engine, either privately or on this blog, I'd like to hear from you.








URL: http://googlewebtoolkit.blogspot.com/2009/10/building-enterprise-web-apps-in-cloud.html

[Gd] Making AJAX Crawlable

| More

Google Web Toolkit Blog: Making AJAX Crawlable

At the recent Search Marketing and Expo East Conference (SMX) several members of the Google Web Toolkit team delivered a presentation on making AJAX enabled web apps crawlable. This presentation included a proposal that is currently in the works which aims to solve the fundamental problem that it is difficult to index AJAX enabled web apps and therefore their searchability suffers. If you care about SEO in your GWT apps, check out the post on the Google Webmaster Central Blog and let us know your thoughts.
URL: http://googlewebtoolkit.blogspot.com/2009/10/making-ajax-crawlable.html

[Gd] Google Sites turns Custom Search on

| More

Google Custom Search: Google Sites turns Custom Search on

Posted by: Scott Johnston, Senior Product Manager, Google Sites and Rajat Mukherjee, Group Product Manager, Search

Google Sites offers users a very simple way to create and publish web sites. Multiple users can collaborate to manage website content as well as add various gadgets into their websites. Google Sites now allows the addition of Google Custom Search as a search option.

In the following example, we add a Yoga Search Custom Search experience to the Yoga for Life web site in a few simple steps. (The example assumes that the Yoga for Life website is hosted by Google Sites, and that the Yoga Search has already been created using Google Custom Search.)
  1. Login to your Google Site, and select the "Manage Site" option in the "More Actions" dropdown.


  2. Select the "Site Layout" option from the Navigation menu on the left. Click the "Configure Search" button.


  3. Select the Advanced tab in the "Configure site search" dialog. To add a new search provider, click on the "Add provider" button.


  4. Now, we'll need to get information about the Custom Search engine we want to use. Open up another tab or browser window and login to the Custom Search control panel. Find the URL for the search engine you want to use by clicking on it's name in the list called My search engines. Copy this URL; you will use it in the next step. In this example, we'll use the URL for Yoga Search.


  5. Go back to the Google Sites search provider dialog. Select "Google Custom Search" as the provider type. Type in the Name, e.g., "Yoga Search" for the search option you'd like your users see on your site, and paste the Custom Search Engine URL that you obtained in the earlier step. Leave the Show results in site option checked. Click OK.


  6. You can change your default provider by clicking on the "General" tab in the "Configure site search" dialog and selecting "Yoga Search". Make sure to Save your settings. You're done.


  7. Your users will see Yoga Search as the default search option in the search box on the Yoga for Life website. Search, and your results from the Yoga Search Custom Search engine will show up inline, with the correct look and feel of your site.


Try it out for your site, with your own Custom Search engine! As always, we'd love to hear your feedback on new features in the user group.
URL: http://googlecustomsearch.blogspot.com/2009/10/google-sites-turns-custom-search-on.html

Wednesday, October 7, 2009

[Gd] Dev Channel Update

| More

Google Chrome Releases: Dev Channel Update

The Dev channel has been updated to 4.0.221.6 for Windows and 4.0.221.8 for Mac and Linux.


  • All
    • Theme change should automatically update New Tab Page background again. [r27841] (Issue: 20392)
  • Mac
    • No longer crash when selecting closed window from Dock menu. [r27769] (Issue: 14003)
    • Fix several issues with dragging tabs and quickly letting go. [r27861] (Issues: 22266, 13594, 22538)
    • Fixes for full screen plugins: keystrokes are now sent to full screen plugins and the Menu Bar is properly hidden. [r27755] (Issues: 19534, 21020)
  • Linux
    • Work around the sudden creation of a tree of directories in your homedir after an update.  [r27997] (Issue: 23327)
    • Tab titles in Thai locales are no longer chopped.  [r27725] (Issue: 22791)
  • Extensions
    • More features for browser actions (still in progress, still Windows-only)
    • Fix bug on Linux where directory cruft was accidentally created. (Issue: 23327)
  • Known Issues
    • Linux: Google Chrome fails to collect zombie processes from closed tabs. (Issue: 23778)
    • Mac: Bookmark bar looks weird, and hurts you when you resize the window (hit cmd-shift-b twice after window resizing as workaround).

More details about additional changes are available in the svn log of all revisions.

You can find out about getting on the Dev channel here: http://dev.chromium.org/getting-involved/dev-channel.

If you find new issues, please let us know by filing a bug at http://code.google.com/p/chromium/issues/entry.

Anthony Laforge
Google Chrome Program Manager
URL: http://googlechromereleases.blogspot.com/2009/10/dev-channel-update.html

[Gd] A proposal for making AJAX crawlable

| More

Official Google Webmaster Central Blog: A proposal for making AJAX crawlable

Webmaster level: Advanced

Today we're excited to propose a new standard for making AJAX-based websites crawlable. This will benefit webmasters and users by making content from rich and interactive AJAX-based websites universally accessible through search results on any search engine that chooses to take part. We believe that making this content available for crawling and indexing could significantly improve the web.

While AJAX-based websites are popular with users, search engines traditionally are not able to access any of the content on them. The last time we checked, almost 70% of the websites we know about use JavaScript in some form or another. Of course, most of that JavaScript is not AJAX, but the better that search engines could crawl and index AJAX, the more that developers could add richer features to their websites and still show up in search engines.

Some of the goals that we wanted to achieve with this proposal were:
  • Minimal changes are required as the website grows

  • Users and search engines see the same content (no cloaking)

  • Search engines can send users directly to the AJAX URL (not to a static copy)

  • Site owners have a way of verifying that their AJAX website is rendered correctly and thus that the crawler has access to all the content


Here's how search engines would crawl and index AJAX in our initial proposal:
  • Slightly modify the URL fragments for stateful AJAX pages
    Stateful AJAX pages display the same content whenever accessed directly. These are pages that could be referred to in search results. Instead of a URL like http://example.com/page?query#state we would like to propose adding a token to make it possible to recognize these URLs: http://example.com/page?query#[FRAGMENTTOKEN]state . Based on a review of current URLs on the web, we propose using "!" (an exclamation point) as the token for this. The proposed URL that could be shown in search results would then be: http://example.com/page?query#!state.

  • Use a headless browser that outputs an HTML snapshot on your web server
    The headless browser is used to access the AJAX page and generates HTML code based on the final state in the browser. Only specially tagged URLs are passed to the headless browser for processing. By doing this on the server side, the website owner is in control of the HTML code that is generated and can easily verify that all JavaScript is executed correctly. An example of such a browser is HtmlUnit, an open-sourced "GUI-less browser for Java programs.

  • Allow search engine crawlers to access these URLs by escaping the state
    As URL fragments are never sent with requests to servers, it's necessary to slightly modify the URL used to access the page. At the same time, this tells the server to use the headless browser to generate HTML code instead of returning a page with JavaScript. Other, existing URLs - such as those used by the user - would be processed normally, bypassing the headless browser. We propose escaping the state information and adding it to the query parameters with a token. Using the previous example, one such URL would be http://example.com/page?query&[QUERYTOKEN]=state . Based on our analysis of current URLs on the web, we propose using "_escaped_fragment_" as the token. The proposed URL would then become http://example.com/page?query&_escaped_fragment_=state .

  • Show the original URL to users in the search results
    To improve the user experience, it makes sense to refer users directly to the AJAX-based pages. This can be achieved by showing the original URL (such as http://example.com/page?query#!state from our example above) in the search results. Search engines can check that the indexable text returned to Googlebot is the same or a subset of the text that is returned to users.



(Graphic by Katharina Probst)

In summary, starting with a stateful URL such as
http://example.com/dictionary.html#AJAX , it could be available to both crawlers and users as
http://example.com/dictionary.html#!AJAX which could be crawled as
http://example.com/dictionary.html?_escaped_fragment_=AJAX which in turn would be shown to users and accessed as
http://example.com/dictionary.html#!AJAX



We're currently working on a proposal and a prototype implementation. Feedback is very welcome — please add your comments below or in our Webmaster Help Forum. Thank you for your interest in making the AJAX-based web accessible and useful through search engines!

Proposal by Katharina Probst, Bruce Johnson, Arup Mukherjee, Erik van der Poel and Li Xiao, Google
Blog post by John Mueller, Webmaster Trends Analyst, Google Zürich
URL: http://googlewebmastercentral.blogspot.com/2009/10/proposal-for-making-ajax-crawlable.html

Tuesday, October 6, 2009

[Gd] AdWords Downtime: October 10th, 10am-2pm PDT

| More

AdWords API Blog: AdWords Downtime: October 10th, 10am-2pm PDT

We'll be performing routine system maintenance on Saturday, October 10th from approximately 10:00am to 2:00pm PDT. You won't be able to access AdWords or the API during this time frame, but your ads will continue to run as normal.

Best,
-Eric Koleda, AdWords API Team
URL: http://adwordsapi.blogspot.com/2009/10/adwords-downtime-october-10th-10am-2pm.html

[Gd] Reunifying duplicate content on your website

| More

Official Google Webmaster Central Blog: Reunifying duplicate content on your website

Handling duplicate content within your own website can be a big challenge. Websites grow; features get added, changed and removed; content comes—content goes. Over time, many websites collect systematic cruft in the form of multiple URLs that return the same contents. Having duplicate content on your website is generally not problematic, though it can make it harder for search engines to crawl and index the content. Also, PageRank and similar information found via incoming links can get diffused across pages we aren't currently recognizing as duplicates, potentially making your preferred version of the page rank lower in Google.

Steps for dealing with duplicate content within your website
  1. Recognize duplicate content on your website.
    The first and most important step is to recognize duplicate content on your website. A simple way to do this is to take a unique text snippet from a page and to search for it, limiting the results to pages from your own website by using a site:query in Google. Multiple results for the same content show duplication you can investigate.

  2. Determine your preferred URLs.
    Before fixing duplicate content issues, you'll have to determine your preferred URL structure. Which URL would you prefer to use for that piece of content?

  3. Be consistent within your website.
    Once you've chosen your preferred URLs, make sure to use them in all possible locations within your website (including in your Sitemap file).

  4. Apply 301 permanent redirects where necessary and possible.
    If you can, redirect duplicate URLs to your preferred URLs using a 301 response code. This helps users and search engines find your preferred URLs should they visit the duplicate URLs. If your site is available on several domain names, pick one and use the 301 redirect appropriately from the others, making sure to forward to the right specific page, not just the root of the domain. If you support both www and non-www host names, pick one, use the preferred domain setting in Webmaster Tools, and redirect appropriately.

  5. Implement the rel="canonical" link element on your pages where you can.
    Where 301 redirects are not possible, the rel="canonical" link element can give us a better understanding of your site and of your preferred URLs. The use of this link element is also supported by major search engines such as Ask.comBing and Yahoo!.

  6. Use the URL parameter handling tool in Google Webmaster Tools where possible.
    If some or all of your website's duplicate content comes from URLs with query parameters, this tool can help you to notify us of important and irrelevant parameters within your URLs. More information about this tool can be found in our announcement blog post.

What about the robots.txt file?

One item which is missing from this list is disallowing crawling of duplicate content with your robots.txt file. We now recommend not blocking access to duplicate content on your website, whether with a robots.txt file or other methods. Instead, use the rel="canonical" link element, the URL parameter handling tool, or 301 redirects. If access to duplicate content is entirely blocked, search engines effectively have to treat those URLs as separate, unique pages since they cannot know that they're actually just different URLs for the same content. A better solution is to allow them to be crawled, but clearly mark them as duplicate using one of our recommended methods. If you allow us to crawl these URLs, Googlebot will learn rules to identify duplicates just by looking at the URL and should largely avoid unnecessary recrawls in any case. In cases where duplicate content still leads to us crawling too much of your website, you can also adjust the crawl rate setting in Webmaster Tools.

We hope these methods will help you to master the duplicate content on your website! Information about duplicate content in general can also be found in our Help Center. Should you have any questions, feel free to join the discussion in our Webmaster Help Forum.

Posted by John Mueller, Webmaster Trends Analyst, Google Zürich
URL: http://googlewebmastercentral.blogspot.com/2009/10/reunifying-duplicate-content-on-your.html

[Gd] ADC 2 Round 1 Scoring Complete

| More

Android Developers Blog: ADC 2 Round 1 Scoring Complete

ADC 2 icon

The response to round one of the Android Developer Challenge 2 has been phenomenal! We originally expected that it would take two weeks to get all the necessary data to complete scoring. Over the last 10 days, more than 26,000 Android users reviewed and submitted our target of over 100 scores per application. With this enthusiastic support of the Android community, we are closing the first round of ADC 2 judging today.

We will now be reviewing the results and preparing for round 2. Please stay tuned for information about round 2, where the community, combined with a panel of judges, will narrow down the top 20 applications in each category to determine the final winners. Until then, users with the ADC 2 judging application currently installed will get a notice saying that round 1 is over. When round 2 opens, the judging application will resume giving out new submissions to score. We look forward to seeing the results of the final round and hope that you choose to help us score these top apps as well!

URL: http://android-developers.blogspot.com/2009/10/adc-2-round-1-scoring-complete.html

[Gd] [Language][Update] New Transliteration Language (Persian)

| More

Google AJAX API Alerts: [Language][Update] New Transliteration Language (Persian)

Added Persian to the Transliteration API.
URL: http://ajax-api-alerts.blogspot.com/2009/10/languageupdate-new-transliteration.html

Monday, October 5, 2009

[Gd] Refreshing code.google.com/speed

| More

Google Code Blog: Refreshing code.google.com/speed

Today, we're happy to share some updates on code.google.com/speed with you.

We launched code.google.com/speed in June, to give web developers access to tools and resources that help them improve the performance of their applications. Since then, the developer community provided us with plenty of suggestions on how to improve our site. Based on your feedback, we made the following improvements:
  • We added new content: 
    • Four new best practice articles on topics such as optimizing JavaScript
    • Two new tech talks on new developer tools
    • A blog gadget that aggregates performance related posts from Google blogs.
  • We improved the layout to make navigation between different tutorials, tech talks and tools smoother.


Just as making the web faster is an ongoing process, we plan to continue updating and enhancing code.google.com/speed with more resources. Currently, we are focusing on increasing community involvement, such as adding more tutorials and tech talks from non-Google authors. So, as a first step, if you have recently written an interesting article on web performance, please let us know by filling in this form. Our team will evaluate all entries and may contact you for potential next steps.

Together, let's make the web faster!

By Yi Wang, Product Manager
URL: http://googlecode.blogspot.com/2009/10/refreshing-codegooglecomspeed.html

[Gd] GWT helps developers innovate in the enterprise

| More

Google Web Toolkit Blog: GWT helps developers innovate in the enterprise

I had an opportunity to sit down with TechCrunch50 Demopit winners and creators of Socialwok, a cloud based application which mixes Google Apps and a unique set of social capabilities to make their customers more productive, both at their desks and on the road via their mobile web client. They chose Google App Engine for scalability and hassle free web hosting and Google Web Toolkit to maximize their productivity so that they could focus on creating a great web experience for their users. You can watch the interview here.











URL: http://googlewebtoolkit.blogspot.com/2009/10/gwt-helps-developers-innovate-in.html

[Gd] Beta and Stable Channel Update

| More

Google Chrome Releases: Beta and Stable Channel Update

The beta and stable channels have been updated to 195.25.  This release includes only a single change that adds an image link to the new tab page which directs new users to the themes gallery.


Anthony Laforge
Google Chrome Program Manager
URL: http://googlechromereleases.blogspot.com/2009/10/beta-and-stable-channel-update.html

[Gd] New parameter handling tool helps with duplicate content issues

| More

Official Google Webmaster Central Blog: New parameter handling tool helps with duplicate content issues

Duplicate content has been a hot topic among webmasters and our blog for over three years. One of our first posts on the subject came out in December of '06, and our most recent post was last week. Over the past three years, we've been providing tools and tips to help webmasters control which URLs we crawl and index, including a) use of 301 redirects, b) www vs. non-www preferred domain setting, c) change of address option, and d) rel="canonical".

We're happy to announce another feature to assist with managing duplicate content: parameter handling. Parameter handling allows you to view which parameters Google believes should be ignored or not ignored at crawl time, and to overwrite our suggestions if necessary.


Let's take our old example of a site selling Swedish fish. Imagine that your preferred version of the URL and its content looks like this:
http://www.example.com/product.php?item=swedish-fish

However, you may also serve the same content on different URLs depending on how the user navigates around your site, or your content management system may embed parameters such as sessionid:
http://www.example.com/product.php?item=swedish-fish&category=gummy-candy
http://www.example.com/product.php?item=swedish-fish&trackingid=1234&sessionid=5678

With the "Parameter Handling" setting, you can now provide suggestions to our crawler to ignore the parameters category, trackingid, and sessionid. If we take your suggestion into account, the net result will be a more efficient crawl of your site, and fewer duplicate URLs.

Since we launched the feature, here are some popular questions that have come up:

Are the suggestions provided a hint or a directive?
Your suggestions are considered hints. We'll do our best to take them into account; however, there may be cases when the provided suggestions may do more harm than good for a site.

When do I use parameter handling vs rel="canonical"?
rel="canonical" is a great tool to manage duplicate content issues, and has had huge adoption. The differences between the two options are:
  • rel="canonical" has to be put on each page, whereas parameter handling is set at the host level
  • rel="canonical" is respected by many search engines, whereas parameter handling suggestions are only provided to Google
Use which option works best for you; it's fine to use both if you want to be very thorough.

As always, your feedback on our new feature is appreciated.

Posted by Tanya Gupta and Ningning Zhu, Software Engineers
URL: http://googlewebmastercentral.blogspot.com/2009/10/new-parameter-handling-tool-helps-with.html

[Gd] Gestures on Android 1.6

| More

Android Developers Blog: Gestures on Android 1.6

Touch screens are a great way to interact with applications on mobile devices. With a touch screen, users can easily tap, drag, fling, or slide to quickly perform actions in their favorite applications. But it's not always that easy for developers. With Android, it's easy to recognize simple actions, like a swipe, but it's much more difficult to handle complicated gestures, which also require developers to write a lot of code. That's why we have decided to introduce a new gestures API in Android 1.6. This API, located in the new package android.gesture, lets you store, load, draw and recognize gestures. In this post I will show you how you can use the android.gesture API in your applications. Before going any further, you should download the source code of the examples.

Creating a gestures library

The Android 1.6 SDK comes with a new application pre-installed on the emulator, called Gestures Builder. You can use this application to create a set of pre-defined gestures for your own application. It also serves as an example of how to let the user define his own gestures in your applications. You can find the source code of Gestures Builders in the samples directory of Android 1.6. In our example we will use Gestures Builder to generate a set of gestures for us (make sure to create an AVD with an SD card image to use Gestures Builder.) The screenshot below shows what the application looks like after adding a few gestures:

As you can see, a gesture is always associated with a name. That name is very important because it identifies each gesture within your application. The names do not have to be unique. Actually it can be very useful to have several gestures with the same name to increase the precision of the recognition. Every time you add or edit a gesture in the Gestures Builder, a file is generated on the emulator's SD card, /sdcard/gestures. This file contains the description of all the gestures, and you will need to package it inside your application inside the resources directory, in /res/raw.

Loading the gestures library

Now that you have a set of pre-defined gestures, you must load it inside your application. This can be achieved in several ways but the easiest is to use the GestureLibraries class:

mLibrary = GestureLibraries.fromRawResource(this, R.raw.spells);
if (!mLibrary.load()) {
finish();
}

In this example, the gesture library is loaded from the file /res/raw/spells. You can easily load libraries from other sources, like the SD card, which is very important if you want your application to be able to save the library; a library loaded from a raw resource is read-only and cannot be modified. The following diagram shows the structure of a library:

Recognizing gestures

To start recognizing gestures in your application, all you have to do is add a GestureOverlayView to your XML layout:

<android.gesture.GestureOverlayView
android:id="@+id/gestures"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1.0" />

Notice that the GestureOverlayView is not part of the usual android.widget package. Therefore, you must use its fully qualified name. A gesture overlay acts as a simple drawing board on which the user can draw his gestures. You can tweak several visual properties, like the color and the width of the stroke used to draw gestures, and register various listeners to follow what the user is doing. The most commonly used listener is GestureOverlayView.OnGesturePerformedListener which fires whenever a user is done drawing a gesture:

GestureOverlayView gestures = (GestureOverlayView) findViewById(R.id.gestures);
gestures.addOnGesturePerformedListener(this);

When the listener fires, you can ask the GestureLibrary to try to recognize the gesture. In return, you will get a list of Prediction instances, each with a name - the same name you entered in the Gestures Builder - and a score. The list is sorted by descending scores; the higher the score, the more likely the associated gesture is the one the user intended to draw. The following code snippet demonstrates how to retrieve the name of the first prediction:

public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {
ArrayList predictions = mLibrary.recognize(gesture);

// We want at least one prediction
if (predictions.size() > 0) {
Prediction prediction = predictions.get(0);
// We want at least some confidence in the result
if (prediction.score > 1.0) {
// Show the spell
Toast.makeText(this, prediction.name, Toast.LENGTH_SHORT).show();
}
}
}

In this example, the first prediction is taken into account only if it's score is greater than 1.0. The threshold you use is entirely up to you but know that scores lower than 1.0 are typically poor matches. And this is all the code you need to create a simple application that can recognize pre-defined gestures (see the source code of the project GesturesDemo):

Gestures overlay

In the example above, the GestureOverlayView was used as a normal view, embedded inside a LinearLayout. However, as its name suggests, it can also be used as an overlay on top of other views. This can be useful to recognize gestures in a game or just anywhere in the UI of an application. In the second example, called GesturesListDemo, we'll create an overlay on top of a list of contacts. We start again in Gestures Builder to create a new set of pre-defined gestures:

And here is what the XML layout looks like:

<android.gesture.GestureOverlayView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/gestures"
android:layout_width="fill_parent"
android:layout_height="fill_parent"

android:gestureStrokeType="multiple"
android:eventsInterceptionEnabled="true"
android:orientation="vertical">

<ListView
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />

</android.gesture.GestureOverlayView>

In this application, the gestures view is an overlay on top of a regular ListView. The overlay also specifies a few properties that we did not need before:

  • gestureStrokeType: indicates whether we want to recognize gestures made of a single stroke or multiple strokes. Since one of our gestures is the "+" symbol, we need multiple strokes
  • eventsInterceptionEnabled: when set to true, this property tells the overlay to steal the events from its children as soon as it knows the user is really drawing a gesture. This is useful when there's a scrollable view under the overlay, to avoid scrolling the underlying child as the user draws his gesture
  • orientation: indicates the scroll orientation of the views underneath. In this case the list scrolls vertically, which means that any horizontal gestures (like action_delete) can immediately be recognized as a gesture. Gestures that start with a vertical stroke must contain at least one horizontal component to be recognized. In other words, a simple vertical line cannot be recognized as a gesture since it would conflict with the list's scrolling.

The code used to load and set up the gestures library and overlay is exactly the same as before. The only difference is that we now check the name of the predictions to know what the user intended to do:

public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {
ArrayList<Prediction> predictions = mLibrary.recognize(gesture);
if (predictions.size() > 0 && predictions.get(0).score > 1.0) {
String action = predictions.get(0).name;
if ("action_add".equals(action)) {
Toast.makeText(this, "Adding a contact", Toast.LENGTH_SHORT).show();
} else if ("action_delete".equals(action)) {
Toast.makeText(this, "Removing a contact", Toast.LENGTH_SHORT).show();
} else if ("action_refresh".equals(action)) {
Toast.makeText(this, "Reloading contacts", Toast.LENGTH_SHORT).show();
}
}
}

The user is now able to draw his gestures on top of the list without interfering with the scrolling:

The overlay even gives visual clues as to whether the gesture is considered valid for recognition. In the case of a vertical overlay, for instance, a single vertical stroke cannot be recognized as a gesture and is therefore drawn with a translucent color:

It's your turn

Adding support for gestures in your application is easy and can be a valuable addition. The gestures API does not even have to be used to recognize complex shapes; it will work equally well to recognize simple swipes. We are very excited by the possibilities the gestures API offers, and we're eager to see what cool applications the community will create with it.

URL: http://android-developers.blogspot.com/2009/10/gestures-on-android-16.html

[Gd] Interactive XMPP demos

| More

Google App Engine Blog: Interactive XMPP demos

We hope you've been enjoying the new XMPP API we shipped in App Engine release 1.2.5. We're always impressed with the cool scenarios our developers create!


A couple of Google engineers found the time to create cool App Engine demos using the XMPP API and we'd like to share them with you.


CrowdGuru - this app, courtesy of App Engine Developer Programs Engineer Nick Johnson, is a fun trivia game which crowdsources answers. Add crowdguru@appspot.com to your IM list and ask it a question. You can read up on full details of the design and implementation here.


Multi-Chat - David Symonds wasn't satisfied with simple person-to-person IM, so he built an IRC-like chat room system! Add multi-chat@appspot.com to your IM list and message it "/help" to find out how you can join channels and start chatting it up. Full source is available here, and a basic web interface is here.


Of course, please note that these apps are solely intended to demonstrate the power of the XMPP API - they are not official products in any form, nor are they supported. In particular, don't send any private or personally identifying information when chatting with these bots.


But definitely try them out and let us know what cool app experiences you are building with App Engine!



Posted by the Google App Engine Team
URL: http://googleappengine.blogspot.com/2009/10/interactive-xmpp-demos.html

[Gd] TotT: Making a Perfect Matcher

| More

Google Testing Blog: TotT: Making a Perfect Matcher

by Zhanyong G. Mock Wan in Google Kirkland

In the previous episode, we showed how Google C++ Mocking Framework matchers can make both your test code and your test output readable. What if you cannot find the right matcher for the task?

Don't settle for anything less than perfect. It's easy to create a matcher that does exactly what you want, either by composing from existing matchers or by writing one from scratch.

The simplest composite matcher is Not(m), which negates matcher m as you may have guessed. We also have AnyOf(m1, ..., mn) for OR-ing and AllOf(m1, ..., mn) for AND-ing. Combining them wisely and you can get a lot done. For example,

EXPECT_THAT(new_code, AnyOf(StartsWith(“// Tests”)),
              Not(ContainsRegex(“TODO.*intern”))));

could generate a message like:

Expected: (starts with “// Tests”) or
          (doesn't contain regular expression “TODO.*intern”)
Actual: “/* TODO: hire an intern. */ int main() {}”

If the matcher expression gets too complex, or your matcher logic cannot be expressed in terms of existing matchers, you can use plain C++. The MATCHER macro lets you define a named matcher:

MATCHER(IsEven, “”) { return (arg % 2) == 0; }

allows you to write EXPECT_THAT(paren_num, IsEven()) to verify that paren_num is divisible by two. The special variable arg refers to the value being validated (paren_num in this case) – it is not a global variable.

You can put any code between {} to validate arg, as long as it returns a bool value.

The empty string “” tells Google C++ Mocking Framework to automatically generate the matcher's description from its name (therefore you'll see “Expected: is even” when the match fails). As long as you pick a descriptive name, you get a good description for free.

You can also give multiple parameters to a matcher, or customize its description. The code:

// P2 means the matcher has 2 parameters. Their names are low and high.

MATCHER_P2(InClosedRange, low, high, “is in range [%(low)s, %(high)s]”) {
  return low <= arg && arg <= high;
}
...
EXPECT_THAT(my_age, InClosedRange(adult_min, penalty_to_withdraw_401k));

may print:

Expected: is in range [18, 60]
  Actual: 2

(No, that's not my real age.) Note how you can use Python-style interpolation in the description string to print the matcher parameters.
You may wonder why we haven't seen any types in the examples. Rest assured that all the code we showed you is type-safe. Google C++ Mocking Framework uses compiler type inference to “write” the matcher parameter types for you, so that you can spend the time on actually writing tests – or finding your perfect match.

Toilet-Friendly Version
URL: http://googletesting.blogspot.com/2009/10/tott-making-perfect-matcher.html