USE ANDROID

Android Aplication, all about android

New Tools For Managing Screen Sizes

[This post is by Dianne Hackborn and a supporting cast of thousands; Dianne’s fingerprints can be found all over the Android Application Framework — Tim Bray]



Android 3.2 includes new tools for supporting devices with a wide range of screen sizes. One important result is better support for a new size of screen; what is typically called a “7-inch” tablet. This release also offers several new APIs to simplify developers’ work in adjusting to different screen sizes.

This a long post. We start by discussing the why and how of Android “dp” arithmetic, and the finer points of the screen-size buckets. If you know all that stuff, you can skip down to “Introducing Numeric Selectors” to read about what’s new. We also provide our recommendations for how you can do layout selection in apps targeted at Android 3.2 and higher in a way that should allow you to support the maximum number of device geometries with the minimum amount of effort.
Of course, the official write-up on Supporting Multiple Screens is also required reading for people working in this space.

Understanding Screen Densities and the “dp”

Resolution is the actual number of pixels available in the display, density is how many pixels appear within a constant area of the display, and size is the amount of physical space available for displaying your interface. These are interrelated: increase the resolution and density together, and size stays about the same. This is why the 320x480 screen on a G1 and 480x800 screen on a Droid are both the same screen size: the 480x800 screen has more pixels, but it is also higher density.
To remove the size/density calculations from the picture, the Android framework works wherever possible in terms of "dp" units, which are corrected for density. In medium-density ("mdpi") screens, which correspond to the original Android phones, physical pixels are identical to dp's; the devices’ dimensions are 320x480 in either scale. A more recent phone might have physical-pixel dimensions of 480x800 but be a high-density device. The conversion factor from hdpi to mdpi in this case is 1.5, so for a developer's purposes, the device is 320x533 in dp's.

Screen-size Buckets

Android has included support for three screen-size “buckets” since 1.6, based on these “dp” units: “normal” is currently the most popular device format (originally 320x480, more recently higher-density 480x800); “small” is for smaller screens, and “large” is for “substantially larger” screens. Devices that fall in the “large” bucket include the Dell Streak and original 7” Samsung Galaxy Tab. Android 2.3 introduced a new bucket size “xlarge”, in preparation for the approximately-10” tablets (such as the Motorola Xoom) that Android 3.0 was designed to support.
The definitions are:
  • xlarge screens are at least 960dp x 720dp.

  • large screens are at least 640dp x 480dp.

  • normal screens are at least 470dp x 320dp.

  • small screens are at least 426dp x 320dp. (Android does not currently support screens smaller than this.)
Here are some more examples of how this works with real screens:
  • A QVGA screen is 320x240 ldpi. Converting to mdpi (a 4/3 scaling factor) gives us 426dp x 320dp; this matches the minimum size above for the small screen bucket.

  • The Xoom is a typical 10” tablet with a 1280x800 mdpi screen. This places it into the xlarge screen bucket.

  • The Dell Streak is a 800x480 mdpi screen. This places it into the bottom of the large size bucket.

  • A typical 7” tablet has a 1024x600 mdpi screen. This also counts as a large screen.

  • The original Samsung Galaxy Tab is an interesting case. Physically it is a 1024x600 7” screen and thus classified as “large”. However the device configures its screen as hdpi, which means after applying the appropriate ⅔ scaling factor the actual space on the screen is 682dp x 400dp. This actually moves it out of the “large” bucket and into a “normal” screen size. The Tab actually reports that it is “large”; this was a mistake in the framework’s computation of the size for that device that we made. Today no devices should ship like this.

Issues With Buckets

Based on developers’ experience so far, we’re not convinced that this limited set of screen-size buckets gives developers everything they need in adapting to the increasing variety of Android-device shapes and sizes. The primary problem is that the borders between the buckets may not always correspond to either devices available to consumers or to the particular needs of apps.
The “normal” and “xlarge” screen sizes should be fairly straightforward as a target: “normal” screens generally require single panes of information that the user moves between, while “xlarge” screens can comfortably hold multi-pane UIs (even in portrait orientation, with some tightening of the space).
The “small” screen size is really an artifact of the original Android devices having 320x480 screens. 240x320 screens have a shorter aspect ratio, and applications that don’t take this into account can break on them. These days it is good practice to test user interfaces on a small screen to ensure there are no serious problems.
The “large” screen size has been challenging for developers — you will notice that it encompases everything from the Dell Streak to the original Galaxy Tab to 7" tablets in general. Different applications may also reasonably want to take different approaches to these two devices; it is also quite reasonable to want to have different behavior for landscape vs. portrait large devices because landscape has plenty of space for a multi-pane UI, while portrait may not.

Introducing Numeric Selectors

Android 3.2 introduces a new approach to screen sizes, with the goal of making developers' lives easier. We have defined a set of numbers describing device screen sizes, which you can use to select resources or otherwise adjust your UI. We believe that using these will not only reduce developers’ workloads, but future-proof their apps significantly.
The numbers describing the screen size are all in “dp” units (remember that your layout dimensions should also be in dp units so that the system can adjust for screen density). They are:
  • width dp: the current width available for application layout in “dp” units; changes when the screen switches orientation between landscape and portrait.

  • height dp: the current height available for application layout in “dp” units; also changes when the screen switches orientation.

  • smallest width dp: the smallest width available for application layout in “dp” units; this is the smallest width dp that you will ever encounter in any rotation of the display.
Of these, smallest width dp is the most important. It replaces the old screen-size buckets with a continuous range of numbers giving the effective size. This number is based on width because that is fairly universally the driving factor in designing a layout. A UI will often scroll vertically, but have fairly hard constraints on the minimum space it needs horizontally; the available width is also the key factor in determining whether to use a phone-style one-pane layout or tablet-style multi-pane layout.
Typical numbers for screen width dp are:
  • 320: a phone screen (240x320 ldpi, 320x480 mdpi, 480x800 hdpi, etc).

  • 480: a tweener tablet like the Streak (480x800 mdpi).

  • 600: a 7” tablet (600x1024).

  • 720: a 10” tablet (720x1280, 800x1280, etc).

Using the New Selectors

When you are designing your UI, the main thing you probably care about is where you switch between a phone-style UI and a tablet-style multi-pane UI. The exact point of this switch will depend on your particular design — maybe you need a full 720dp width for your tablet layout, maybe 600dp is enough, or 480dp, or even some other number between those. Either pick a width and design to it; or after doing your design, find the smallest width it supports.
Now you can select your layout resources for phones vs. tablets using the number you want. For example, if 600dp is the smallest width for your tablet UI, you can do this:
res/layout/main_activity.xml           # For phones
res/layout-sw600dp/main_activity.xml   # For tablets
For the rare case where you want to further customize your UI, for example for 7” vs. 10” tablets, you can define additional smallest widths:
res/layout/main_activity.xml           # For phones
res/layout-sw600dp/main_activity.xml   # For 7” tablets
res/layout-sw720dp/main_activity.xml   # For 10” tablets
Android will pick the resource that is closest to the device’s “smallest width,” without being larger; so for a hypothetical 700dp x 1200dp tablet, it would pick layout-sw600dp.
If you want to get fancier, you can make a layout that can change when the user switches orientation to the one that best fits in the current available width. This can be of particular use for 7” tablets, where a multi-pane layout is a very tight fit in portrait::
res/layout/main_activity.xml          # Single-pane
res/layout-w600dp/main_activity.xml   # Multi-pane when enough width
Or the previous three-layout example could use this to switch to the full UI whenever there is enough width:
res/layout/main_activity.xml                 # For phones
res/layout-sw600dp/main_activity.xml         # Tablets
res/layout-sw600dp-w720dp/main_activity.xml  # Large width
In the setup above, we will always use the phone layout for devices whose smallest width is less than 600dp; for devices whose smallest width is at least 600dp, we will switch between the tablet and large width layouts depending on the current available width.
You can also mix in other resource qualifiers:
res/layout/main_activity.xml                 # For phones
res/layout-sw600dp/main_activity.xml         # Tablets
res/layout-sw600dp-port/main_activity.xml    # Tablets when portrait

Selector Precedence

While it is safest to specify multiple configurations like this to avoid potential ambiguity, you can also take advantage of some subtleties of resource matching. For example, the order that resource qualifiers must be specified in the directory name (documented in Providing Resources) is also the order of their “importance.” Earlier ones are more important than later ones. You can take advantage of this to, for example, easily have a landscape orientation specialization for your default layout:
res/layout/main_activity.xml                 # For phones
res/layout-land/main_activity.xml            # For phones when landscape
res/layout-sw600dp/main_activity.xml         # Tablets
In this case when running on a tablet that is using landscape orientation, the last layout will be used because the “swNNNdp” qualifier is a better match than “port”.

Combinations and Versions

One final thing we need to address is specifying layouts that work on both Android 3.2 and up as well as previous versions of the platform.
Previous versions of the platform will ignore any resources using the new resource qualifiers. This, then, is one approach that will work:
res/layout/main_activity.xml           # For phones
res/layout-xlarge/main_activity.xml    # For pre-3.2 tablets
res/layout-sw600dp/main_activity.xml   # For 3.2 and up tablets
This does require, however, that you have two copies of your tablet layout. One way to avoid this is by defining the tablet layout once as a distinct resource, and then making new versions of the original layout resource that point to it. So the layout resources we would have are:
res/layout/main_activity.xml           # For phones
res/layout/main_activity_tablet.xml    # For tablets
To have the original layout point to the tablet version, you put <item> specifications in the appropriate values directories. That is these two files:
res/values-xlarge/layout.xml
res/values-sw600dp/layout.xml
Both would contain the following XML defining the desired resource:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <item type="layout" name="main_activty">
            @layout/main_activity_tablet
    </item>
</resources>
Of course, you can always simply select the resource to use in code. That is, define two or more resources like “layout/main_activity” and “layout/main_activity_tablet,” and select the one to use in your code based on information in the Configuration object or elsewhere. For example:
public class MyActivity extends Activity {
    @Override protected void onCreate(Bundle savedInstanceState) {
        super.onCreate();

        Configuration config = getResources().getConfiguration();
        if (config.smallestScreenWidthDp >= 600) {
            setContentView(R.layout.main_activity_tablet);
        } else {
            setContentView(R.layout.main_activity);
        }
    }
}

Conclusion

We strongly recommend that developers start using the new layout selectors for apps targeted at Android release 3.2 or higher, as we will be doing for Google apps. We think they will make your layout choices easier to express and manage.
Furthermore, we can see a remarkably wide variety of Android-device form factors coming down the pipe. This is a good thing, and will expand the market for your work. These new layout selectors are specifically designed to make it straightforward for you to make your apps run well in a future hardware ecosystem which is full of variety (and surprises).

More Carrier Billing Options on Android Market



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



Over the past year, we’ve seen very strong growth in the number of Android users around the world. To make it easier for those users to purchase their favorite apps and games on Android Market, we’re bringing Direct Carrier Billing to additional carrier networks in South Korea, the UK, and Germany.



In South Korea, we’ve begun a phased rollout of the service to users on the top two carrier networks — SK Telecom and KT Corporation. When complete, the rollout will reach more than 10 million users, who will be able to charge their Android Market purchases straight to their phone bills.



In Europe, we’re rolling out the service to users on two popular regional carriers, Vodafone UK and Vodafone DE. Initially, the service will be available only to users who have purchased their devices through Vodafone’s online and retail channels.



The new launches expand the network of carriers already offering direct billing service in the US on the T-Mobile, AT&T, and Sprint networks, and in Japan on SoftBank, KDDI, and NTT DOCOMO networks.



Direct Carrier Billing is a key payment option for users worldwide, especially in regions where credit cards are less common. We will continue to partner with more operators to offer this payment option to their Android users. Watch for more announcements in the weeks ahead.
Multiple APK Support in Android Market

Multiple APK Support in Android Market

[This post is by Eric Chu, Android Developer Ecosystem. —Dirk Dougherty]
At Google I/O we announced our plans to add several new capabilities to help developers manage their products more effectively in Android Market. We’re pleased to let you know that the latest of those, multiple APK support, is now available. Multiple APK support is a new publishing option in Android Market for those developers who want extra control over distribution.
Until now, each product listing on Android Market has included a single APK file, a universal payload that is deliverable to all eligible devices — across all platform versions, screen sizes, and chipsets. Broad distribution of a single APK works very well for almost all applications and has the advantage of simplified product maintenance.
With multiple APK support, you can now upload multiple versions of an APK for a single product listing, with each one addressing a different subset of your customers. These APKs are complete, independent APKs that share the same package name, but contain code and resources to target different Android platform versions, screen sizes, or GL texture-compression formats. When users download or purchase your app, Android Market chooses the right APK to deliver based on the characteristics of the device.
When you upload multiple APK files, Android Market handles them as part of a single product listing that aggregates the app details, ratings, and comments across the APKs. All users who browse your app’s details page see the same product with the same description, branding assets, screenshots, video, ratings, and comments. Android Market also aggregates the app’s download statistics, reviews, and billing data across all of the APKs.
Multiple APK support gives you a variety of ways to control app distribution. For example, you could use it to create separate APKs for phones and tablets under the same product listing. You could also use it to take advantage of new APIs or new hardware capabilities without impacting your existing customer base.
To support this new capability, we’ve updated the Developer Console to include controls for uploading and managing APKs in a product listing — we encourage you to take a look. If you’d like to learn more about how multiple APK support works, please read the developer documentation. As always, please feel free to give us feedback on the feature through the Market Help Center.

Thinking Like a Web Designer


[This post is by Roman Nurik, who is passionate about icons, with input from me and a bunch of the Framework engineers. —Tim Bray]
The number of people working on mobile apps, and specifically Android, is growing fast. Since modern mobile software-development is a relatively new profession, the community is growing by sucking in experts from related domains, one being web design and development.
It turns out that familiarity with web UI development, particularly using modern HTML5 techniques, can be a great primer for Android UI development. The Android framework and SDK have many analogues to tools and techniques in the Web repertoire of HTML, CSS, and JavaScript.
In this blog post, we’ll walk through a few web development features and look for matches in the world of Android UI development.

Device resolutions and physical sizes

One of the most important aspects of both Android UI design and web design is support for multiple screen resolutions and physical sizes. Just as your web app needs to work on any physical display and inside any size browser window, your native app needs to run on a variety of form factors, ranging from 2.5” phones to 10” tablets to (possibly) 50” TVs.
Let’s look at some ways in which CSS and Android allow for flexible and adaptive layouts.

Providing custom layouts for different resolutions

CSS3 media queries allow developers to include additional stylesheets to target different viewport and screen configurations. For example, developers can provide additional style rules or override existing styles for mobile devices. Although the markup (layout hierarchy) remains the same, CSS3 has several sophisticated techniques for completely transforming the placement of elements with different stylesheets.
Android has long offered a similar mechanism in resource directory qualifiers. This extends to many different types of resources (layouts, images or ‘drawables’, styles, dimensions, etc). Thus you can customize the view hierarchy as well as styling depending on device form factor, A base set of layouts for handsets can be extended for tablets by placing additional layouts in res/layout-xlarge or res/layout-sw600dp (smallest width 600 density-independent pixels) directories. Note that the latter syntax requires Android 3.2 or later.
Below is a CSS3 example of how one could hide a ‘left pane’ on smaller devices and show it on screens at least 600 pixels wide:
#leftPane {
  display: none;
}

@media screen and (min-device-width:600px) {
  #leftPane {
    display: block;
  }
}
The same could be accomplished on Android using multiple layout directories:
res/layout/foo.xml:
<FrameLayout>
  <!-- a single pane -->
  <View android:id="main_pane">
</FrameLayout>
res/layout-sw600dp/foo.xml:
<LinearLayout android:orientation="horizontal">
  <!-- two panes -->
  <View android:id="left_pane">
  <View android:id="main_pane">
</LinearLayout>
As a side note, if you plan on creating multi-pane layouts, consider using fragments, which help break up your screens into modular chunks of both layout and code.
There are also other neat ways of using resource directory qualifiers. For example, you could create values/dimens.xml and values-sw600dp/dimens.xml files specifying different font sizes for body text, and reference those values in your layouts by setting android:textSize="@dimen/my_body_text_size". The same could be done for margins, line spacing, or other dimensions to help manage whitespace on larger devices.

‘Holy grail’ layouts

Web developers have long dreamt of an easy way to build a ‘holy grail’ 5-pane layout (header/footer + 3 vertical columns). There are a variety of pre-CSS3 tricks including position:fixed, float:left, negative margins, and so on, to build such layouts but CSS3 introduced the flexible box module, which simplifies this tremendously.

Figure: An archetypal “holy grail” layout
It turns out that grail is pretty holy for Android tablet apps, too, and in particular for tablets held sideways in landscape mode. A good approach involves the use of LinearLayout, one of the simplest and most popular of the Android layouts.
LinearLayout has this neat way to stretch its children to fit the remaining space, or to distribute available space to certain children, using the android:layout_weight attribute. If a LinearLayout has two children with a fixed size, and another child with a nonzero layout_weight, that other child view will stretch to fill the remaining available space. For more on layout_weight and other ways to make layouts more efficient (like switching from nested LinearLayouts to RelativeLayout), check out Layout Tricks: Creating Efficient Layouts.
Let’s take a look at some example code for implementing such a ‘holy grail’ layout on Android and on the web:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <!-- top pane -->
    <View android:id="@+id/top_pane"
        android:layout_width="match_parent"
        android:layout_height="50dp" />

    <LinearLayout android:id="@+id/middle_container"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="horizontal">

        <!-- left pane -->
        <View id="@+id/left_pane"
            android:layout_width="300dp"
            android:layout_height="match_parent" />

        <!-- center pane -->
        <View id="@+id/center_pane"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1" />

        <!-- right pane -->
        <View id="@+id/right_pane"
            android:layout_width="300dp"
            android:layout_height="match_parent" />

    </LinearLayout>

    <!-- bottom pane -->
    <View android:id="@+id/bottom_pane"
        android:layout_width="match_parent"
        android:layout_height="50dp" />

</LinearLayout>
Note: Android tablet apps in landscape will generally show an action bar as the top pane and will usually have neither a right nor bottom pane. Also note that the action bar layout is automatically provided by the framework as of Android 3.0, and thus you don’t need to worry about positioning it.
And here’s an example implementation using the CSS3 flexible box model; notice the similarities:
<style>
  html, body { margin: 0; height: 100%; }

  #container {
    height: 100%;
    display: -webkit-box; /* like LinearLayout */
    display:    -moz-box;
    -webkit-box-orient: vertical; /* like android:orientation */
       -moz-box-orient: vertical;
  }

  #top, #bottom { height: 50px; }

  #middle {
    -webkit-box-flex: 1; /* like android:layout_weight */
       -moz-box-flex: 1;
    display: -webkit-box;
    -webkit-box-orient: horizontal;
       -moz-box-orient: horizontal;
  }

  #left, #right { width: 300px; }

  #center {
    -webkit-box-flex: 1;
       -moz-box-flex: 1;
  }
</style>

<div id="container">
  <div id="top"></div>
  <div id="middle">
    <div id="left"></div>
    <div id="center"></div>
    <div id="right"></div>
  </div>
  <div id="bottom"></div>
</div>

Layered content

In CSS, with position:absolute, you can overlay your UI elements. On Android, you can use FrameLayout to achieve this. The child views in a frame layout are laid out on top of each other, with optional layout_gravity attributes indicating alignment with the parent frame layout.
Below is a contrived example of a FrameLayout with three children.

Figure: Example FrameLayout with three children (2 with top-left and 1 bottom-right alignment)

Figure: Isometric view of the example FrameLayout and its children.
The code for this example is as follows:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="300dp"
    android:layout_height="200dp">

    <!-- bottom-most child, with bottom-right alignment -->
    <View android:layout_gravity="bottom|right"
        android:layout_width="100dp"
        android:layout_height="150dp" />

    <!-- middle child, with top-left alignment -->
    <View android:layout_gravity="top|left"
        android:layout_width="200dp"
        android:layout_height="175dp" />

    <!-- top-most child, with top-left alignment →
    <!-- also stretched to fill vertically -->
    <View android:layout_gravity="top|left"
        android:layout_width="100dp"
        android:layout_height="match_parent" />

</FrameLayout>

Scrollable content

HTML, by default, flows in reading order and scrolls vertically. When content extends beyond the bottom of the browser, scrollbars automatically appear. Content panes can also be made individually scrollable using overflow:scroll or overflow:auto.
Android screen content isn’t scrollable by default. However, many content Views such as ListView and EditText offer scrolling, and any layout can be made scrollable by wrapping it in a ScrollView or HorizontalScrollView.
It’s also possible to add custom scrolling to views by using methods like View.scrollTo and helpers like Scroller in response to touch events. And for horizontal, snap-to-page-bounds scrolling, one can use the excellent new ViewPager class in the support library.
Below is an example of a ScrollView containing a single TextView child and the code needed to implement something like this.

Figure: A TextView inside a ScrollView, scrolled about half way.

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

    <!-- the scrollable content -->
    <TextView android:layout_gravity="bottom|right"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="32dp"
        android:textSize="48sp"
        android:text="The\nquick\nbrown\nfox\njumps\nover..." />

</ScrollView>

Custom layouts

Sometimes the positioning and layout behaviors you can achieve with CSS aren’t enough to achieve your desired layout. In those cases, developers fall back on JavaScript coupled with absolute positioning to place and size elements as needed.
Programmatically defined layouts are also possible on Android. In fact, they’re sometimes the most elegant and/or performant way of implementing a unique or otherwise tricky layout. Not happy with nesting LinearLayouts for implementing a 2x3 grid of navigation icons? Just extend ViewGroup and implement your own layout logic! (see an example DashboardLayout here). All the built-in layouts such as LinearLayout, FrameLayout, and RelativeLayout are implemented this way, so there generally aren’t the same performance implications with custom layouts as there are with scripted layout on the web.

Device densities

Web designers have long dealt with the reality that display densities vary, and that there wasn’t much they could do about it. This meant that for a long time web page graphics and UI elements had different physical sizes across different displays. Your 100px wide logo could be 1” wide on a desktop monitor or ¾” on a netbook. This was mostly OK, given that (a) pointing devices such as mice offered generally good precision in interacting with such elements and (b) browsers allowed visually-impaired users to zoom pages arbitrarily.
However, on touch-enabled mobile devices, designers really need to begin thinking about physical screen size, rather than resolution in pixels. A 100px wide button on a 120dpi (low density) device is ~0.9” wide while on a 320dpi (extra-high density) screen it’s only ~0.3” wide. You need to avoid the fat-finger problem, where a crowded space of small touch targets coupled with an imprecise pointing tool (your finger) leads to accidental touches. The Android framework tries really hard to take your layout and scale elements up or down as necessary to work around device-density differences and get a usable result on a wide range of them. This includes the browser, which scales a 160px <img> at 100% browser zoom up to 240px on a 240dpi screen, such that its physical width is always 1”.
Developers can achieve finer-grained control over this browser scaling by providing custom stylesheets and images for different densities, using CSS3 media query filters such as -webkit-max-device-pixel-ratio and <meta> viewport arguments such as target-densitydpi=device-dpi. For an in-depth discussion on how to tame this mobile browser behavior see this blog post: Pixel-perfect Android web UIs.
For native Android apps, developers can use resource directory qualifiers to provide different images per density (such as drawable-hdpi and drawable-mdpi). In addition, Android offers a special dimension unit called ‘density independent pixels’ (dp) which can (and should!) be used in layout definitions to offset the density factors and create UI elements that have consistent physical sizes across screens with different densities.

Features you don’t have out of the box

There are a few features that web designers and developers rely on that aren’t currently available in the Android UI toolkit.
Developers can defer to user-driven browser zooming and two-dimensional panning for content that is too small or too large for its viewport, respectively. Android doesn’t currently provide an out-of-the-box mechanism for two-dimensional layout zooming and panning, but with some extra legwork using existing APIs, these interactions are possible. However, zooming and panning an entire UI is not a good experience on mobile, and is generally more appropriate for individual content views such as lists, photos, and maps.
Additionally, vector graphics (generally implemented with SVG) are gaining in popularity on the Web for a number of reasons: the need for resolution independence, accessibility and ‘indexability’ for text-heavy graphics, tooling for programmatic graphic generation, etc. Although you can’t currently drop an SVG into an Android app and have the framework render it for you, Android’s version of WebKit supports SVG as of Android 3.0. As an alternative, you can use the very robust Canvas drawing methods, similar to HTML5’s canvas APIs, to render vector graphics. There are also community projects such as svg-android that support rendering a subset of the SVG spec.

Conclusion

Web developers have a number of different tools for frontend layout and styling at their disposal, and there are analogues for almost all of these in the world of Android UI engineering. If you’re wondering about analogues to other web- or CSS-isms, start a conversation out there in the Android community; you’ll find you’re not alone.
Debugging Android JNI with CheckJNI

Debugging Android JNI with CheckJNI

[This post is by Elliott Hughes, a Software Engineer on the Dalvik team — Tim Bray]
Although most Android apps run entirely on top of Dalvik, some use the Android NDK to include native code using JNI. Native code is harder to get right than Dalvik code, and when you have a bug, it’s often a lot harder to find and fix it. Using JNI is inherently tricky (there’s precious little help from the type system, for example), and JNI functions provide almost no run-time checking. Bear in mind also that the developer console’s crash reporting doesn’t include native crashes, so you don’t even necessarily know how often your native code is crashing.

What CheckJNI can do

To help, there’s CheckJNI. It can catch a number of common errors, and the list is continually increasing. In Gingerbread, for example, CheckJNI can catch all of the following kinds of error:
  • Arrays: attempting to allocate a negative-sized array.
  • Bad pointers: passing a bad jarray/jclass/jobject/jstring to a JNI call, or passing a NULL pointer to a JNI call with a non-nullable argument.
  • Class names: passing anything but the “java/lang/String” style of class name to a JNI call.
  • Critical calls: making a JNI call between a GetCritical and the corresponding ReleaseCritical.
  • Direct ByteBuffers: passing bad arguments to NewDirectByteBuffer.
  • Exceptions: making a JNI call while there’s an exception pending.
  • JNIEnv*s: using a JNIEnv* from the wrong thread.
  • jfieldIDs: using a NULL jfieldID, or using a jfieldID to set a field to a value of the wrong type (trying to assign a StringBuilder to a String field, say), or using a jfieldID for a static field to set an instance field or vice versa, or using a jfieldID from one class with instances of another class.
  • jmethodIDs: using the wrong kind of jmethodID when making a Call*Method JNI call: incorrect return type, static/non-static mismatch, wrong type for ‘this’ (for non-static calls) or wrong class (for static calls).
  • References: using DeleteGlobalRef/DeleteLocalRef on the wrong kind of reference.
  • Release modes: passing a bad release mode to a release call (something other than 0, JNI_ABORT, or JNI_COMMIT).
  • Type safety: returning an incompatible type from your native method (returning a StringBuilder from a method declared to return a String, say).
  • UTF-8: passing an invalid Modified UTF-8 byte sequence to a JNI call.
If you’ve written any amount of native code without CheckJNI, you’re probably already wishing you’d known about it. There’s a performance cost to using CheckJNI (which is why it isn’t on all the time for everybody), but it shouldn’t change the behavior in any other way.

Enabling CheckJNI

If you’re using the emulator, CheckJNI is on by default. If you’re working with an Android device, use the following adb command:
adb shell setprop debug.checkjni 1
This won’t affect already-running apps, but any app launched from that point on will have CheckJNI enabled. (Changing the property to any other value or simply rebooting will disable CheckJNI again.) In this case, you’ll see something like this in your logcat output the next time each app starts:
D Late-enabling CheckJNI
If you don’t see this, your app was probably already running; you just need to force stop it and start it again.

Example

Here’s the output you get if you return a byte array from a native method declared to return a String:
W JNI WARNING: method declared to return 'Ljava/lang/String;' returned '[B'
W              failed in LJniTest;.exampleJniBug
I "main" prio=5 tid=1 RUNNABLE
I   | group="main" sCount=0 dsCount=0 obj=0x40246f60 self=0x10538
I   | sysTid=15295 nice=0 sched=0/0 cgrp=default handle=-2145061784
I   | schedstat=( 398335000 1493000 253 ) utm=25 stm=14 core=0
I   at JniTest.exampleJniBug(Native Method)
I   at JniTest.main(JniTest.java:11)
I   at dalvik.system.NativeStart.main(Native Method)
I 
E VM aborting
Without CheckJNI, you’d just die via SIGSEGV, with none of this output to help you!

New JNI documentation

We’ve also recently added a page of JNI Tips that explains some of the finer points of JNI. If you write native methods, even if CheckJNI isn’t rejecting your code, you should still read that page. It covers everything from correct usage of the JavaVM and JNIEnv types, how to work with native threads, local and global references, dealing with Java exceptions in native code, and much more, including answers to frequently-asked JNI questions.

What CheckJNI can’t do

There are still classes of error that CheckJNI can’t find. Most important amongst these are misuses of local references. CheckJNI can spot if you stash a JNIEnv* somewhere and then reuse it on the wrong thread, but it can’t detect you stashing a local reference (rather than a global reference) and then reusing it in a later native method call. Doing so is invalid, but currently mostly works (at the cost of making life hard for the GC), and we’re still working on getting CheckJNI to spot these mistakes.
We’re hoping to have more checking, including for local reference misuse, in a future release of Android. Start using CheckJNI now, though, and you’ll be able to take advantage of our new checks as they’re added.

Google Play Featured-Image Guidelines

By Natascha Bock, a Product Marketing Manager on the Google Play team



Localize your promotional graphics and videos new!


Google Play lets you provide different promotional graphics for each
language you support. Localizing your promotional graphics helps you reach your global user base more effectively. Read more below or go to the Developer Console Preview to get started.


If your app is selected for featuring on Google Play,our editorial team uses your 1024 x 500 “Featured Image” to promote the app on tablets, phones, and the Web. The image can be used on the home page on all versions of Google Play (Web, tablet and phone), on your product page in the Web and tablet versions, and on current and future top-level Google Play pages on phones.
Creating a Featured Image that will do a great job of highlighting your app requires special design consideration.

Not Really Optional

While many promotional assets are listed as “optional” for publishing in Google Play, we strongly recommend treating them as required. To start with, a Featured Image is required if your app is to be featured anywhere within Google Play. They’re a good idea anyhow; they enhance your product page, making your game or app more attractive to end-users (and more likely to be considered for featuring by our editorial team).
There’s nothing optional about the size, either; it has to be 1024 x 500 pixels.

Do’s and Dont’s

Your graphic is not an ad, it’s a teaser. It’s a place for bold, creative promotional images.
Vivid background colors work best. Black and white are problems because those are the backgrounds used by the mobile-device and Web versions of Google Play.
Limit Text to your app name and maybe a few additional descriptive words. Anything else will be unreadable on phones, anyhow.









Do: Make the graphic fun
and enticing./td>
Don't: Create a text-heavy
advertising-style graphic.
Do: Use colors that stand out on
black or white backgrounds.
Don't: Let the graphic fade into
the background.
Do: Promote your brand prominently.Don't: Overload the graphic with details.
Do: Localize your image as needed
for different languages.



Scaling

Your image has to be designed to scale; it will need to look good both in a full-size Web browser and on a little handset. You can rely on the aspect ratio being constant, but not the size. Here’s a tip: Try resizing your image down to 1 inch in width. If it still looks good and conveys your brand message, you have a winner.
On the Web:


On a tablet:


On a big phone:


On a small phone:

More Dont’s

  • Device imagery is tempting, but becomes dated fast, and may be inappropriate if your user’s device looks entirely different.
  • In-app screenshots are inappropriate because your product page already includes a place for these.
  • Just using your app icon is a failure of imagination. You have more room; put it to good use!

Consider the Context

Given the size of the form factor, the phone is the most challenging channel for your image. Below we have both the “good” and “bad” sample images in that context:

Localize your Featured Image and other promotional assets


Android's user base is global. To help you reach all of these users effectively, Google Play lets you provide a separate featured image for each language that you support, as well as separate screenshots and promotional videos. You can add your localized images and videos in the Developer Console.


Localizing your featured image is highly recommended as a powerful way to get your message across to users around the world. It goes hand-in-hand with localizing your app's description and other details and it's built-in string resources.



Don’t Forget

A 1024 x 500 Featured Image is required for feature placement consideration. Don't miss out on the opportunity!

Android’s HTTP Clients

Jesse Wilson
[This post is by Jesse Wilson from the Dalvik team. —Tim Bray]


Most network-connected Android apps will use HTTP to send and receive data. Android includes two HTTP clients: HttpURLConnection and Apache HTTP Client. Both support HTTPS, streaming uploads and downloads, configurable timeouts, IPv6 and connection pooling.

Apache HTTP Client

DefaultHttpClient and its sibling AndroidHttpClient are extensible HTTP clients suitable for web browsers. They have large and flexible APIs. Their implementation is stable and they have few bugs.
But the large size of this API makes it difficult for us to improve it without breaking compatibility. The Android team is not actively working on Apache HTTP Client.

HttpURLConnection

HttpURLConnection is a general-purpose, lightweight HTTP client suitable for most applications. This class has humble beginnings, but its focused API has made it easy for us to improve steadily.
Prior to Froyo, HttpURLConnection had some frustrating bugs. In particular, calling close() on a readable InputStream could poison the connection pool. Work around this by disabling connection pooling:
private void disableConnectionReuseIfNecessary() {
    // HTTP connection reuse which was buggy pre-froyo
    if (Integer.parseInt(Build.VERSION.SDK) < Build.VERSION_CODES.FROYO) {
        System.setProperty("http.keepAlive", "false");
    }
}
In Gingerbread, we added transparent response compression. HttpURLConnection will automatically add this header to outgoing requests, and handle the corresponding response:
Accept-Encoding: gzip
Take advantage of this by configuring your Web server to compress responses for clients that can support it. If response compression is problematic, the class documentation shows how to disable it.
Since HTTP’s Content-Length header returns the compressed size, it is an error to use getContentLength() to size buffers for the uncompressed data. Instead, read bytes from the response until InputStream.read() returns -1.
We also made several improvements to HTTPS in Gingerbread. HttpsURLConnection attempts to connect with Server Name Indication (SNI) which allows multiple HTTPS hosts to share an IP address. It also enables compression and session tickets. Should the connection fail, it is automatically retried without these features. This makes HttpsURLConnection efficient when connecting to up-to-date servers, without breaking compatibility with older ones.
In Ice Cream Sandwich, we are adding a response cache. With the cache installed, HTTP requests will be satisfied in one of three ways:
  • Fully cached responses are served directly from local storage. Because no network connection needs to be made such responses are available immediately.

  • Conditionally cached responses must have their freshness validated by the webserver. The client sends a request like “Give me /foo.png if it changed since yesterday” and the server replies with either the updated content or a 304 Not Modified status. If the content is unchanged it will not be downloaded!

  • Uncached responses are served from the web. These responses will get stored in the response cache for later.
Use reflection to enable HTTP response caching on devices that support it. This sample code will turn on the response cache on Ice Cream Sandwich without affecting earlier releases:
private void enableHttpResponseCache() {
    try {
        long httpCacheSize = 10 * 1024 * 1024; // 10 MiB
        File httpCacheDir = new File(getCacheDir(), "http");
        Class.forName("android.net.http.HttpResponseCache")
            .getMethod("install", File.class, long.class)
            .invoke(null, httpCacheDir, httpCacheSize);
    } catch (Exception httpResponseCacheNotAvailable) {
    }
}
You should also configure your Web server to set cache headers on its HTTP responses.

Which client is best?

Apache HTTP client has fewer bugs on Eclair and Froyo. It is the best choice for these releases.
For Gingerbread and better, HttpURLConnection is the best choice. Its simple API and small size makes it great fit for Android. Transparent compression and response caching reduce network use, improve speed and save battery. New applications should use HttpURLConnection; it is where we will be spending our energy going forward.