Introducing Google Brain Search for mobile

Ever had a word on the tip of your tongue but just couldn't remember it? Or perhaps blanked on a person's name in a socially awkward situation? Or even suffered memory deterioration due to ordinary aging or questionable life choices? If so, Brain Search for mobile may be for you. Using our new CADIE technology, we can now index the content of your brain to make it searchable, thus bringing you aided retrieval of memories. Check out this video to see how it works:



Your phone already has an antenna, which can pick up wireless signals. CADIE technology modifies the input wavelengths so it can read brain waves. Go to the Brain Search App (here on a computer or here on a phone.) If you bring your phone to your forehead, your phone can index your brain, making it searchable. 

Since your phone is now modified to read brainwaves, you don't even have to type your search. Put your phone to your forehead and think your query, then click on "Search me". This is helpful in situations where you don't want onlookers to know what you're searching for, so you can feel comfortable asking personal things such as "What did I eat that's making me so gassy?" or "Did I ever go out with that girl? She looks vaguely familiar." And, since CADIE's artificial neural networks run faster than those of a human being, it is faster for her to search through your thoughts and memories than for you to do it yourself.

Brain Search is available for the US, UK, France, Germany, and Italy, and on a number of different devices.
  • On Android and iPhone devices, Brain Search runs in the browser, taking advantage of HTML5 and Gears technologies.
  • On Windows Mobile devices, make sure you download and install the latest version of Google Mobile App. Click the Panda icon (CADIE's choice, don't ask us) to get to Brain Search.  
  • On Blackberry devices (US and UK only), make sure you download and install the latest version of Google Mobile App. Type "Brain Search" in the search box. You'll get a link to Brain Search in the search suggestions below. 
To get started on any of these, go to google.com on your mobile device, and click the Brain Search link.

Don't forget. Brain Search.


Posted by Effie Seiberg, CADIE team

Mobile internet usage and useful mobile ads

Last December, those of you who responded to our 100th mobile blog post said that you wanted more editorial content and mobile industry insight. Here are a couple of recent mobile-related articles that you might find interesting from Google executives.

The first article went out yesterday on TechCrunch from Vic Gundotra, our VP of engineering for Google's mobile and developer products. Vic talks about the nature and prerequisites of surging mobile internet usage. Straight-forward and flat-rate data plans, modern mobile web browsers, and easy access to mobile apps -- that's what you want, right? This chart, for instance, compares mobile search traffic from one carrier (MetroPCS) that offers a simple, flat-rate data plan with a larger carrier that does not offer a comparable plan.

The second article was published today on MediaPost from Doug Garland, our VP of product management for mobile advertising. Doug offers suggestions on how to make mobile advertising work and describes the benefits of experimenting with new opportunities.

As always, feel free to leave questions and comments below or in our forum.

Developer News

For no particular reason other than to celebrate this particular Monday, I wanted to update developers on two Android-related news items.

If you're a developer who will be in the San Francisco Bay Area at the end of May, I hope you'll join us at the 2009 Google I/O developer conference. You might have already seen the sessions we had listed for Android, but today I'm quite pleased to let you know that we've added a few more Android-related sessions. You can find the full list plus abstracts on the Google I/O site, but here are the titles:

  • Turbo-Charge Your UI: How to Make Your Android UI Fast and Efficient
  • Pixel-Perfect Code: How to Marry Interaction and Visual Design the Android Way
  • Supporting Multiple Devices with One Binary
  • Debugging Arts of the Ninja Masters
  • Coding for Life—Battery Life, That Is
  • Writing Real-Time Games for Android
  • Android Lightning Talks

These sessions don't even include the "fireside chat" with the Core Technical Team that we have planned. We're working on still more sessions too; keep an ear to the ground on this blog and the Google I/O site for the latest info. I'm pretty excited about how the Android sessions for Google I/O are coming together. I think it's going to be a great event, and I hope to meet many of you there.

The other topic I want to mention is that our partners at HTC have uploaded a new system image for Android Dev Phone 1 owners. This new image is mostly the same as the one we mentioned earlier this month, but adds voice dialing. Note that not all features will work correctly in all countries, such as voice dialing and Google Voice Search which currently only work well for US English. Additionally, there are some features that we aren't able to make available at all in some countries. For instance, this build can't currently include Google Latitude due to privacy standards in some regions. We'll always keep the ADP1 builds as full-featured as we can, but it's important to remember that these devices are primarily intended for development, and won't necessarily have all the features included on mainstream builds.

I hope this news is useful to you. As always, happy coding!

Android Layout Tricks #3: Optimize with stubs

Sharing and reusing layouts is very easy with Android thanks to the <include /> tag, sometimes even too easy and you might end up with user interfaces that contain a large number of views, some of which are rarely used. Thankfully, Android offers a very special widget called ViewStub, which brings you all the benefits of the <include /> without polluting your user interface with rarely used views.

A ViewStub is a dumb and lightweight view. It has no dimension, it does not draw anything and does not participate in the layout in any way. This means a ViewStub is very cheap to inflate and very cheap to keep in a view hierarchy. A ViewStub can be best described as a lazy include. The layout referenced by a ViewStub is inflated and added to the user interface only when you decide so.

The following screenshot comes from the Shelves application. The main purpose of the activity shown in the screenshot is to present the user with a browsable list of books:

The same activity is also used when the user adds or imports new books. During such an operation, Shelves shows extra bits of user interface. The screenshot below shows the progress bar and cancel button that appear at the bottom of the screen during an import:

Because importing books is not a common operation, at least when compared to browsing the list of books, the import panel is originally represented by a ViewStub:

When the user initiates the import process, the ViewStub is inflated and replaced by the content of the layout file it references:

To use a ViewStub all you need is to specify an android:id attribute, to later inflate the stub, and an android:layout attribute, to reference what layout file to include and inflate. A stub lets you use a third attribute, android:inflatedId, which can be used to override the id of the root of the included file. Finally, the layout parameters specified on the stub will be applied to the roof of the included layout. Here is an example:

<ViewStub
android:id="@+id/stub_import"
android:inflatedId="@+id/panel_import"

android:layout="@layout/progress_overlay"

android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom" />

When you are ready to inflate the stub, simply invoke the inflate() method. You can also simply change the visibility of the stub to VISIBLE or INVISIBLE and the stub will inflate. Note however that the inflate() method has the benefit of returning the root View of the inflate layout:

((ViewStub) findViewById(R.id.stub_import)).setVisibility(View.VISIBLE);
// or
View importPanel = ((ViewStub) findViewById(R.id.stub_import)).inflate();

It is very important to remember that after the stub is inflated, the stub is removed from the view hierarchy. As such, it is unnecessary to keep a long-lived reference, for instance in an class instance field, to a ViewStub.

A ViewStub is a great compromise between ease of programming and efficiency. Instead of inflating views manually and adding them at runtime to your view hierarchy, simply use a ViewStub. It's cheap and easy. The only drawback of ViewStub is that it currently does not support the <merge /> tag.

Happy coding!

Look Ma, No Hands - Google Mobile App for Blackberry now with Search by voice and My Location

Remember the last time you tried to search for "Marks & Spencers London SW1W" on your Blackberry and ended up with 10 extra characters in the spelling of "Spencers" before you gave up on the "London" bit? If you're like us and hate typing on that tiny keyboard, you'll be glad to hear that Google Mobile App on your Blackberry will let you search with your voice and with My Location. Give it a try by visiting http://m.google.com on your Blackberry. (Blackberry Storm is not supported at this time.) Your fingers will thank you for it.

Get the latest version of Google Mobile App at http://m.google.com

Suppose you're vacationing in London, and you have a craving for fish and chips. With the My Location feature enabled, you can just enter "fish n chips" into Google Mobile App, and it will return the fish and chips restaurants closest to you. No need to type in "fish and chips near SW1W". And since Google Mobile App displays search suggestions as you type, you may only need to type part of the query before "Best Fish n Chips in London" pops up as a suggestion. We're a fan of anything that saves keystrokes on the way to deep-fried British goodness.

Search suggestions appear as you type, saving you keystrokes and time

Now on your vacation, you could have sworn your friend said to meet in "Lester Square". Unfortunately, "Lester Square" is nowhere to be found on the Tube Map. A quick voice search on Google Mobile App (just press and hold the green button) for "Lester Square" reveals the true spelling. Leicester Square is actually only two stops away on the Picadilly Line. Problem solved! And as always, local results have a link to open Google Maps for mobile to guide you there. Searching by voice can be used in combination with the My Location feature, and it works well with standard Google searches, such as currency conversion and weather. So keystrokes have been reduced... to a single press of the green button in Google Mobile App.


Who knew 'Lester Square' had an extra 'ice' in its spelling.

And if you happen to speak with a British accent, you'll be happy to know that we now support British English as well. Google Mobile App is now available on all versions of Blackberry running on O/S 4.1+ and with Search by voice on O/S 4.2 and above, although the Blackberry Storm is not supported at this time. 

Posted by Luca Zanolin, Google Mobile App engineer

New YouTube App for Windows Mobile and Nokia S60 phones

We've been working hard to support more devices and to offer better speed, quality, and robustness in the YouTube app. So we're excited to announce a new version of our mobile YouTube application that's optimized for most Window Mobile and Symbian Series 60 devices. Visit m.youtube.com from your phone to download the app.
  • More phones: Supports most Windows Mobile and Nokia S60 devices (a list of supported Nokia S60 devices is available here).
  • Speed: Faster application start-up, searching, and video loading. For even quicker access, add the application icon to your phone's home screen.
  • Video quality: The application automatically detects your device and network capabilities, and selects the highest available stream quality based on those. Videos will look sharper and sound clearer than ever.
  • WiFi: Improved streaming over WiFi to support a wider range of networks.
  • More robust streaming: Improved buffering ensures that videos will play even in weak coverage areas.
  • Easy video viewing: Once installed, no configuration is required outside of the application. We've worked really hard to make video playback "just work".
The application will alert you as more improvements become available, so keep an eye out for updates. In the meantime, visit our Community Help Forums to leave feedback for us.

For more info, check out the YouTube Blog.



Posted by Andreas Tuerk, Product Manager and Stephen Spence, Software Engineer, Mobile Team

Here comes Google Voice

We've got good news for GrandCentral users -- now you can begin previewing Google Voice, an application that helps you centralize all your telephony needs. Some features of Google Voice include voicemail transcription, the ability to search and store SMS messages and low-priced international dialing. The original functionality of GrandCentral, such as a centralized number and web accessible voicemail inbox, live on within Google Voice. You can read more about this release on the Official Google Blog.

New Image Search Results for Android and iPhone

Today we launched a new Image Search results page for Android, iPhone, and iPod touch in the US, the UK, and Japan.

With the new Image Search results, you can easily scan up to 20 images on a single results page and get the details for images that interest you. From the details page, you can view a larger thumbnail, visit the web page containing the image, or view the image by itself in full size. The new results page also supports "search-by-style" filters, which allow you to restrict your search results to people's faces, clip art, line drawings, or photo content. This feature was previously launched on Google Image Search in December 2008, and we are excited to now bring this feature to mobile.

To try it yourself, go to google.com on your Android-powered device , iPhone, or iPod touch, and click on "Images" before doing your search.

How to use Image Search:

1. To begin image search, go to google.com and click on “Images.”


2. The results page shows related images. Clicking on an image loads the details page.



3. On results page, the “filter” option on the blue bar allows selection of image style and SafeSearch settings.


4. The image details page shows a larger thumbnail and links to the original website and image.



Software Update Available for the Android Developer Phone

Back in December, the Android Dev Phone 1 (ADP1) went on sale, giving developers access to unlocked hardware for their work. A few weeks ago, consumers with retail devices received an over the air update with the 1.1 release of Android. I know that many developers will be pleased to hear that today, our colleagues at HTC have released a 1.1 version of Android for the Android Dev Phone which you can install on your device. If you have questions about the process of updating your device, you can ask the mailing list we've set up for such questions.

This new system image is fully compatible with Android 1.1. To see a list of everything that's new, you can review the notes from the 1.1_r1 SDK. This update also includes support for searching by voice, and priced apps in the Android Market.

Some developers have asked about the support for copy-protected apps on developer devices, and indeed there is a limitation you should be aware of. Many developers are concerned about the unauthorized redistribution of their applications, so they make use of the copy-protection feature (known as "forward locking") which prevents applications from being copied off devices. However, developer phones like the ADP1 allow for unrestricted access to the device's contents, making it impossible to enforce copy protection. As a result, the Market application on such devices is not able to access copy protected apps, whether they are free or paid. If you choose to add copy protection when you upload your application to the Android Market, then you won't be able to test it on the ADP1's Android Market client. Your application will always be accessible to users who have standard configurations though, and if your application (whether it is free or paid) is not copy-protected it will appear on all devices, including developer configurations.

If you own an Android Developer Phone, I definitely suggest you take advantage of this update. There's lots of good stuff in there, and the new software is backward compatible with Android 1.0, too. The original 1.0 system image is also now available, you need to downgrade for any reason. Happy coding!

Window Backgrounds & UI Speed

Some Android applications require to squeeze every bit of performance out of the UI toolkit and there are many ways to do so. In this article, you will discover how to speed up the drawing and the perceived startup time of your activities. Both these techniques rely on a single feature, the window's background drawable.

The term window background is a bit misleading however. When you setup your user interface by calling setContentView() on an Activity, Android adds your views to the Activity's window. The window however does not contain only your views, but a few others created for you. The most important one is, in the current implementation used on the T-Mobile G1, the DecorView, highlighted in the view hierarchy below:

A typical Android view hierarchy

The DecorView is the view that actually holds the window's background drawable. Calling getWindow().setBackgroundDrawable() from your Activity changes the background of the window by changing the DecorView's background drawable. As mentioned before, this setup is very specific to the current implementation of Android and can change in a future version or even on another device.

If you are using the standard Android themes, a default background drawable is set on your activities. The standard theme currently used on the T-Mobile G1 uses for instance a ColorDrawable. For most applications, this background drawable works just fine and can be left alone. It can however impacts your application's drawing performance. Let's take the example of an application that always draws a full screen opaque picture:

An opaque user interface doesn't need a window background

You can see on this screenshot that the window's background is invisible, entirely covered by an ImageView. This application is setup to redraw as fast as it can and draws at about 44 frames per second, or 22 milliseconds per frame (note: the number of frames per second used in this article were obtained on a T-Mobile G1 with my finger on the screen so as to reduce the drawing speed which would otherwise be capped at 60 fps.) An easy way to make such an application draw faster is to remove the background drawable. Since the user interface is entirely opaque, drawing the background is simply wasteful. Removing the background improves the performance quite nicely:

Remove the background for faster drawing

In this new version of the application, the drawing speed went up to 51 frames per second, or 19 milliseconds per frame. The difference of 3 milliseconds per is easily explained by the speed of the memory bus on the T-Mobile G1: it is exactly the time it takes to move the equivalent of a screenful of pixels on the bus. The difference could be even greater if the default background was using a more expensive drawable.

Removing the window's background can be achieved very easily by using a custom theme. To do so, first create a file called res/values/theme.xml containing the following:

<resources>
<style name="Theme.NoBackground" parent="android:Theme">
<item name="android:windowBackground">@null</item>
</style>
</resources>

You then need to apply the theme to your activity by adding the attribute android:theme="@style/Theme.NoBackground" to your <activity /> or <application /> tag. This trick comes in very handy for any app that uses a MapView, a WebView or any other full screen opaque view.

Opaque views and Android: this optimization is currently necessary because the Android UI toolkit is not smart enough to prevent the drawing of views hidden by opaque children. The main reason why this optimization was not implemented is simply because there are usually very few opaque views in Android applications. This is however something that I definitely plan on implementing as soon as possible and I can only apologize for not having been able to do this earlier.

Using a theme to change the window's background is also a fantastic way to improve the perceived startup performance of some of your activities. This particular trick can only be applied to activities that use a custom background, like a texture or a logo. The Shelves application is a good example:

Textured backgrounds are good candidates for window's background

If this application simply set the wooden background in the XML layout or in onCreate() the user would see the application startup with the default theme and its dark background. The wooden texture would only appear after the inflation of the content view and the first layout/drawing pass. This causes a jarring effect and gives the user the impression that the application takes time to load (which can actually be the case.) Instead, the application defines the wooden background in a theme, picked up by the system as soon as the application starts. The user never sees the default theme and gets the impression that the application is up and running right away. To limit the memory and disk usage, the background is a tiled texture defined in res/drawable/background_shelf.xml:

<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/shelf_panel"
android:tileMode="repeat" />

This drawable is simply referenced by the theme:

<resources>
<style name="Theme.Shelves" parent="android:Theme">
<item name="android:windowBackground">@drawable/background_shelf</item>
<item name="android:windowNoTitle">true</item>
</style>
</resources>

The same exact trick is used in the Google Maps application that ships with the T-Mobile G1. When the application is launched, the user immediately sees the loading tiles of MapView. This is only a trick, the theme is simply using a tiled background that looks exactly like the loading tiles of MapView.

Sometimes the best tricks are also the simplest so the next time you create an activity with an opaque UI or a custom background, remember to change the window's background.

Download the source code of the first example.

Download the source code of Shelves.

Finance for Android App

Just over a year ago, during a user experience research trip for Google Finance, we were at the home of a stay-at-home mom / day trader. She was frustrated that there were "personal blackout periods" in the trading day when she was entirely disconnected from the stock market -- for example, while she was ferrying kids around or at lunch with friends. Her situation wasn't unique. During our research visits, we had been hearing similar concerns from people who need to stay connected to the market. With the hope of resolving this dilemma, we started to design and build a finance application for the Android platform in our Google 20% time.

As the Finance for Android application took shape, and the team of 20% engineers grew, we added more features with the aim of allowing users to get stock quotes, market data, and news as fast as possible. If you are following the markets throughout the day, check out the real-time streaming quotes in your portfolio, fast stock look-ups with search auto-suggestion, and 'recent quotes' to make it even easier receive quotes on-the-go. For each stock, you can see detailed quotes, charts and news, and any change you make to your portfolio automatically syncs up with the Google Finance website. So now you don't have to worry about setting up a separate portfolio on your phone.

If you're in the US, you can now download Finance for Android from Android Market.











Android Layout Tricks #3: Optimize by merging

In the previous installment of Android Layout Tricks, I showed you how to use the <include /> tag in XML layout to reuse and share your layout code. I also mentioned the <merge /> and it's now time to learn how to use it.

The <merge /> was created for the purpose of optimizing Android layouts by reducing the number of levels in view trees. It's easier to understand the problem this tag solves by looking at an example. The following XML layout declares a layout that shows an image with its title on top of it. The structure is fairly simple; a FrameLayout is used to stack a TextView on top of an ImageView:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">

<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"

android:scaleType="center"
android:src="@drawable/golden_gate" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="20dip"
android:layout_gravity="center_horizontal|bottom"

android:padding="12dip"

android:background="#AA000000"
android:textColor="#ffffffff"

android:text="Golden Gate" />

</FrameLayout>

This layout renders nicely as we expected and nothing seems wrong with this layout:



A FrameLayout is used to overlay a title on top of an image


Things get more interesting when you inspect the result with HierarchyViewer. If you look closely at the resulting tree you will notice that the FrameLayout defined in our XML file (highlighted in blue below) is the sole child of another FrameLayout:

A layout with only one child of same dimensions can be removed

Since our FrameLayout has the same dimension as its parent, by the virtue of using the fill_parent constraints, and does not define any background, extra padding or a gravity, it is totally useless. We only made the UI more complex for no good reason. But how could we get rid of this FrameLayout? After all, XML documents require a root tag and tags in XML layouts always represent view instances.

That's where the <merge /> tag comes in handy. When the LayoutInflater encounters this tag, it skips it and adds the <merge /> children to the <merge /> parent. Confused? Let's rewrite our previous XML layout by replacing the FrameLayout with <merge />:

<merge xmlns:android="http://schemas.android.com/apk/res/android">

<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"

android:scaleType="center"
android:src="@drawable/golden_gate" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="20dip"
android:layout_gravity="center_horizontal|bottom"

android:padding="12dip"

android:background="#AA000000"
android:textColor="#ffffffff"

android:text="Golden Gate" />

</merge>

With this new version, both the TextView and the ImageView will be added directly to the top-level FrameLayout. The result will be visually the same but the view hierarchy is simpler:

Optimized view hierarchy using the merge tag

Obviously, using <merge /> works in this case because the parent of an activity's content view is always a FrameLayout. You could not apply this trick if your layout was using a LinearLayout as its root tag for instance. The <merge /> can be useful in other situations though. For instance, it works perfectly when combined with the <include /> tag. You can also use <merge /> when you create a custom composite view. Let's see how we can use this tag to create a new view called OkCancelBar which simply shows two buttons with customizable labels. You can also download the complete source code of this example. Here is the XML used to display this custom view on top of an image:

<merge
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:okCancelBar="http://schemas.android.com/apk/res/com.example.android.merge">

<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"

android:scaleType="center"
android:src="@drawable/golden_gate" />

<com.example.android.merge.OkCancelBar
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"

android:paddingTop="8dip"
android:gravity="center_horizontal"

android:background="#AA000000"

okCancelBar:okLabel="Save"
okCancelBar:cancelLabel="Don't save" />

</merge>

This new layout produces the following result on a device:

Creating a custom view with the merge tag

The source code of OkCancelBar is very simple because the two buttons are defined in an external XML file, loaded using a LayoutInflate. As you can see in the following snippet, the XML layout R.layout.okcancelbar is inflated with the OkCancelBar as the parent:

public class OkCancelBar extends LinearLayout {
public OkCancelBar(Context context, AttributeSet attrs) {
super(context, attrs);
setOrientation(HORIZONTAL);
setGravity(Gravity.CENTER);
setWeightSum(1.0f);

LayoutInflater.from(context).inflate(R.layout.okcancelbar, this, true);

TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.OkCancelBar, 0, 0);

String text = array.getString(R.styleable.OkCancelBar_okLabel);
if (text == null) text = "Ok";
((Button) findViewById(R.id.okcancelbar_ok)).setText(text);

text = array.getString(R.styleable.OkCancelBar_cancelLabel);
if (text == null) text = "Cancel";
((Button) findViewById(R.id.okcancelbar_cancel)).setText(text);

array.recycle();
}
}

The two buttons are defined in the following XML layout. As you can see, we use the <merge /> tag to add the two buttons directly to the OkCancelBar. Each button is included from the same external XML layout file to make them easier to maintain; we simply override their id:

<merge xmlns:android="http://schemas.android.com/apk/res/android">
<include
layout="@layout/okcancelbar_button"
android:id="@+id/okcancelbar_ok" />

<include
layout="@layout/okcancelbar_button"
android:id="@+id/okcancelbar_cancel" />
</merge>

We have created a flexible and easy to maintain custom view that generates an efficient view hierarchy:

The resulting hierarchy is simple and efficient

The <merge /> tag is extremely useful and can do wonders in your code. However, it suffers from a couple of limitation:

  • <merge /> can only be used as the root tag of an XML layout

  • When inflating a layout starting with a <merge />, you must specify a parent ViewGroup and you must set attachToRoot to true (see the documentation of the inflate() method)

In the next installment of Android Layout Tricks you will learn about ViewStub, a powerful variation of <include /> that can help you further optimize your layouts without sacrificing features.

Download the complete source code of this example.