Wednesday, February 9, 2011

Android 2.3.3 Platform, New NFC Capabilities

Several weeks ago we released Android 2.3, which introduced several new forms of communication for developers and users. One of those, Near Field Communications (NFC), let developers get started creating a new class of contactless, proximity-based applications for users.

NFC is an emerging technology that promises exciting new ways to use mobile devices, including ticketing, advertising, ratings, and even data exchange with other devices. We know there’s a strong interest to include these capabilities into many applications, so we’re happy to announce an update to Android 2.3 that adds new NFC capabilities for developers. Some of the features include:

  • A comprehensive NFC reader/writer API that lets apps read and write to almost any standard NFC tag in use today.
  • Advanced Intent dispatching that gives apps more control over how/when they are launched when an NFC tag comes into range.
  • Some limited support for peer-to-peer connection with other NFC devices.

We hope you’ll find these new capabilities useful and we’re looking forward to seeing the innovative apps that you will create using them.

Android 2.3.3 is a small feature release that includes a new API level, 10.
Going forward, we expect most devices shipping with an Android 2.3 platform to run Android 2.3.3 (or later). For an overview of the API changes, see the Android 2.3.3 Version Notes. The Android 2.3.3 SDK platform for development and testing is available through the Android SDK Manager.

Thursday, February 3, 2011

The Android 3.0 Fragments API

[This post is by Dianne Hackborn, a Software Engineer who sits very near the exact center of everything Android. — Tim Bray]

An important goal for Android 3.0 is to make it easier for developers to write applications that can scale across a variety of screen sizes, beyond the facilities already available in the platform:

  • Since the beginning, Android’s UI framework has been designed around the use of layout managers, allowing UIs to be described in a way that will adjust to the space available. A common example is a ListView whose height changes depending on the size of the screen, which varies a bit between QVGA, HVGA, and WVGA aspect ratios.

  • Android 1.6 introduced a new concept of screen densities, making it easy for apps to scale between different screen resolutions when the screen is about the same physical size. Developers immediately started using this facility when higher-resolution screens were introduced, first on Droid and then on other phones.

  • Android 1.6 also made screen sizes accessible to developers, classifying them into buckets: “small” for QVGA aspect ratios, “normal” for HVGA and WVGA aspect ratios, and “large” for larger screens. Developers can use the resource system to select between different layouts based on the screen size.

The combination of layout managers and resource selection based on screen size goes a long way towards helping developers build scalable UIs for the variety of Android devices we want to enable. As a result, many existing handset applications Just Work under Honeycomb on full-size tablets, without special compatibility modes, with no changes required. However, as we move up into tablet-oriented UIs with 10-inch screens, many applications also benefit from a more radical UI adjustment than resources can easily provide by themselves.

Introducing the Fragment

Android 3.0 further helps applications adjust their interfaces with a new class called Fragment. A Fragment is a self-contained component with its own UI and lifecycle; it can be-reused in different parts of an application’s user interface depending on the desired UI flow for a particular device or screen.

In some ways you can think of a Fragment as a mini-Activity, though it can’t run independently but must be hosted within an actual Activity. In fact the introduction of the Fragment API gave us the opportunity to address many of the pain points we have seen developers hit with Activities, so in Android 3.0 the utility of Fragment extends far beyond just adjusting for different screens:

  • Embedded Activities via ActivityGroup were a nice idea, but have always been difficult to deal with since Activity is designed to be an independent self-contained component instead of closely interacting with other activities. The Fragment API is a much better solution for this, and should be considered as a replacement for embedded activities.

  • Retaining data across Activity instances could be accomplished through Activity.onRetainNonConfigurationInstance(), but this is fairly klunky and non-obvious. Fragment replaces that mechanism by allowing you to retain an entire Fragment instance just by setting a flag.

  • A specialization of Fragment called DialogFragment makes it easy to show a Dialog that is managed as part of the Activity lifecycle. This replaces Activity’s “managed dialog” APIs.

  • Another specialization of Fragment called ListFragment makes it easy to show a list of data. This is similar to the existing ListActivity (with a few more features), but should reduce the common question about how to show a list with some other data.

  • The information about all fragments currently attached to an activity is saved for you by the framework in the activity’s saved instance state and restored for you when it restarts. This can greatly reduce the amount of state save and restore code you need to write yourself.

  • The framework has built-in support for managing a back-stack of Fragment objects, making it easy to provide intra-activity Back button behavior that integrates the existing activity back stack. This state is also saved and restored for you automatically.

Getting started

To whet your appetite, here is a simple but complete example of implementing multiple UI flows using fragments. We first are going to design a landscape layout, containing a list of items on the left and details of the selected item on the right. This is the layout we want to achieve:

The code for this activity is not interesting; it just calls setContentView() with the given layout:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">

<fragment class="com.example.android.apis.app.TitlesFragment"
android:id="@+id/titles" android:layout_weight="1"
android:layout_width="0px"
android:layout_height="match_parent" />

<FrameLayout android:id="@+id/details" android:layout_weight="1"
android:layout_width="0px"
android:layout_height="match_parent" />

</LinearLayout>

You can see here our first new feature: the <fragment> tag allows you to automatically instantiate and install a Fragment subclass into your view hierarchy. The fragment being implemented here derives from ListFragment, displaying and managing a list of items the user can select. The implementation below takes care of displaying the details of an item either in-place or as a separate activity, depending on the UI layout. Note how changes to fragment state (the currently shown details fragment) are retained across configuration changes for you by the framework.

public static class TitlesFragment extends ListFragment {
boolean mDualPane;
int mCurCheckPosition = 0;

@Override
public void onActivityCreated(Bundle savedState) {
super.onActivityCreated(savedState);

// Populate list with our static array of titles.
setListAdapter(new ArrayAdapter<String>(getActivity(),
R.layout.simple_list_item_checkable_1,
Shakespeare.TITLES));

// Check to see if we have a frame in which to embed the details
// fragment directly in the containing UI.
View detailsFrame = getActivity().findViewById(R.id.details);
mDualPane = detailsFrame != null
&& detailsFrame.getVisibility() == View.VISIBLE;

if (savedState != null) {
// Restore last state for checked position.
mCurCheckPosition = savedState.getInt("curChoice", 0);
}

if (mDualPane) {
// In dual-pane mode, list view highlights selected item.
getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
// Make sure our UI is in the correct state.
showDetails(mCurCheckPosition);
}
}

@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("curChoice", mCurCheckPosition);
}

@Override
public void onListItemClick(ListView l, View v, int pos, long id) {
showDetails(pos);
}

/**
* Helper function to show the details of a selected item, either by
* displaying a fragment in-place in the current UI, or starting a
* whole new activity in which it is displayed.
*/
void showDetails(int index) {
mCurCheckPosition = index;

if (mDualPane) {
// We can display everything in-place with fragments.
// Have the list highlight this item and show the data.
getListView().setItemChecked(index, true);

// Check what fragment is shown, replace if needed.
DetailsFragment details = (DetailsFragment)
getFragmentManager().findFragmentById(R.id.details);
if (details == null || details.getShownIndex() != index) {
// Make new fragment to show this selection.
details = DetailsFragment.newInstance(index);

// Execute a transaction, replacing any existing
// fragment with this one inside the frame.
FragmentTransaction ft
= getFragmentManager().beginTransaction();
ft.replace(R.id.details, details);
ft.setTransition(
FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();
}

} else {
// Otherwise we need to launch a new activity to display
// the dialog fragment with selected text.
Intent intent = new Intent();
intent.setClass(getActivity(), DetailsActivity.class);
intent.putExtra("index", index);
startActivity(intent);
}
}
}

For this first screen we need an implementation of DetailsFragment, which simply shows a TextView containing the text of the currently selected item.

public static class DetailsFragment extends Fragment {
/**
* Create a new instance of DetailsFragment, initialized to
* show the text at 'index'.
*/
public static DetailsFragment newInstance(int index) {
DetailsFragment f = new DetailsFragment();

// Supply index input as an argument.
Bundle args = new Bundle();
args.putInt("index", index);
f.setArguments(args);

return f;
}

public int getShownIndex() {
return getArguments().getInt("index", 0);
}

@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
if (container == null) {
// Currently in a layout without a container, so no
// reason to create our view.
return null;
}

ScrollView scroller = new ScrollView(getActivity());
TextView text = new TextView(getActivity());
int padding = (int)TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
4, getActivity().getResources().getDisplayMetrics());
text.setPadding(padding, padding, padding, padding);
scroller.addView(text);
text.setText(Shakespeare.DIALOGUE[getShownIndex()]);
return scroller;
}
}

It is now time to add another UI flow to our application. When in portrait orientation, there is not enough room to display the two fragments side-by-side, so instead we want to show only the list like this:

With the code shown so far, all we need to do here is introduce a new layout variation for portrait screens like so:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment class="com.example.android.apis.app.TitlesFragment"
android:id="@+id/titles"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>

The TitlesFragment will notice that it doesn’t have a container in which to show its details, so show only its list. When you tap on an item in the list we now need to go to a separate activity in which the details are shown.

With the DetailsFragment already implemented, the implementation of the new activity is very simple because it can reuse the same DetailsFragment from above:

public static class DetailsActivity extends FragmentActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

if (getResources().getConfiguration().orientation
== Configuration.ORIENTATION_LANDSCAPE) {
// If the screen is now in landscape mode, we can show the
// dialog in-line so we don't need this activity.
finish();
return;
}

if (savedInstanceState == null) {
// During initial setup, plug in the details fragment.
DetailsFragment details = new DetailsFragment();
details.setArguments(getIntent().getExtras());
getSupportFragmentManager().beginTransaction().add(
android.R.id.content, details).commit();
}
}
}

Put that all together, and we have a complete working example of an application that fairly radically changes its UI flow based on the screen it is running on, and can even adjust it on demand as the screen configuration changes.

This illustrates just one way fragments can be used to adjust your UI. Depending on your application design, you may prefer other approaches. For example, you could put your entire application in one activity in which you change the fragment structure as its state changes; the fragment back stack can come in handy in this case.

More information on the Fragment and FragmentManager APIs can be found in the Android 3.0 SDK documentation. Also be sure to look at the ApiDemos app under the Resources tab, which has a variety of Fragment demos covering their use for alternative UI flow, dialogs, lists, populating menus, retaining across activity instances, the back stack, and more.

Fragmentation for all!

For developers starting work on tablet-oriented applications designed for Android 3.0, the new Fragment API is useful for many design situations that arise from the larger screen. Reasonable use of fragments should also make it easier to adjust the resulting application’s UI to new devices in the future as needed -- for phones, TVs, or wherever Android appears.

However, the immediate need for many developers today is probably to design applications that they can provide for existing phones while also presenting an improved user interface on tablets. With Fragment only being available in Android 3.0, their shorter-term utility is greatly diminished.

To address this, we plan to have the same fragment APIs (and the new LoaderManager as well) described here available as a static library for use with older versions of Android; we’re trying to go right back to 1.6. In fact, if you compare the code examples here to those in the Android 3.0 SDK, they are slightly different: this code is from an application using an early version of the static library fragment classes which is running, as you can see on the screenshots, on Android 2.3. Our goal is to make these APIs nearly identical, so you can start using them now and, at whatever point in the future you switch to Android 3.0 as your minimum version, move to the platform’s native implementation with few changes in your app.

We don’t have a firm date for when this library will be available, but it should be relatively soon. In the meantime, you can start developing with fragments on Android 3.0 to see how they work, and most of that effort should be transferable.

Wednesday, February 2, 2011

New Merchandising and Billing Features on Android Market

[This post is by Eric Chu, Android Developer Ecosystem. —Dirk Dougherty]


Following on last week’s announcement of the Android 3.0 Preview SDK, I’d like to share some more good news with you about three important new features on Android Market.

Android Market on the Web


Starting today, we have extended Android Market client from mobile devices to every desktop. Anyone can now easily find and share applications from their favorite browser. Once users select an application they want, it will automatically be downloaded to their Android-powered devices over-the-air.

Android Market on the Web dramatically expands the discoverability of applications through a rich browsing experience, suggestion-guided searching, deep linking, social sharing, and other merchandising features.

We are releasing the initial version of Android Market on the Web in English and will be extending it to other languages in the weeks ahead.

If you have applications published on Android Market, we encourage you to visit the site and review how they are presented. If you need additional information about what assets you should provide, please visit Android Market Help Center.

You can access Android Market on the Web at:

http://market.android.com/

Buyer’s Currency

Android Market lets you sell applications to users in 32 buyer countries around the world. Today we’re introducing Buyer’s Currency to give you more control over how you price your products across those countries. This feature lets you price your applications differently in each market and improves the purchase experience for buyers by showing prices in their home currencies.

We’ll be rolling out Buyer’s Currency in stages, starting with developers in the U.S. and reaching developers in other countries shortly after. We anticipate it will take approximately four months for us to complete this process.

We encourage you to watch for the appearance of new Buyer’s Currency options in the Android Market publishing console and set prices as soon as possible.

In-app Billing

After months of hard work by the Android Market team, I am extremely pleased to announce the arrival of In-app Billing on Android Market. This new service gives developers more ways to monetize their applications through new billing models including try-and-buy, virtual goods, upgrades, and more.

The In-app Billing service manages billing transactions between apps and users, providing a consistent purchasing experience with familiar forms of payment across all apps. At the same time, it gives you full control over how your digital goods are purchased and tracked. You can let Android Market manage and track the purchases for you or you can integrate with your own back-end service to verify and track purchases in the way that's best for your app.

We’ll be launching In-app Billing in stages. Beginning today, we are providing detailed documentation and a sample application to help you get familiar with the service. Over the next few weeks we’ll be rolling out updates to the Android Market client that will enable you to test against the In-app Billing service. Before the end of this quarter, the service will be live for users, to enable you to start monetizing your applications with this new capability. For complete information about the rollout, see the release information in the In-app Billing documentation.

Helping developers merchandise and monetize their products is a top priority for the Android Market team. We will continue to work hard to to make it the best marketplace for your to distribute your products. For now, we hope you’ll check out these new features to help you better deliver your products through Android Market.

Wednesday, January 26, 2011

Android 3.0 Platform Preview and Updated SDK Tools

Android 3.0 (Honeycomb) is a new version of the Android platform that is designed from the ground up for devices with larger screen sizes, particularly tablets. It introduces a new “holographic” UI theme and an interaction model that builds on the things people love about Android — multitasking, notifications, widgets, and others — and adds many new features as well.

Besides the user-facing features it offers, Android 3.0 is also specifically designed to give developers the tools and capabilities they need to create great applications for tablets and similar devices, together with the flexibility to adapt existing apps to the new UI while maintaining compatibility with earlier platform versions and other form-factors.

Today, we are releasing a preview of the Android 3.0 SDK, with non-final APIs and system image, to allow developers to start testing their existing applications on the tablet form-factor and begin getting familiar with the new UI patterns, APIs, and capabilties that will be available in Android 3.0.

Here are some of the highlights:

UI framework for creating great apps for larger screen devices: Developers can use a new UI components, new themes, richer widgets and notifications, drag and drop, and other new features to create rich and engaging apps for users on larger screen devices.

High-performance 2D and 3D graphics: A new property-based animation framework lets developers add great visual effects to their apps. A built-in GL renderer lets developers request hardware-acceleration of common 2D rendering operations in their apps, across the entire app or only in specific activities or views. For adding rich 3D scenes, developers take advantage of a new 3D graphics engine called Renderscript.

Support for multicore processor architectures: Android 3.0 is optimized to run on either single- or dual-core processors, so that applications run with the best possible performance.

Rich multimedia: New multimedia features such as HTTP Live streaming support, a pluggable DRM framework, and easy media file transfer through MTP/PTP, give developers new ways to bring rich content to users.

New types of connectivity: New APIs for Bluetooth A2DP and HSP let applications offer audio streaming and headset control. Support for Bluetooth insecure socket connection lets applications connect to simple devices that may not have a user interface.

Enhancements for enterprise: New administrative policies, such as for encrypted storage and password expiration, help enterprise administrators manage devices more effectively.

For an complete overview of the new user and developer features, see the Android 3.0 Platform Highlights.

Additionally, we are releasing updates to our SDK Tools (r9), NDK (r5b), and ADT Plugin for Eclipse (9.0.0). Key features include:

  • UI Builder improvements in the ADT Plugin:
    • Improved drag-and-drop in the editor, with better support for included layouts.
    • In-editor preview of objects animated with the new animation framework.
    • Visualization of UI based on any version of the platform. independent of project target. Improved rendering, with better support for custom views.

To find out how to get started developing or testing applications using the Android 3.0 Preview SDK, see the Preview SDK Introduction. Details about the changes in the latest versions of the tools are available on the SDK Tools, the ADT Plugin, and NDK pages on the site.

Note that applications developed with the Android 3.0 Platform Preview cannot be published on Android Market. We’ll be releasing a final SDK in the weeks ahead that you can use to build and publish applications for Android 3.0.

Thursday, January 20, 2011

Processing Ordered Broadcasts

[This post is by Bruno Albuquerque, an engineer who works in Google’s office in Belo Horizonte, Brazil. —Tim Bray]

One of the things that I find most interesting and powerful about Android is the concept of broadcasts and their use through the BroadcastReceiver class (from now on, we will call implementations of this class “receivers”). As this document is about a very specific usage scenario for broadcasts, I will not go into detail about how they work in general, so I recommend reading the documentation about them in the Android developer site. For the purpose of this document, it is enough to know that broadcasts are generated whenever something interesting happens in the system (connectivity changes, for example) and you can register to be notified whenever one (or more) of those broadcasts are generated.

While developing Right Number, I noticed that some developers who create receivers for ordered broadcasts do not seem to be fully aware of what is the correct way to do it. This suggests that the documentation could be improved; in any case, things often still work(although it is mostly by chance than anything else).

Non-ordered vs. Ordered Broadcasts

In non-ordered mode, broadcasts are sent to all interested receivers “at the same time”. This basically means that one receiver can not interfere in any way with what other receivers will do neither can it prevent other receivers from being executed. One example of such broadcast is the ACTION_BATTERY_LOW one.

In ordered mode, broadcasts are sent to each receiver in order (controlled by the android:priority attribute for the intent-filter element in the manifest file that is related to your receiver) and one receiver is able to abort the broadcast so that receivers with a lower priority would not receive it (thus never execute). An example of this type of broadcast (and one that will be discussing in this document) is the ACTION_NEW_OUTGOING_CALL one.

Ordered Broadcast Usage

As mentioned earlier in this document, the ACTION_NEW_OUTGOING_CALL broadcast is an ordered one. This broadcast is sent whenever the user tries to initiate a phone call. There are several reasons that one would want to be notified about this, but we will focus on only 2:

  • To be able to reject an outgoing call;

  • To be able to rewrite the number before it is dialed.

In the first case, an app may want to control what numbers can be dialed or what time of the day numbers can be dialed. Right Number does what is described in the second case so it can be sure that a number is always dialed correctly no matter where in the world you are.

A naive BroadcastReceiver implementation would be something like this (note that you should associate this receiver with the ACTION_NEW_OUTGOING_CALL broadcast in the manifest file for your application):

public class CallReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// Original phone number is in the EXTRA_PHONE_NUMBER Intent extra.
String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);

if (shouldCancel(phoneNumber)) {
// Cancel our call.
setResultData(null);
} else {
// Use rewritten number as the result data.
setResultData(reformatNumber(phoneNumber));
}
}

The receiver either cancels the broadcast (and the call) or reformats the number to be dialed. If this is the only receiver that is active for the ACTION_NEW_OUTGOING_CALL broadcast, this will work exactly as expected. The problem arrises when you have, for example, a receiver that runs before the one above (has a higher priority) and that also changes the number as instead of looking at previous results of other receivers, we are just using the original (unmodified) number!

Doing It Right

With the above in mind, here is how the code should have been written in the first place:

public class CallReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// Try to read the phone number from previous receivers.
String phoneNumber = getResultData();

if (phoneNumber == null) {
// We could not find any previous data. Use the original phone number in this case.
phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
}

if (shouldCancel(phoneNumber)) {
// Cancel our call.
setResultData(null);
} else {
// Use rewritten number as the result data.
setResultData(reformatNumber(phoneNumber));
}
}

We first check if we have any previous result data (which would be generated by a receiver with a higher priority) and only if we can not find it we use the phone number in the EXTRA_PHONE_NUMBER intent extra.

How Big Is The Problem?

We have actually observed phones with a priority 0 receiver for the NEW_OUTGOING_CALL intent installed out of the box (this will be the last one that is called after all others) that completely ignores previous result data which means that, in effect, they disable any useful processing of ACTION_NEW_OUTGOING_CALL (other than canceling the call, which would still work). The only workaround for this is to also run your receiver at priority 0, which works due to particularities of running 2 receivers at the same priority but, by doing that, you break one of the few explicit rules for processing outgoing calls:

“For consistency, any receiver whose purpose is to prohibit phone calls should have a priority of 0, to ensure it will see the final phone number to be dialed. Any receiver whose purpose is to rewrite phone numbers to be called should have a positive priority. Negative priorities are reserved for the system for this broadcast; using them may cause problems.”

Conclusion

There are programs out there that do not play well with others. Urge any developers of such programs to read this post and fix their code. This will make Android better for both developers and users.

Notes About Priorities

  • For the NEW_OUTGOING_CALL intent, priority 0 should only be used by receivers that want to reject calls. This is so it can see changes from other receivers before deciding to reject the call or not.

  • Receivers that have the same priority will also be executed in order, but the order in this case is undefined.

  • Use non-negative priorities only. Negative ones are valid but will result in weird behavior most of the time.

Thursday, January 13, 2011

Have Androids. Will Travel.

[The first part of this post is by Reto Meier. —Tim Bray]

From c-base in Berlin to the Ice Bar in Stockholm, from four courses of pasta in Florence to beer and pretzels in Munich, and from balalikas in Moscow to metal cage mind puzzles in Prague - one common theme was the enthusiasm and quality of the Android developers in attendance. You guys are epic.

For those of you who couldn't join us, we're in the middle of posting all the sessions we presented during this most recent world tour. Stand by for links.

Droidcon UK

We kicked off our conference season at Droidcon UK, an Android extravaganza consisting of a bar camp on day 1 and formal sessions on day 2. It was the perfect place for the Android developer relations team to get together and kick off three straight weeks of Google Developer Days, GTUG Hackathons, and Android Developer Labs.

Android Developer Labs

The first of our Android Developer Labs was a return to Berlin: home to c-base (a place we never got tired of) and the Beuth Hochschule für Technik Berlin. This all day event cost me my voice, but attracted nearly 300 developers (including six teams who battled it out to win a Lego Mindstorm for best app built on the day.)

Next stop was Florence which played host to our first Italian ADL after some fierce campaigning by local Android developers. 160 developers from all over Italy joined us in beautiful Florence where the Firenze GTUG could not have been more welcoming. An afternoon spent with eager developers followed up by an evening of real Italian pasta - what's not to love?

From the warmth of Florence to the snow of Stockholm where we joined the Stockholm GTUG for a special Android themed event at Bwin Games. After a brief introduction we split into six breakout sessions before the attendees got down to some serious hacking to decide who got to bring home the Mindstorm kit.

Google Developer Days

The Google Developer Days are always a highlight on my conference schedule, and this year's events were no exception. It's a unique opportunity for us to meet with a huge number of talented developers - over 3,000 in Europe alone. Each event featured a dedicated Android track with six sessions designed to help Android developers improve their skills.

It was our first time in Munich where we played host to 1200 developers from all over Germany. If there was any doubt we'd come to the right place, the hosting of the Blinkendroid Guinness World Record during the after-party soon dispelled it.

Moscow and Prague are always incredible places to visit. The enthusiasm of the nearly 2,500 people who attended is the reason we do events like these. You can watch the video for every Android session from the Prague event and check out the slides for each of the Russian sessions too.

GTUG Hackathons

With everyone in town for the GDDs we wanted to make the most it. Working closely with the local GTUGs, the Android and Chrome teams held all-day hackathon bootcamps in each city the day before the big event.

It was a smaller crowd in Moscow, but that just made the competition all the more fierce. So much so that we had to create a new Android app just for the purpose of measuring the relative volume of applause in order to choose a winner.

If a picture is a thousand words, this video of the Prague Hackathon in 85 seconds will describe the event far better than I ever could. What the video doesn't show is that the winners of "best app of the day" in Prague had never developed for Android before.

In each city we were blown away by the enthusiasm and skill on display. With so many talented, passionate developers working on Android it's hard not to be excited by what we'll find on the Android Market next. In the mean time, keep coding; we hope to be in your part of the world soon.

On To South America

[Thanks, Reto. This is Tim again. The South American leg actually happened before the Eurotour, but Reto got his writing done first, so I'll follow up here.]

We did more or less the same set of things in South America immediately before Reto’s posse fanned out across Europe. Our events were in São Paulo, Buenos Aires, and Santiago; we were trying to teach people about Android and I hope we succeeded. On the other hand, I know that we learned lots of things. Here are a few of them:

  • Wherever we went, we saw strange (to us) new Android devices. Here’s a picture of a Brazilian flavor of the Samsung Galaxy S, which comes with a fold-out antenna and can get digital TV off the air. If you’re inside you might need to be near a window, but the picture quality is fantastic.

  • There’s a conventional wisdom about putting on free events: Of the people who register, only a certain percentage will show up. When it comes to Android events in South America, the certain-percentage part is wrong. As a result, we dealt with overcrowded rooms and overflow arrangements all over the place. I suppose this is a nice problem to have, but we still feel sorry about some of the people who ended up being overcrowded and overflowed.

  • Brazilians laugh at themselves, saying they’re always late. (Mind you, I’ve heard Indians and Jews and Irish people poke the same fun at themselves, so I suspect lateness may be part of the human condition). Anyhow, Brazilians are not late for Android events; when we showed up at the venue in the grey light of dawn to start setting up, they were already waiting outside.

  • I enjoyed doing the hands-on Android-101 workshops (I’ve included a picture of one), but I’m not sure Googlers need to be doing any more of those. Wherever you go, there’s now a community of savvy developers who can teach each other through the finer points of getting the SDK installed and working and “Hello World” running.

  • Brazil and Argentina and Chile aren’t really like each other. But each has its own scruffy-open-source-geek contingent that likes to get together, and Android events are a good opportunity. I felt totally at home drinking coffee with these people and talking about programming languages and screen densities and so on, even when we had to struggle our way across language barriers.

The people were so, so, warm-hearted and welcoming and not shy in the slightest and I can’t think about our tour without smiling. A big thank-you to all the South-American geeks and hackers and startup cowboys; we owe you a return visit.

Tuesday, January 11, 2011

Gingerbread NDK Awesomeness

[This post is by Chris Pruett, an outward-facing Androider who focuses on the world of games. —Tim Bray]

We released the first version of the Native Development Kit, a development toolchain for building shared libraries in C or C++ that can be used in conjunction with Android applications written in the Java programming language, way back in July of 2009. Since that initial release we’ve steadily improved support for native code; key features such as OpenGL ES support, debugging capabilities, multiple ABI support, and access to bitmaps in native code have arrived with each NDK revision. The result has been pretty awesome: we’ve seen huge growth in certain categories of performance-critical applications, particularly 3D games.

These types of applications are often impractical via Dalvik due to execution speed requirements or, more commonly, because they are based on engines already developed in C or C++. Early on we noted a strong relationship between the awesomeness of the NDK and the awesomeness of the applications that it made possible; at the limit of this function is obviously infinite awesomeness (see graph, right).

With the latest version of the NDK we intend to further increase the awesomeness of your applications, this time by a pretty big margin. With NDK r5, we’re introducing new APIs that will allow you to do more from native code. In fact, with these new tools, applications targeted at Gingerbread or later can be implemented entirely in C++; you can now build an entire Android application without writing a single line of Java.

Of course, access to the regular Android API still requires Dalvik, and the VM is still present in native applications, operating behind the scenes. Should you need to do more than the NDK interfaces provide, you can always invoke Dalvik methods via JNI. But if you prefer to work exclusively in C++, the NDK r5 will let you build a main loop like this:

void android_main(struct android_app* state) {
// Make sure glue isn't stripped.
app_dummy();

// loop waiting for stuff to do.
while (1) {
// Read all pending events.
int ident;
int events;
struct android_poll_source* source;

// Read events and draw a frame of animation.
if ((ident = ALooper_pollAll(0, NULL, &events,
(void**)&source)) >= 0) {
// Process this event.
if (source != NULL) {
source->process(state, source);
}
}
// draw a frame of animation
bringTheAwesome();
}
}

(For a fully working example, see the native-activity sample in NDK/samples/native-activity and the NativeActivity documentation.)

In addition to fully native applications, the latest NDK lets you play sound from native code (via the OpenSL ES API, an open standard managed by Khronos, which also oversees OpenGL ES), handle common application events (life cycle, touch and key events, as well as sensors), control windows directly (including direct access to the window’s pixel buffer), manage EGL contexts, and read assets directly out of APK files. The latest NDK also comes with a prebuilt version of STLport, making it easier to bring STL-reliant applications to Android. Finally, r5 adds backwards-compatible support for RTTI, C++ exceptions, wchar_t, and includes improved debugging tools. Clearly, this release represents a large positive ∆awesome.

We worked hard to increase the utility of the NDK for this release because you guys, the developers who are actually out there making the awesome applications, told us you needed it. This release is specifically designed to help game developers continue to rock; with Gingerbread and the NDK r5, it should now be very easy to bring games written entirely in C and C++ to Android with minimal modification. We expect the APIs exposed by r5 to also benefit a wide range of media applications; access to a native sound buffer and the ability to write directly to window surfaces makes it much easier for applications implementing their own audio and video codecs to achieve maximum performance. In short, this release addresses many of the requests we’ve received over the last year since the first version of the NDK was announced.

We think this is pretty awesome and hope you do too.