Pages

Friday, 15 March 2013

Android Browser User-Agent Issues

[This post is by Bart Sears, who manages the Android Browser team. —Tim Bray]

This posting describes some issues when browsing websites with mobile variants using large-form-factor Android devices. This posting will be of interest both to OEMs (with recommendations on how to set the User Agent string for the device) and to web site designers/administrators (with recommendations on how to decide to provide either a mobile version, a desktop version, or a large-form-factor touch device version of the site).

Details

With the advent of Android devices with larger form factors, we’ve been evaluating the best way for web sites to provide a UI appropriate for the various Android devices that are now available to consumers. We have received feedback that consumers using larger-form-factor devices often prefer the “full” or “desktop” version of the site over the “mobile” version. Most websites providing “mobile” versions key off of the HTTP User-Agent header field to determine whether to provide the full site or a mobile version.

While large-form-factor Android devices could use “User Agent Spoofing” to provide a desktop User Agent in the HTTP header, we recommend against this. There may be site customizations needed for Android devices (for example changes in the way that mouseover is used) and the site would be unable to provide these customizations if it receives a spoofed User Agent that did not indicate that this was an Android device.

Currently, Android devices provide the following (in addition to standard info) in the User-Agent: "Android", a version number, a device name, a specific build, Webkit version info, and "Mobile". For example, Froyo on a Nexus One has the following User Agent:

Mozilla/5.0 (Linux; U; Android 2.2.1; en-us; Nexus One Build/FRG83) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1

The "Mobile" string in the User Agent indicates that this device would prefer a version of the website optimized for Mobile (small form factor devices), if available.

We recommend that manufactures of large-form-factor devices (where the user may prefer the standard web site over a mobile optimized version) remove "Mobile" from the User Agent (and keep the rest of the User Agent as currently implemented). Web sites can then key off "Mobile" in the User Agent to decide on which UI version to present to the device. So a large screen device running Froyo would have a User Agent similar to:

Mozilla/5.0 (Linux; U; Android 2.2.1; en-us; device Build/FRG83) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Safari/533.1

Where "device" would be replaced with the actual name of the new device. Sites can continue to use “Android” in the User Agent to optimize for Android specific features and can also key off of “Mobile” to determine which UI to present.

Android at the Game Developer's Conference

Tuesday, March 9 marks the start of the 2010 Game Developers Conference in San Francisco, and Android will be there! There has been a lot of interest about Android from the game development community, and our presence at GDC is intended to provide developers everything they need to get started with the platform. We are hosting several technical sessions and participating in two industry panels.

We also want to meet you and answer your questions about Android game development, so we've set aside time for "office hours." Android team engineers will be on-hand to answer your questions, and if you have a game in development for Android, we'd love to see a demo.

Below, you can see the technical sessions that we're hosting and industry panels that we're participating in. We look forward to seeing you at GDC2010!

Technical sessions

Tuesday, March 9

Bootstrapping Games on Android
Chris Pruett
Everything you need to know about games on Android in 60 minutes.
1:45 PM - 2:45 PM
Room 309, South Hall

Wednesday, March 10

Bring Your Games to Android
Jack Palevich
An in-depth look at writing and porting C++ games using the NDK and a thin Java shell.
10:30 AM - 11:30 AM
Room 302, South Hall

Get the Most out of Android Media APIs
Dave Sparks & Jason Sams
Tips and tricks for optimizing your sound, video, and graphics for compatibility, efficiency, and battery life.
11:45 AM - 12:45 PM
Room 302, South Hall

Android Office Hours
The Android team
Come meet the team, ask us your questions, and show off your games!
3:00 PM - 4:00 PM
Room 302, South Hall

Industry panels

Wednesday, March 10

GamesBeat2010: A sea of mobile devices
Eric Chu
Industry experts weigh in on the future of mobile game development.
4:30 PM - 5:30 PM
Moscone Convention Center

Thursday, March 11

After the iPhone...what?
Dave Sparks
Audio experts discuss the nitty gritty technical details of alternative gaming platforms.
10:30 AM - 11:30 AM
Room 112, North Hall

Android Developer Challenge Judges and Top 50 Details

It's been a busy few weeks here as we've wrapped up the first round of the Android Developer Challenge. We'd like to share a couple pieces of information with you:

  • The full list of judges is now available. It was fun to work with such a diverse group of judges from different companies all around the world.
  • A slide deck of the Android Developer Challenge prize recipients is also available. The deck includes descriptions and screenshots of the 46 recipients who consented to sharing their information and is a great way to get a feel for the quality of apps submitted.

The prize recipients' entries were just the tip of the iceberg in terms of great applications submitted, and we'd like to thank and congratulate everyone who entered the challenge. We look forward to seeing all of the application in the hands of consumers with Android devices.

Thursday, 14 March 2013

Android 4.0 Graphics and Animations

[This post is by Romain Guy and Chet Haase, Android engineers who have been known to collaborate on the subject of graphics, UIs, and animation. You can read more from them on their blogs at curious-creature.org and graphics-geek.blogspot.com. — Tim Bray]

Earlier this year, Android 3.0 launched with a new 2D rendering pipeline designed to support hardware acceleration on tablets. With this new pipeline, all drawing operations performed by the UI toolkit are carried out using the GPU.

You’ll be happy to hear that Android 4.0, Ice Cream Sandwich, brings an improved version of the hardware-accelerated 2D rendering pipeline to phones, starting with Galaxy Nexus.

Enabling hardware acceleration

In Android 4.0 (API level 14), hardware acceleration, for the first time, is on by default for all applications. For applications at lower API levels, you can turn it on by adding android:hardwareAccelerated="true" to the tag in your AndroidManifest.xml.

To learn more about the hardware accelerated 2D rendering pipeline visit the official Android developer guide. This guide explains how to control hardware acceleration at various levels, offers several performance tips and tricks and describes in details the new drawing model.

I also encourage you to watch the Android Hardware Accelerated Rendering talk that we gave at Google I/O 2011.

Introducing TextureView

Applications that need to display OpenGL or video content rely today on a special type of UI element called SurfaceView. This widget works by creating a new window placed behind your application’s window. It then punches a hole through your application’s window to reveal the new window. While this approach is very efficient, since the content of the new window can be refreshed without redrawing the application’s window, it suffers from several important limitations.

Because a SurfaceView’s content does not live in the application’s window, it cannot be transformed (moved, scaled, rotated) efficiently. This makes it difficult to use a SurfaceView inside a ListView or a ScrollView. SurfaceView also cannot interact properly with some features of the UI toolkit such as fading edges or View.setAlpha().

To solve these problems, Android 4.0 introduces a new widget called TextureView that relies on the hardware accelerated 2D rendering pipeline and SurfaceTexture. TextureView offers the same capabilities as SurfaceView but, unlike SurfaceView, behaves as a regular view. You can for instance use a TextureView to display an OpenGL scene or a video stream. The TextureView itself can be animated, scrolled, etc.

The following piece of code creates a TextureView to display the video preview from the default camera. The TextureView itself is rotated 45 degrees and semi-transparent.

public class TextureViewActivity extends Activity implements TextureView.SurfaceTextureListener { private Camera mCamera; private TextureView mTextureView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mTextureView = new TextureView(this); mTextureView.setSurfaceTextureListener(this); setContentView(mTextureView); } @Override public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { mCamera = Camera.open(); Camera.Size previewSize = mCamera.getParameters().getPreviewSize(); mTextureView.setLayoutParams(new FrameLayout.LayoutParams( previewSize.width, previewSize.height, Gravity.CENTER)); try { mCamera.setPreviewTexture(surface); } catch (IOException t) { } mCamera.startPreview();  mTextureView.setAlpha(0.5f); mTextureView.setRotation(45.0f); } @Override public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { // Ignored, the Camera does all the work for us } @Override public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { mCamera.stopPreview(); mCamera.release(); return true; } @Override public void onSurfaceTextureUpdated(SurfaceTexture surface) { // Called whenever a new frame is available and displayed in the TextureView }}

A TextureView can just as easily be used to embed an OpenGL scene in your application. As of Android 4.0, eglCreateWindowSurface() can be used to render into a SurfaceTexture object.

Animation

There were minor improvements in Android 4.0 to some of the new animation facilities that were added in the 3.x releases.

First, if you're new to the new android.animation package and classes added in 3.0 and 3.1, you might want to read Animation in Honeycomb and Introducing ViewPropertyAnimator. These articles discuss the new APIs added in 3.0 that make animation in Android easier, more powerful, and more flexible. The Android 4.0 improvements discussed below are small additions to these core facilities.

Properties

One of the constraints of the Java programming language is the lack of “properties”. There is no way to refer generically to a field or a setter/getter of an object. As long as you know what kind of object you have, this is not a problem, because you then know the set of fields and methods that you can call. But if someone passes you some subclass of Object and you'd like to get or set some value “foo” on it, you're out of luck. You can use reflection or JNI to get access to the foo field/methods, but there is no way to refer directly to a field or a method unless you know the instance type of the object that has that field/method on it.

This is a constraint that the new animation system works within. Its whole job, you might say, is to get and set values on generic objects that it's been told about. If someone wants to animate the alpha property on a View, they tell the system the target object and the name of that field (“alpha”), and the animation system uses JNI to figure out which method(s) act on a field of that name. Basically, it looks for setAlpha() and, sometimes, getAlpha() methods. Then when an animation frame occurs, it calculates the new value and passes it into the setter method that it found.

This seems like a lot of work for what it does, but there's really no way around it. Unless the animation system were specific to View objects, there's no way that it could know that the target object has appropriate setter/getter methods. And even if it did, there's still no way for callers that construct the animations to tell the animator about the property named “alpha”; there are no function handles like there are in other languages, and there's no way to reference a public field either. (I'm ignoring Reflection here, which has Method and Field objects, because this approach requires much more overhead and processing than the simple function/field references of other languages).

If only there were a way to refer to these properties and to get/set them on generic objects...

Now there is. There is a new Property object in the android.util package that does exactly this. This class offers a set() and a get() method. So if someone hands you a Property object, you can safely call the set() and get() methods without knowing anything about the target object and it will do the job. Moreover, it will do it much more efficiently than the current JNI or reflection approaches because it can, depending on the implementation of it, set a field or call a method on the target object directly. For example, the new ALPHA property on View calls setAlpha() on the View object.

The Property class is a generic utility that can be used anywhere, not just in animations. But it's animations that benefit enormously from it, in their ability to handle properties in a type-safe and efficient manner.

For example prior to Android 4.0, you might construct a fade-out animation on some object myView like this:

ObjectAnimator anim = ObjectAnimator.ofFloat(myView, "alpha", 0);

In Android 4.0, you can use the new ALPHA object on View to construct a Property-based animator instead:

ObjectAnimator anim = ObjectAnimator.ofFloat(myView, View.ALPHA, 0);

ViewPropertyAnimator Additions

There were minor API additions to the ViewPropertyAnimator class (introduced in Android 3.1) which make this class more flexible and powerful:

  • cancel(): You can now cancel() a running ViewPropertyAnimator.

  • setStartDelay(): You can now set a startDelay on the ViewPropertyAnimator, just like the startDelay of the other Animator classes.

  • start(): ViewPropertyAnimators start automatically, but they do so on the next animation frame handled. This allows them to collect several requests and bundle them together, which is much more efficient and makes it easier to synchronize multiple animations together. However, if you just want to run a single animation, or want to make sure it starts immediately, at the time of construction, you can call start() to avoid that intervening delay.

LayoutTransition

LayoutTransition (introduced in Android 3.0) continues to provide functionality that makes some kinds of animations easier, specifically when adding, removing, hiding, and showing views. For example, either this snippet in a layout file:

Or this code added at runtime:

 container.setLayoutTransition(new LayoutTransition());

will result in a container that animates the visibility of its children views. So when a view is added to the container, the other children will animate out of the way and then the new one will fade in. Similarly, removing a child from the container will fade it out and then animate the other children around to their final places and sizes.

You can customize the animations and timing behavior of a LayoutTransition object, but the code above allows a very easy way to get reasonable default animation behavior.

One of the constraints in the pre-4.0 version of the class was that it did not account for changes in the bounds of the parent hierarchy. So, for example, if a LinearLayout with horizontal orientation has a layout_width of wrap_content and you want to run a transition that removes an item from that layout, then you might notice the parent snapping to the end size and clipping its children instead of animating all of them into their new positions. The new approach (enabled by default, but disabled by a call to setAnimateParentHierarchy(false)) also animates the layout bounds and scrolling values of the parent layout and its parents, all the way up the view hierarchy. This allows LayoutTransition to account for all layout-related changes due to that view being added or removed from its transitioning container.

Conclusion

The Android 3.0 release saw huge improvements in the visual capabilities of the platform, as we started enabling hardware acceleration and providing new, more flexible animation capabilities. Android 4.0 continues this trend as we continue to work hard on improving the performance, features, and usability of the Android APIs. We’re not done yet, but the enhancements in this release should help you create more exciting Android experiences and applications.