<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-6755709643044947179</atom:id><lastBuildDate>Fri, 25 May 2012 22:38:14 +0000</lastBuildDate><category>User Interface</category><category>Mountain View</category><category>Location</category><category>Gestures</category><category>Google Play</category><category>London</category><category>Android 2.1</category><category>Android Developer Phone</category><category>Boston</category><category>accessibility</category><category>Open source</category><category>Android Developer Challenge</category><category>Resources</category><category>Apps</category><category>OpenGL ES</category><category>NDK</category><category>Cool Stuff</category><category>Debugging</category><category>Speech Input</category><category>Text-to-Speech</category><category>io2010</category><category>Google I/O</category><category>Android 2.3.3</category><category>Android 3.2</category><category>Munich</category><category>Guidelines</category><category>Android 2.0</category><category>JNI</category><category>Quick Search Box</category><category>Tel Aviv</category><category>Android Market</category><category>Android 2.3</category><category>Android 1.5</category><category>Developer profiles</category><category>Widgets</category><category>Developer Labs</category><category>Announcements</category><category>Sample code</category><category>Dashboard</category><category>Intents</category><category>Android 2.2</category><category>Layout</category><category>Code Day</category><category>Android 1.6</category><category>Developer Days</category><category>How-to</category><category>Android 3.0</category><category>SDK updates</category><category>Input methods</category><category>Android 4.0</category><category>Optimization</category><title>Arena51</title><description>Arena51.be website</description><link>http://android-developers.blogspot.com/</link><managingEditor>noreply@blogger.com (David McLaughlin)</managingEditor><generator>Blogger</generator><openSearch:totalResults>276</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/android" /><feedburner:info uri="android" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2Fandroid" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fandroid" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Ffeeds.feedburner.com%2Fandroid" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feeds.feedburner.com/android" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fandroid" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fandroid" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fandroid" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><feedburner:feedFlare href="http://www.addtoany.com/?linkname=Arena51&amp;linkurl=http%3A%2F%2Ffeeds.feedburner.com%2Fandroid&amp;type=feed" src="http://www.addtoany.com/addfr-b.gif">Add to Any Feed Reader</feedburner:feedFlare><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6755709643044947179.post-5249461569188418981</guid><pubDate>Thu, 24 May 2012 17:02:00 +0000</pubDate><atom:updated>2012-05-24T23:04:50.417-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Google Play</category><title>In-app Subscriptions in Google Play</title><description>&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;[This post is by Ibrahim Elbouchikhi, Product Manager on the Google Play team. —Dirk Dougherty]&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
We launched In-app Billing on Google Play a year ago to give developers more ways to sell and engage users over the lifetime of their apps. Since the launch, In-app Billing has been extremely successful in helping developers monetize their apps through try-and-buy, virtual goods, upgrades, and other popular business models. Today, 23 of the 24 top-grossing apps in Google Play use In-app Billing, and the total revenue generated from in-app purchases exceeds revenue from traditional app purchases.&lt;br /&gt;
&lt;br /&gt;
We’re now taking In-app Billing further by adding another important business model &amp;mdash; subscriptions. &lt;span itemprop="description"&gt;Starting today, developers can use In-app Billing to sell monthly or annual subscriptions from inside of their apps. All subscriptions are auto-renewing, for every app and game and every type of subscription product.&lt;/span&gt; Developers just set the price and billing interval and Google Play manages the purchase transactions for them, just as it does for other in-app products and app purchases.&lt;br /&gt;
&lt;br /&gt;
For users, Google Play provides a familiar and convenient purchase experience, highlighting subscription details such as price and billing interval before continuing with purchases. After the transaction, Google Play manages recurring billing and keeps users informed of new charges, sending them an email with each renewal. At any time, users can visit My Apps in the Play Store app to view their subscriptions and cancel any subscription as needed.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-WBPXJ8PZI7I/T72bX3RgwkI/AAAAAAAABm8/P-ESiHcCbfk/s1600/google-play-subscriptions-lg.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img itemprop="image" border="0" style="border:5px solid #ddd;" height="324" src="http://1.bp.blogspot.com/-6K1kfNOdek8/T72bXvtTSQI/AAAAAAAABmw/kYzmJt0_328/s1600/google-play-subscriptions.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
While making it easy for developers to offer a great purchasing experience, our subscriptions are also designed for flexibility. Developers can use them to monetize premium dynamic content such as journals and magazines, but they can also use them to sell access to bundled products, game levels, music and video content, value-added services, or any other digital content. &lt;br /&gt;
&lt;br /&gt;
Building on Google Play’s strength as a truly cloud-connected experience, developers can offer users the ability to carry their subscriptions across multiple properties, services, or campaigns. To make this easier, we’re introducing an HTTP-based publisher API through which enterprise-scale backend servers can validate or cancel subscriptions. Using this API, for example, developers can extend access from their Android apps to their web properties, based on subscriptions that are purchased on Google Play.&lt;br /&gt;
&lt;br /&gt;
In the coming days, several developers will be launching apps with Google Play subscriptions and we expect many more to follow. Glu Mobile is launching updated versions of its top Android titles, including &lt;a href="https://play.google.com/store/apps/details?id=com.glu.modwarsniper"&gt;Frontline Commando&lt;/a&gt;, offering subscriptions through custom VIP currency packages. "We're using Google Play subscriptions to offer consumers a compelling value and a single currency which they can use across Glu’s most popular titles” says Niccolo de Masi, CEO of Glu.  “We're excited to bring these capabilities to our Android users and we believe that Google Play subscriptions will fuel further growth in our business."&lt;br /&gt;
&lt;br /&gt;
If you’re a developer, you can get started with subscriptions right away by reading the &lt;a href="http://developer.android.com/guide/market/billing/index.html"&gt;In-app Billing documentation&lt;/a&gt; and downloading the &lt;a href="http://developer.android.com/guide/market/billing/billing_integrate.html#billing-download"&gt;updated sample app&lt;/a&gt;. If you are already using in-app billing, you’ll find that adding support for subscriptions is straightforward and involves only minor changes to your code.&lt;br /&gt;
&lt;br /&gt;
You can publish your updated apps and subscription products as soon as you are ready. We’ve already rolled out client support to most Android devices worldwide, so any user with Google Play 3.5 or higher installed can buy subscriptions starting today.&lt;br /&gt;
&lt;br /&gt;
We’re looking forward to seeing how you use subscriptions in your apps!&lt;br /&gt;
&lt;a href="https://plus.google.com/108967384991768947849/posts/Q4dCQwzgD3j" style="text-decoration: none; color: #333;"&gt;&lt;br /&gt;
&lt;div style="display: inline-block; line-height: 0;float:right;"&gt;&lt;div style="float:left;"&gt;&lt;span style="font: 13px/16px arial,sans-serif; margin-right: 4px; margin-top: 11px;"&gt;Join the discussion on&lt;/span&gt;&lt;br /&gt;
&lt;span style="font: bold 13px/16px arial,sans-serif; margin-right: 4px; margin-top: 7px;"&gt;+Android Developers&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="float: right;"&gt;&lt;img src="https://ssl.gstatic.com/images/icons/gplus-32.png" width="32" height="32" style="border: 0;"/&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6755709643044947179-5249461569188418981?l=android-developers.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/android?a=6rhyDZZ-ZXY:SuY-Cdp4wfI:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?i=6rhyDZZ-ZXY:SuY-Cdp4wfI:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=6rhyDZZ-ZXY:SuY-Cdp4wfI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=6rhyDZZ-ZXY:SuY-Cdp4wfI:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/android/~4/6rhyDZZ-ZXY" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/android/~3/6rhyDZZ-ZXY/in-app-subscriptions-in-google-play.html</link><author>noreply@blogger.com (Dirk Dougherty)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-6K1kfNOdek8/T72bXvtTSQI/AAAAAAAABmw/kYzmJt0_328/s72-c/google-play-subscriptions.png" height="72" width="72" /><feedburner:origLink>http://android-developers.blogspot.com/2012/05/in-app-subscriptions-in-google-play.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6755709643044947179.post-8932561739684765625</guid><pubDate>Tue, 08 May 2012 18:00:00 +0000</pubDate><atom:updated>2012-05-08T11:13:46.706-07:00</atom:updated><title>Using DialogFragments</title><description>&lt;p&gt;&lt;i&gt;[This post is by &lt;a href="http://turbomanage.com/"&gt;David Chandler&lt;/a&gt;, Android Developer Advocate&amp;nbsp;&amp;mdash;&amp;nbsp;Tim Bray]&lt;/i&gt;&lt;/p&gt;&lt;p&gt;Honeycomb introduced Fragments to support reusing portions of UI and logic across multiple activities in an app. In parallel, the showDialog / dismissDialog methods in Activity are being deprecated &lt;a href="http://android-developers.blogspot.com/2011/02/android-30-fragments-api.html"&gt;in favor of DialogFragments&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;In this post, I’ll show how to use DialogFragments with the &lt;a href="http://developer.android.com/reference/android/support/v4/app/DialogFragment.html"&gt;v4 support library&lt;/a&gt; (for backward compatibility on pre-Honeycomb devices) to show a simple edit dialog and return a result to the calling Activity using an interface. For design guidelines around Dialogs, see the &lt;a href="http://developer.android.com/design/building-blocks/dialogs.html"&gt;&lt;cite&gt;Android Design&lt;/cite&gt;&lt;/a&gt; site.&lt;/p&gt;&lt;h3&gt;The Layout&lt;/h3&gt;&lt;p&gt;Here’s the layout for the dialog in a file named &lt;code&gt;fragment_edit_name.xml&lt;/code&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&amp;lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/edit_name"
    android:layout_width="wrap_content" android:layout_height="wrap_content"
    android:layout_gravity="center" android:orientation="vertical"  &gt;

    &amp;lt;TextView
        android:id="@+id/lbl_your_name" android:text="Your name" 
        android:layout_width="wrap_content" android:layout_height="wrap_content" /&gt;
      
    &amp;lt;EditText
        android:id="@+id/txt_your_name"
        android:layout_width="match_parent"  android:layout_height="wrap_content" 
        android:inputType=”text”
        android:imeOptions="actionDone" /&gt;
&amp;lt;/LinearLayout&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note the use of two optional attributes. In conjunction with &lt;code&gt;android:inputType=”text”&lt;/code&gt;, &lt;code&gt;android:imeOptions=”actionDone”&lt;/code&gt; configures the soft keyboard to show a Done key in place of the Enter key.&lt;/p&gt;&lt;h3&gt;The Dialog Code&lt;/h3&gt;&lt;p&gt;The dialog extends &lt;a href="http://developer.android.com/reference/android/app/DialogFragment.html"&gt;DialogFragment&lt;/a&gt;, and since we want backward compatibility, we’ll import it from the v4 support library. (To add the support library to an Eclipse project, right-click on the project and choose Android Tools | Add Support Library...). &lt;/p&gt;&lt;pre&gt;&lt;code&gt;import android.support.v4.app.DialogFragment;
// ...

public class EditNameDialog extends DialogFragment {

    private EditText mEditText;

    public EditNameDialog() {
        // Empty constructor required for DialogFragment
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_edit_name, container);
        mEditText = (EditText) view.findViewById(R.id.txt_your_name);
        getDialog().setTitle("Hello");

        return view;
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The dialog extends DialogFragment and includes the required empty constructor. Fragments implement the &lt;code&gt;onCreateView()&lt;/code&gt; method to actually load the view using the provided LayoutInflater.&lt;/p&gt;&lt;h3&gt;Showing the Dialog&lt;/h3&gt;&lt;p&gt;Now we need some code in our Activity to show the dialog. Here is a simple example that immediately shows the EditNameDialog to enter the user’s name. On completion, it shows a Toast with the entered text.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
// ...

public class FragmentDialogDemo extends FragmentActivity implements EditNameDialogListener {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        showEditDialog();
    }

    private void showEditDialog() {
        FragmentManager fm = getSupportFragmentManager();
        EditNameDialog editNameDialog = new EditNameDialog();
        editNameDialog.show(fm, "fragment_edit_name");
    }

    @Override
    public void onFinishEditDialog(String inputText) {
        Toast.makeText(this, "Hi, " + inputText, Toast.LENGTH_SHORT).show();
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;There are a few things to notice here. First, because we’re using the support library for backward compatibility with the Fragment API, our Activity extends FragmentActivity from the support library. Because we’re using the support library, we call &lt;code&gt;getSupportFragmentManager()&lt;/code&gt; instead of &lt;code&gt;getFragmentManager()&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;After loading the initial view, the activity immediately shows the EditNameDialog by calling its show() method. This allows the DialogFragment to ensure that what is happening with the Dialog and Fragment states remains consistent. By default, the back button will dismiss the dialog without any additional code.&lt;/p&gt;&lt;h3&gt;Using the Dialog&lt;/h3&gt;&lt;p&gt;Next, let’s enhance EditNameDialog so it can return a result string to the Activity.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;import android.support.v4.app.DialogFragment;
// ...
public class EditNameDialog extends DialogFragment implements OnEditorActionListener {

    public interface EditNameDialogListener {
        void onFinishEditDialog(String inputText);
    }

    private EditText mEditText;

    public EditNameDialog() {
        // Empty constructor required for DialogFragment
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_edit_name, container);
        mEditText = (EditText) view.findViewById(R.id.txt_your_name);
        getDialog().setTitle("Hello");

        // Show soft keyboard automatically
        mEditText.requestFocus();
        getDialog().getWindow().setSoftInputMode(
                LayoutParams.SOFT_INPUT_STATE_VISIBLE);
        mEditText.setOnEditorActionListener(this);

        return view;
    }

    @Override
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
        if (EditorInfo.IME_ACTION_DONE == actionId) {
            // Return input text to activity
            EditNameDialogListener activity = (EditNameDialogListener) getActivity();
            activity.onFinishEditDialog(mEditText.getText().toString());
            this.dismiss();
            return true;
        }
        return false;
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For user convenience, we programmatically focus on the EditText with &lt;code&gt;mEditText.requestFocus()&lt;/code&gt;. Alternatively, we could have used the &lt;code&gt;&amp;lt;requestFocus/&gt;&lt;/code&gt; tag in the layout XML to do this; however, in some cases it’s preferable to request focus programmatically. For example, an OnFocusChangeListener added in the Fragment’s &lt;code&gt;onCreateView()&lt;/code&gt; method won’t get called if you request focus in the layout XML.&lt;/p&gt;&lt;p&gt;If the user focuses on an EditText, the soft keyboard will automatically appear. In order to force this to happen with our programmatic focus, we call &lt;code&gt;getDialog().getWindow().setSoftInputMode()&lt;/code&gt;. Note that many Window operations you might have done previously in a Dialog can still be done in a DialogFragment, but you have to call &lt;code&gt;getDialog().getWindow()&lt;/code&gt; instead of just &lt;code&gt;getWindow()&lt;/code&gt;. The resulting dialog is shown on both a handset and tablet (not to scale):&lt;/p&gt;&lt;a href="http://1.bp.blogspot.com/-6qyjPxTuzv0/T6lde-Oq_fI/AAAAAAAABXc/zle7OFEGP44/s1600/fddns%2Bcopy.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 203px;" src="http://1.bp.blogspot.com/-6qyjPxTuzv0/T6lde-Oq_fI/AAAAAAAABXc/zle7OFEGP44/s400/fddns%2Bcopy.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5740221986742402546" /&gt;&lt;/a&gt;&lt;p&gt;The &lt;code&gt;onEditorAction()&lt;/code&gt; method handles the callback when the user presses the Done key. It gets invoked because we’ve set an OnEditorActionListener on the EditText. It calls back to the Activity to send the entered text. To do this, EditNameDialog declares an interface EditNameDialogListener that is implemented by the Activity. This enables the dialog to be reused by many Activities. To invoke the callback method &lt;code&gt;onFinishEditDialog()&lt;/code&gt;, it obtains a reference to the Activity which launched the dialog by calling getActivity(), which all Fragments provide, and then casts it to the interface type. In &lt;a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller"&gt;MVC&lt;/a&gt; architecture, this is a common pattern for allowing a view to communicate with a controller.&lt;/p&gt;&lt;p&gt;We can dismiss the dialog one of two ways. Here we are calling dismiss() within the Dialog class itself. It could also be called from the Activity like the show() method.&lt;/p&gt;&lt;p&gt;Hopefully this sheds some more light on Fragments as they relate to Dialogs. You can find the sample code in this blog post &lt;a href="http://code.google.com/p/dialogfragmentdemo/"&gt;on Google Code&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;References for learning more about Fragments:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;a href="http://developer.android.com/guide/topics/fundamentals/fragments.html"&gt;Fragments Dev Guide&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href="http://developer.android.com/training/basics/fragments/index.html"&gt;“Basic Training” on Fragments&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href="http://android-developers.blogspot.com/2009/04/updating-applications-for-on-screen.html"&gt;Updating Applications for On-screen Input Methods&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href="http://developer.android.com/reference/android/widget/TextView.OnEditorActionListener.html"&gt;OnEditorActionListener&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href="http://developer.android.com/reference/android/view/inputmethod/EditorInfo.html"&gt;EditorInfo and IME options&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6755709643044947179-8932561739684765625?l=android-developers.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/android?a=FlyiSr9RP44:8Wzu3o7A3Rw:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?i=FlyiSr9RP44:8Wzu3o7A3Rw:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=FlyiSr9RP44:8Wzu3o7A3Rw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=FlyiSr9RP44:8Wzu3o7A3Rw:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/android/~4/FlyiSr9RP44" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/android/~3/FlyiSr9RP44/using-dialogfragments.html</link><author>noreply@blogger.com (Tim Bray)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-6qyjPxTuzv0/T6lde-Oq_fI/AAAAAAAABXc/zle7OFEGP44/s72-c/fddns%2Bcopy.png" height="72" width="72" /><feedburner:origLink>http://android-developers.blogspot.com/2012/05/using-dialogfragments.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6755709643044947179.post-3327640679187090676</guid><pubDate>Fri, 13 Apr 2012 16:44:00 +0000</pubDate><atom:updated>2012-04-13T10:16:28.609-07:00</atom:updated><title>Android C2DM — Client Login key expiration</title><description>&lt;p&gt;&lt;i&gt;[This post is by &lt;a href="https://plus.google.com/104524825852741167674/posts"&gt;Francesco Nerieri&lt;/a&gt;, engineering team lead for C2DM&amp;nbsp;&amp;mdash;&amp;nbsp;Tim Bray]&lt;/i&gt;&lt;/p&gt;&lt;p&gt;In the upcoming weeks, some of the older Client Login authentication keys will expire. If you generated the token you’re currently using to authenticate with the C2DM servers before October 2011, it will stop working.  &lt;/p&gt;&lt;p&gt;If the response from the C2DM servers contains an &lt;code&gt;Update-Client-Auth&lt;/code&gt; header, you’ll need to replace the current token with the one included in the header.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  // Check for updated token header
  String updatedAuthToken = conn.getHeaderField(UPDATE_CLIENT_AUTH);
  if (updatedAuthToken != null &amp;amp;&amp;amp; !authToken.equals(updatedAuthToken)) {
    log.info("Got updated auth token from datamessaging servers: " +
        updatedAuthToken);
    serverConfig.updateToken(updatedAuthToken);
  }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We suggest that you start using the Update-Client-Auth response header to update tokens regularly, as keys will expire periodically from now on.  For example, have a look at  the Chrome to Phone service hosted on code.google.com; &lt;a href="http://code.google.com/p/chrometophone/source/browse/trunk/appengine/c2dm/com/google/android/c2dm/server/C2DMessaging.java"&gt;this code&lt;/a&gt; takes care of authenticating via Client Login and then sending a message:&lt;/p&gt;&lt;p&gt;Alternatively, you can manually generate a new Client Login token now and replace the one currently in use.  ClientLogin can be used with any application that can make an HTTPS POST request. The POST request should be structured as a form post with the default encoding application/x-www-form-urlencoded, like this:&lt;/p&gt;&lt;pre class="no-pretty-print"&gt;POST /accounts/ClientLogin HTTP/1.0
Content-type: application/x-www-form-urlencoded

accountType=GOOGLE&amp;amp;Email=johndoe@gmail.com&amp;amp;Passwd=north23AZ&amp;amp;service=ac2dm&lt;/pre&gt;&lt;p&gt;If the POST succeeds, the response contains the authorization token, labeled "Auth", which is your new token.  You could even do this from the command line:&lt;/p&gt;&lt;pre class="no-pretty-print"&gt;curl -d \
  "accountType=HOSTED_OR_GOOGLE&amp;amp;Email=johndoe@gmail.com&amp;amp;Passwd=north23AZ&amp;amp;service=ac2dm" \
  https://www.google.com/accounts/ClientLogin | \
  grep Auth&lt;/pre&gt;&lt;p&gt;If your request fails or if you are prompted for captchas, please read &lt;a href="https://developers.google.com/accounts/docs/AuthForInstalledApps"&gt;ClientLogin for Installed Applications&lt;/a&gt;.  And of course, if you updated your code to use the Update-Client-Auth header &lt;em&gt;after&lt;/em&gt; the keys had expired, then you will first need to manually generate a new token.  &lt;/p&gt;&lt;p&gt;Have fun with C2DM!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6755709643044947179-3327640679187090676?l=android-developers.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/android?a=Y8kDPMYjhRs:Yw9mhl_SLlY:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?i=Y8kDPMYjhRs:Yw9mhl_SLlY:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=Y8kDPMYjhRs:Yw9mhl_SLlY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=Y8kDPMYjhRs:Yw9mhl_SLlY:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/android/~4/Y8kDPMYjhRs" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/android/~3/Y8kDPMYjhRs/android-c2dm-client-login-key.html</link><author>noreply@blogger.com (Tim Bray)</author><feedburner:origLink>http://android-developers.blogspot.com/2012/04/android-c2dm-client-login-key.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6755709643044947179.post-4703451917614898270</guid><pubDate>Thu, 12 Apr 2012 20:30:00 +0000</pubDate><atom:updated>2012-04-12T16:31:04.654-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Google Play</category><title>New Seller Countries in Google Play</title><description>&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;a href="http://3.bp.blogspot.com/-ZrvsOxe_OBA/T1W6xuCBMkI/AAAAAAAABZ4/uwCvJl0YRYs/s1600/gplay_logo_web_white.png" imageanchor="1" style="clear:both; float:left;margin-left:0em; margin-right:1em;margin-bottom:1em;margin-top:1em;"&gt;&lt;img itemprop="image" border="0" src="http://developer.android.com/images/home/play_logo.png" /&gt;&lt;/a&gt;&lt;/div&gt;Over the past year we’ve been working to expand the list of countries and currencies from which Android developers can sell their products. &lt;span itemprop="description"&gt;Starting today, developers in Czech Republic, Israel, Poland, and Mexico can sell priced applications and in-app products on Google Play, using their local bank accounts for payments. Welcome developers!&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
If you develop Android apps in one of the new countries and want to get started selling them, visit &lt;a href="http://play.google.com/apps/publish"&gt;play.google.com/apps/publish&lt;/a&gt; and set up a new Google Play developer account. Once you’ve uploaded your apps, you can price them in any available buyer currencies, publish, and then receive payouts and financial data in your local currency. &lt;br /&gt;
&lt;br /&gt;
If you are based in Israel or Mexico and are currently selling apps through an AdSense merchant account, you will need to migrate your apps to a new Google Play developer account in your local currency. Watch for an email that provides complete information on the migration process and timeline.&lt;br /&gt;
&lt;br /&gt;
Additionally, we encourage developers everywhere to visit the Developer Console as soon as possible to set prices for their products in the currencies of these new countries. Stay tuned for more announcements soon as we continue to roll out our new billing infrastructure to buyers and sellers throughout the world.&lt;br /&gt;
&lt;a href="https://plus.google.com/108967384991768947849/posts/JtgT9Ezg9g6" style="text-decoration: none; color: #333;"&gt;&lt;br /&gt;
&lt;div style="display: inline-block; line-height: 0;float:right;"&gt;&lt;div style="float:left;"&gt;&lt;span style="font: 13px/16px arial,sans-serif; margin-right: 4px; margin-top: 11px;"&gt;Join the discussion on&lt;/span&gt;&lt;br /&gt;
&lt;span style="font: bold 13px/16px arial,sans-serif; margin-right: 4px; margin-top: 7px;"&gt;+Android Developers&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="float: right;"&gt;&lt;img src="https://ssl.gstatic.com/images/icons/gplus-32.png" width="32" height="32" style="border: 0;"/&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6755709643044947179-4703451917614898270?l=android-developers.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/android?a=Sc3IbkYENmM:womV4eK0Hp8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?i=Sc3IbkYENmM:womV4eK0Hp8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=Sc3IbkYENmM:womV4eK0Hp8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=Sc3IbkYENmM:womV4eK0Hp8:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/android/~4/Sc3IbkYENmM" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/android/~3/Sc3IbkYENmM/new-seller-countries-in-google-play.html</link><author>noreply@blogger.com (Dirk Dougherty)</author><feedburner:origLink>http://android-developers.blogspot.com/2012/04/new-seller-countries-in-google-play.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6755709643044947179.post-9037887593434390057</guid><pubDate>Tue, 10 Apr 2012 17:35:00 +0000</pubDate><atom:updated>2012-04-10T16:53:03.976-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">accessibility</category><title>Accessibility: Are You Serving All Your Users?</title><description>&lt;p&gt;&lt;i&gt;[This post is by &lt;a href="https://plus.google.com/103507786235300238642/posts"&gt;Joe Fernandez&lt;/a&gt;,  a technical writer for &lt;a href="http://developer.android.com/"&gt;developer.android.com&lt;/a&gt; who cares about accessibility and usability.&amp;nbsp;—&amp;nbsp;Tim&amp;nbsp;Bray.]&lt;/i&gt;&lt;/p&gt;&lt;p&gt;We recently published some new resources to help developers make their Android applications more accessible:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;a href="http://developer.android.com/guide/topics/ui/accessibility/index.html"&gt;Accessibility Developer Guide&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href="http://developer.android.com/training/accessibility/index.html"&gt;Implementing Accessibility Training&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;“But,” you may be thinking, “What is accessibility, exactly? Why should I make it a priority? How do I do it? And most importantly, how do I spell it?” All good questions. Let’s hit some of the key points.&lt;/p&gt;&lt;p&gt;Accessibility is about making sure that Android users who have limited vision or other physical impairments can use your application just as well as all those folks in line at the supermarket checking email on their phones. It’s also about the Mom over in the produce section whose kids are driving her to distraction, and really needs to see that critical notification your application is trying to deliver. It’s also about you, in the future; Is your eyesight getting better over time? How about that hand-eye coordination?&lt;/p&gt;&lt;p&gt;When it comes down to it, making an application accessible is about having a deep commitment to usability, getting the details right and delighting your users. It also means stepping into new territory and getting a different perspective on your application. Try it out: Open up an application you developed (or your all-time favorite app), then close your eyes and try to complete a task. No peeking! A little challenging, right? &lt;/p&gt;&lt;h3&gt;How Android Enables Accessibility&lt;/h3&gt;&lt;p&gt;One of main ways that Android enables accessibility is by allowing users to hear spoken feedback that announces the content of user interface components as they interact with applications. This spoken feedback is provided by an accessibility service called &lt;a href="https://play.google.com/store/apps/details?id=com.google.android.marvin.talkback"&gt;TalkBack&lt;/a&gt;, which is available for free on Google Play and has become a standard component of recent Android releases.&lt;/p&gt;&lt;p&gt;Now &lt;a href="http://developer.android.com/guide/topics/ui/accessibility/apps.html#test-audibles"&gt;enable TalkBack&lt;/a&gt;, and try that eyes-closed experiment again. Being able to hear your application’s interface probably makes this experiment a little easier, but it’s still challenging. This type of interaction is how many folks with limited vision use their Android devices every day. The spoken feedback works because all the user interface components provided by the Android framework are built so they can provide descriptions of themselves to accessibility services like TalkBack. &lt;/p&gt;&lt;p&gt;Another key element of accessibility on Android devices is the ability to use alternative navigation. Many users prefer directional controllers such as D-pads, trackballs or keyboard arrows because it allows them to make discrete, predictable movements through a user interface. You can try out directional control with your apps using the virtual keyboard in the &lt;a href="http://developer.android.com/guide/developing/devices/emulator.html"&gt;Android emulator&lt;/a&gt; or by installing and enabling the &lt;a href="https://play.google.com/store/apps/details?id=com.googlecode.eyesfree.inputmethod.latin"&gt;Eyes-Free Keyboard&lt;/a&gt; on your device. Android enables this type of navigation by default, but you, as a developer, may need to take a few steps to make sure users can effectively navigate your app this way.&lt;/p&gt;&lt;h3&gt;How to Make Your Application Accessible&lt;/h3&gt;&lt;p&gt;It would be great to be able to give you a standard recipe for accessibility, but the truth of the matter is that the right answer depends on the design and functionality of your application. Here are some key steps for ensuring that your application is accessible:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Task flows:&lt;/b&gt; Design well-defined, clear task flows with minimal navigation steps, especially for major user tasks, and make sure those tasks are navigable via focus controls (see item 4).&lt;/p&gt;&lt;/li&gt;&lt;p&gt;&lt;li&gt;&lt;b&gt;Action target size:&lt;/b&gt; Make sure buttons and selectable areas are of sufficient size for users to easily touch them, especially for critical actions. How big? We recommend that touch targets be &lt;a href="http://developer.android.com/design/style/metrics-grids.html#48dp-rhythm"&gt;48dp&lt;/a&gt; (roughly 9mm) or larger.&lt;/li&gt;&lt;/p&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Label user interface controls:&lt;/b&gt; &lt;a href="http://developer.android.com/guide/topics/ui/accessibility/apps.html#label-ui"&gt;Label user interface components&lt;/a&gt; that do not have visible text, especially &lt;a href="http://developer.android.com/reference/android/widget/ImageButton.html"&gt;ImageButton&lt;/a&gt;, &lt;a href="http://developer.android.com/reference/android/widget/ImageView.html"&gt;ImageView&lt;/a&gt;, and &lt;a href="http://developer.android.com/reference/android/widget/EditText.html"&gt;EditText&lt;/a&gt; components. Use the &lt;a href="http://developer.android.com/reference/android/view/View.html#attr_android:contentDescription"&gt;android:contentDescription&lt;/a&gt; XML layout attribute or &lt;a href="http://developer.android.com/reference/android/view/View.html#attr_android:contentDescription"&gt;setContentDescription()&lt;/a&gt; to provide this information for accessibility services. &lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Enable focus-based navigation:&lt;/b&gt; Make sure &lt;a href="http://developer.android.com/guide/topics/ui/accessibility/apps.html#focus-nav"&gt;users can navigate&lt;/a&gt; your screen layouts using hardware-based or software directional controls (D-pads, trackballs and keyboards). In a few cases, you may need to make UI components &lt;a href="http://developer.android.com/reference/android/view/View.html#attr_android:focusable"&gt;focusable&lt;/a&gt; or change the &lt;a href="http://developer.android.com/guide/topics/ui/accessibility/apps.html#focus-order"&gt;focus order&lt;/a&gt; to be more logical.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Use framework-provided controls:&lt;/b&gt; Use Android's built-in user interface controls whenever possible, as these components provide accessibility support by default.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Custom view controls:&lt;/b&gt; If you build &lt;a href="http://developer.android.com/guide/topics/ui/custom-components.html "&gt;custom interface controls&lt;/a&gt; for your application, &lt;a href="http://developer.android.com/guide/topics/ui/accessibility/apps.html#custom-views"&gt;implement accessibility interfaces&lt;/a&gt; for your custom views and provide text labels for the controls.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;b&gt;Test:&lt;/b&gt; Checking off the items on this list doesn’t guarantee your app is accessible. &lt;a href="http://developer.android.com/guide/topics/ui/accessibility/apps.html#test"&gt;Test accessibility&lt;/a&gt; by attempting to navigate your application using directional controls, and also try eyes free navigation with the TalkBack service enabled.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Here’s an example of implementing some basic accessibility features for an ImageButton inside an XML layout:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&amp;lt;ImageButton
    android:id="@+id/add_note_button"
    android:src="@drawable/add_note_image"
    android:contentDescription="@string/add_note_description"/&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Notice that we’ve added a content description that accessibility services can use to provide an audible explanation of the button. Users can navigate to this button and activate it with directional controls, because ImageButton objects are focusable by default (so you don’t have to include the &lt;code&gt;android:focusable="true"&lt;/code&gt; attribute).&lt;/p&gt;&lt;p&gt;The good news is that, in most cases, implementing accessibility isn’t about radically restructuring your application, but rather working through the subtle details of accessibility. Making sure your application is accessible is an opportunity to look at your app from a different perspective, improve the overall quality of your app and ensure that all your users have a great experience.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6755709643044947179-9037887593434390057?l=android-developers.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/android?a=-xUuTWMwlZ8:JgryyKJUIW0:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?i=-xUuTWMwlZ8:JgryyKJUIW0:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=-xUuTWMwlZ8:JgryyKJUIW0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=-xUuTWMwlZ8:JgryyKJUIW0:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/android/~4/-xUuTWMwlZ8" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/android/~3/-xUuTWMwlZ8/accessibility-are-you-serving-all-your.html</link><author>noreply@blogger.com (Tim Bray)</author><feedburner:origLink>http://android-developers.blogspot.com/2012/04/accessibility-are-you-serving-all-your.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6755709643044947179.post-8363285670263533337</guid><pubDate>Mon, 09 Apr 2012 18:00:00 +0000</pubDate><atom:updated>2012-04-09T12:33:29.842-07:00</atom:updated><title>A Faster Emulator with Better Hardware Support</title><description>&lt;p&gt;&lt;i&gt;[This post is by Xavier Ducrohet and Reto Meier of the Android engineering team. — Tim Bray.]&lt;/i&gt;&lt;/p&gt;&lt;p&gt;The Android emulator is a key tool for Android developers in building and testing their apps. As the power and diversity of Android devices has grown quickly,  it’s been hard for the emulator keep pace. &lt;/p&gt;&lt;p&gt;Today we’re thrilled to announce several significant improvements to the emulator, including a dramatic performance upgrade and support for a broader range of hardware features, notably sensors and multi-finger input.&lt;/p&gt;&lt;h3&gt;Added GPU Support&lt;/h3&gt;&lt;p&gt;The system image we’re shipping today has built-in GPU support (Android 4.0.3 r2).  With Android’s growing reliance on using the GPU to improve performance, the difference is significant.  In the video below,   the emulator is still interpreting ARM instructions; the performance boost is the effect of putting the GPU to work.&lt;/p&gt;&lt;iframe width="420" height="315" src="http://www.youtube.com/embed/T--vFtyZvc4" frameborder="0" allowfullscreen=""&gt;&lt;/iframe&gt;&lt;p&gt;
As a bonus, since we’re now supporting OpenGL ES 2.0, your OpenGL games can now run inside the emulator. &lt;/p&gt;&lt;p&gt;Please note that there are a lot of GPUs out there, and we haven’t tested all of them for this beta release, so let us know if you have &lt;a href="http://code.google.com/p/android/issues/entry?template=Tools%20GPU%20bug%20report"&gt;feedback&lt;/a&gt; or encounter issues. &lt;/p&gt;&lt;h3&gt;More Hardware Feature Emulation&lt;/h3&gt;&lt;p&gt;The hardware features of mobile devices are a significant part of what makes them a unique platform for development, so we’re also pleased to announce that in addition to the camera support we added last year, it’s now possible to use a tethered Android device to supply inputs for sensors and multi-touch input.&lt;/p&gt;&lt;p&gt;We’re working on providing emulator support for more hardware features including Bluetooth and NFC.&lt;/p&gt;&lt;h3&gt;Improved CPU Performance&lt;/h3&gt;&lt;p&gt;We’ve also improved the CPU performance of the Android emulator.  Hardware floating point operation has been available for system images since Ice Cream Sandwich (Android 4.0), allowing CPU operations to be emulated roughly twice as quickly.&lt;/p&gt;&lt;p&gt;Last week’s r17 developer tools release included x86 system images and host drivers (available through the SDK Manager), allowing the emulator to access the host CPU natively and offer significantly faster execution.&lt;/p&gt;&lt;p&gt;This video shows a CPU-bound application on two emulators running the same system image, one with virtualization, one without.&lt;/p&gt;&lt;iframe width="420" height="315" src="http://www.youtube.com/embed/1gnQX_izOrk" frameborder="0" allowfullscreen=""&gt;&lt;/iframe&gt;&lt;h3&gt;Building a modern emulator&lt;/h3&gt;&lt;p&gt;Because the Android platform allows deep interaction between applications, and with system components, we need to provide an emulator with a complete system image.  Our emulator virtualizes a complete device: hardware, kernel, low-level system libraries, and app framework.&lt;/p&gt;&lt;p&gt;Of course, the system being emulated typically has an ARM CPU; historically, we’d been emulating those instructions in software, and that worked OK until the advent of tablet support with additional animations and complexity in Android 3.0.&lt;/p&gt;&lt;p&gt;The missing pieces were the completion of Android x86 support, and the GPU support in last week’s release of SDK Tools r17.  This works by funneling the OpenGL ES 2.0 instructions from the emulator to the host OS, converted to standard OpenGL 2.0, and running natively on the host GPU.&lt;/p&gt;&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;p&gt;The Android ecosystem has a lot of devices in many different form factors. Developers need a good way of testing these apps without having to own everything out there and a fast, rich Android emulator is immensely helpful.&lt;/p&gt;&lt;p&gt;We hope that these new improvements will make the emulator a more useful tool in your development and testing, and look forward to improving it further for you.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6755709643044947179-8363285670263533337?l=android-developers.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/android?a=OCt1AQzfyWI:8Wsx2bOgcpg:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?i=OCt1AQzfyWI:8Wsx2bOgcpg:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=OCt1AQzfyWI:8Wsx2bOgcpg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=OCt1AQzfyWI:8Wsx2bOgcpg:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/android/~4/OCt1AQzfyWI" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/android/~3/OCt1AQzfyWI/faster-emulator-with-better-hardware.html</link><author>noreply@blogger.com (Tim Bray)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://img.youtube.com/vi/T--vFtyZvc4/default.jpg" height="72" width="72" /><feedburner:origLink>http://android-developers.blogspot.com/2012/04/faster-emulator-with-better-hardware.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6755709643044947179.post-8804233573658324945</guid><pubDate>Wed, 04 Apr 2012 05:43:00 +0000</pubDate><atom:updated>2012-04-04T10:46:03.599-07:00</atom:updated><title>The Gmail Public Labels API</title><description>&lt;p&gt;&lt;i&gt;[This post is by Nadav Aharony, a product manager on the Android team&amp;nbsp;&amp;mdash;&amp;nbsp;Tim Bray]&lt;/i&gt;&lt;/p&gt;&lt;p&gt;We’re rolling out new developer features for the Gmail Android app:  It now includes a public ContentProvider that you can use to retrieve label data. You can use this to access up-to-date unread counts for specific accounts’ inboxes and labels. &lt;/p&gt;&lt;p&gt;To use the API, the Gmail app needs to be at version 2.3.6 or higher on Froyo or Gingerbread; 4.0.5 or higher on Honeycomb and ICS. Before using it, be sure you first check the Gmail app version; we’ve provided a handy  &lt;code&gt;GmailContract.canReadLabels(Context)&lt;/code&gt; method to help with this. Your app will need the &lt;code&gt;com.google.android.gm.permission.READ_CONTENT_PROVIDER&lt;/code&gt; permission.&lt;/p&gt;&lt;h3&gt;Finding the Gmail accounts set up on the device&lt;/h3&gt;&lt;p&gt;The Labels API needs a valid Gmail account to build a query for per-label information.  Assuming the &lt;a href="http://developer.android.com/reference/android/Manifest.permission.html#GET_ACCOUNTS"&gt;GET_ACCOUNTS&lt;/a&gt; permission, the &lt;a href="http://developer.android.com/reference/android/accounts/AccountManager.html"&gt;AccountManager&lt;/a&gt; can be used to fetch this information:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;// Get the account list, and pick the first one
final String ACCOUNT_TYPE_GOOGLE = "com.google";
final String[] FEATURES_MAIL = {
        "service_mail"
};
AccountManager.get(this).getAccountsByTypeAndFeatures(ACCOUNT_TYPE_GOOGLE, FEATURES_MAIL,
        new AccountManagerCallback() {
            @Override
            public void run(AccountManagerFuture future) {
                Account[] accounts = null;
                try {
                    accounts = future.getResult();
                    if (accounts != null &amp;amp;&amp;amp; accounts.length &gt; 0) {
                        String selectedAccount = accounts[0].name;
                        queryLabels(selectedAccount);
                    }

                } catch (OperationCanceledException oce) {
                    // TODO: handle exception
                } catch (IOException ioe) {
                    // TODO: handle exception
                } catch (AuthenticatorException ae) {
                    // TODO: handle exception
                }
            }
        }, null /* handler */);&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Getting and accessing existing labels&lt;/h3&gt;&lt;p&gt;Once you’ve got the email account, you can get a &lt;a href="http://developer.android.com/guide/topics/providers/content-provider-basics.html"&gt;ContentProvider&lt;/a&gt; URI to query against. We've provided a simple support class called &lt;a href="https://developers.google.com/gmail/android/com/google/android/gm/contentprovider/GmailContract"&gt;GmailContract.java&lt;/a&gt; for constructing the URI and defining the columns and relevant constants. &lt;/p&gt;&lt;p&gt;You can access any label, predefined or user-defined. The predefined labels include (you have to use symbolic constants rather than these strings, see below): &lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Priority Inbox&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Starred&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Chats&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Sent&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Drafts&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;All mail&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Spam&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Trash&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;To obtain a Cursor with information for all labels in an account, your app can either query this URI directly or use a &lt;a href="http://developer.android.com/reference/android/content/CursorLoader.html"&gt;CursorLoader&lt;/a&gt;. Here’s an example:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Cursor c = 
    getContentResolver().query(GmailContract.Labels.getLabelsUri(selectedAccount), 
        null, null, null, null);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can query and watch for changes on a single label by storing the URI value in the &lt;code&gt;GmailContract.Labels.URI&lt;/code&gt; column from the cursor data.&lt;/p&gt;&lt;p&gt;The &lt;code&gt;NAME&lt;/code&gt; value for pre-defined labels can vary by locale, so don’t use &lt;code&gt;GmailContract.Labels.NAME&lt;/code&gt;. Instead, identify pre-defined labels like Inbox, Sent or Drafts using the String value in the &lt;code&gt;GmailContract.Labels.CANONICAL_NAME&lt;/code&gt; column. Here’s an example:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;// loop through the cursor and find the Inbox
if (c != null) {
    final String inboxCanonicalName = GmailContract.Labels.LabelCanonicalName.CANONICAL_NAME_INBOX;
    final int canonicalNameIndex = c.getColumnIndexOrThrow(GmailContract.Labels.CANONICAL_NAME);
    while (c.moveToNext()) {
        if (inboxCanonicalName.equals(c.getString(canonicalNameIndex))) {
            // this row corresponds to the Inbox
        }
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you choose to use a &lt;a href="http://developer.android.com/reference/android/content/CursorLoader.html"&gt;CursorLoader&lt;/a&gt;, it will keep the label counts up to date as they change over time.&lt;/p&gt;&lt;h3&gt;Sample App&lt;/h3&gt;&lt;p&gt;You can find a sample app that makes use of the new API &lt;a href="https://developers.google.com/gmail/android/android-gmail-api-sample.tar.gz"&gt;here&lt;/a&gt;. The app provides a basic readout of label and message-count information.&lt;/p&gt;&lt;p&gt;People care about their incoming mail; we’re looking forward to seeing what you do with access to this information.  We’re also open to suggestions as to how to improve and extend this new API.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6755709643044947179-8804233573658324945?l=android-developers.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/android?a=SgVlzpjU--E:tHdJ53OJ_sg:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?i=SgVlzpjU--E:tHdJ53OJ_sg:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=SgVlzpjU--E:tHdJ53OJ_sg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=SgVlzpjU--E:tHdJ53OJ_sg:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/android/~4/SgVlzpjU--E" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/android/~3/SgVlzpjU--E/gmail-public-labels-api.html</link><author>noreply@blogger.com (Tim Bray)</author><feedburner:origLink>http://android-developers.blogspot.com/2012/04/gmail-public-labels-api.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6755709643044947179.post-3726073550611530071</guid><pubDate>Thu, 29 Mar 2012 17:20:00 +0000</pubDate><atom:updated>2012-03-29T11:36:53.681-07:00</atom:updated><title>Making the Android Developer Console work for your whole team</title><description>&lt;a href="http://4.bp.blogspot.com/-Hzf1VF82_FE/T3OXjzFfijI/AAAAAAAABQM/GbKa2aE5m9o/s1600/mum2.png"&gt;&lt;img style="border: 5px solid #ddd;float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 400px; height: 191px;" src="http://4.bp.blogspot.com/-Hzf1VF82_FE/T3OXjzFfijI/AAAAAAAABQM/GbKa2aE5m9o/s400/mum2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5725086192582494770" /&gt;&lt;/a&gt;&lt;p&gt;&lt;i&gt;[This post is by &lt;a href="https://plus.google.com/100189531984607939401/posts"&gt;Ellie Powers&lt;/a&gt;, a product manager on the Google Play team. — Tim Bray]&lt;/i&gt;&lt;/p&gt;As your apps have gotten more successful, more people have joined your team. Today, we’re making it easier to work together on analyzing and managing your published Android apps. Sharing passwords is &lt;a href="https://support.google.com/googleplay/android-developer/bin/answer.py?hl=en&amp;amp;answer=2543765"&gt;generally a bad idea&lt;/a&gt;; so as of now, there’s no need to do that for the Android Developer Console — everyone can use his or her own Google account.&lt;br /&gt;
&lt;br /&gt;
The account that you use today to sign into the Android Developer Console will become the &lt;em&gt;account owner&lt;/em&gt;; only the account owner can manage access to the Console. The account owner can email an invitation to anyone; when they accept it, they’ll need to use a Google account to sign in.&lt;br /&gt;
&lt;br /&gt;
Different people in your team do different jobs, so when you invite someone to your Android Developer Console, you’ll be able to specify what access they need. Today, you can limit access per-user to financial reports. In the future, we’ll give you more fine-grained control over access to the Console.  For details, see &lt;a href="http://support.google.com/googleplay/android-developer/bin/answer.py?hl=en&amp;answer=2528691"&gt;Account owner and user access&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
We hope this helps your team collaborate more easily. If you have any issues, feel free to get in touch via the &lt;a href="http://support.google.com/googleplay/android-developer/bin/answer.py?hl=en&amp;amp;answer=136601"&gt;Developer Help Center&lt;/a&gt;. &lt;br /&gt;
&lt;a href="https://plus.google.com/108967384991768947849/posts/6VWzZeupVSJ" style="text-decoration: none; color: #333;"&gt;&lt;br /&gt;
&lt;div style="display: inline-block; line-height: 0;float:right;"&gt;&lt;div style="float:left;"&gt;&lt;span style="font: 13px/16px arial,sans-serif; margin-right: 4px; margin-top: 11px;"&gt;Join the discussion on&lt;/span&gt;&lt;br /&gt;
&lt;span style="font: bold 13px/16px arial,sans-serif; margin-right: 4px; margin-top: 7px;"&gt;+Android Developers&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="float: right;"&gt;&lt;img src="https://ssl.gstatic.com/images/icons/gplus-32.png" width="32" height="32" style="border: 0;"/&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6755709643044947179-3726073550611530071?l=android-developers.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/android?a=ntgrKbj9ZRc:6tqMTtXLGWE:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?i=ntgrKbj9ZRc:6tqMTtXLGWE:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=ntgrKbj9ZRc:6tqMTtXLGWE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=ntgrKbj9ZRc:6tqMTtXLGWE:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/android/~4/ntgrKbj9ZRc" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/android/~3/ntgrKbj9ZRc/making-developer-console-work-for-your.html</link><author>noreply@blogger.com (Tim Bray)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-Hzf1VF82_FE/T3OXjzFfijI/AAAAAAAABQM/GbKa2aE5m9o/s72-c/mum2.png" height="72" width="72" /><feedburner:origLink>http://android-developers.blogspot.com/2012/03/making-developer-console-work-for-your.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6755709643044947179.post-7890934758713735222</guid><pubDate>Thu, 22 Mar 2012 19:37:00 +0000</pubDate><atom:updated>2012-03-22T13:32:11.743-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Google Play</category><title>New Sales Reports on Google Play</title><description>&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;[This post is by Debashish Chatterjee, Krishna Atkuru, and Ellie Powers of the Google Play Publisher Site team. —Dirk Dougherty]&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
For app publishers, complete and timely sales reporting is incredibly useful for managing a business on Google Play. &lt;span itemprop="description"&gt;Today we are introducing a new financial tool &amp;mdash; Estimated Sales Reports &amp;mdash; to give you visibility over ongoing product sales and help you support customers between payout cycles.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
The new sales reports show you complete transaction details of recent sales and refunds for all products in your developer account, including both in-app products and paid apps. Each report is a cumulative for the current payout period, updated nightly with the details of recent transactions. As customers complete purchases and their accounts are charged (or refunds are applied), the new transaction details are appended to the Estimated Sales Report. Depending on account timezone differences, transactions appear on the estimated sales report within 2 days of completion.  Finally, at the close of the monthly payout cycle, the current Estimated Sales Report is archived and a new report is created for the next cycle.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-jEJOB4SYd80/T2f6LeYdU6I/AAAAAAAABc4/90JYhqczswE/s1600/sreports.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" itemprop="image" width="700" src="http://1.bp.blogspot.com/-fp2UoTwAZ8E/T2f7lHCLFYI/AAAAAAAABdE/DfUMZ0xPg9s/s1600/sreports-sm.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
You can access current or past sales reports from the “Merchant Reports” section of the Developer Console. The Estimated Sales Reports are downloadable CSV (comma-separated values) files, so you can analyze the data using any tools you choose, in the same way as you've been doing for payout reports. The sales reports list the same details as payout reports &amp;mdash; buyer and order, product, device information, amount, currency of sale, and more &amp;mdash; except without final payment details. This makes it easier for you to reconcile recorded sales against your actual payouts. Estimated sales reports are available with data starting February 1, 2012.&lt;br /&gt;
&lt;br /&gt;
We’ve also taken this opportunity to rename our existing “Merchant Sales Reports” to Monthly Payout Reports, to better reflect their content. &lt;br /&gt;
&lt;br /&gt;
Together with the application statistics introduced last month, the Estimated Sales and Monthly Payout Reports give you a more complete view of your products’ download and sales activity over time. We hope you’ll find them useful. As always, please feel free to give us feedback through the &lt;a href="http://support.google.com/googleplay/android-developer/bin/answer.py?hl=en&amp;answer=136601"&gt;Developer Help Center&lt;/a&gt;.&lt;br /&gt;
&lt;a href="https://plus.google.com/108967384991768947849/posts/RR9C2VcyQTT" style="text-decoration: none; color: #333;"&gt;&lt;br /&gt;
&lt;div style="display: inline-block; line-height: 0;float:right;"&gt;&lt;div style="float:left;"&gt;&lt;span style="font: 13px/16px arial,sans-serif; margin-right: 4px; margin-top: 11px;"&gt;Join the discussion on&lt;/span&gt;&lt;br /&gt;
&lt;span style="font: bold 13px/16px arial,sans-serif; margin-right: 4px; margin-top: 7px;"&gt;+Android Developers&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="float: right;"&gt;&lt;img src="https://ssl.gstatic.com/images/icons/gplus-32.png" width="32" height="32" style="border: 0;"/&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;img border="0" style="display:none;" height="86" width="210"  itemprop="image" src="http://4.bp.blogspot.com/-y-HO0r43sPY/T2jSexzGMFI/AAAAAAAABds/VqsNksEPnB0/s400/sl-mini2.png" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6755709643044947179-7890934758713735222?l=android-developers.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/android?a=Vjl-mKRNB_U:irgISEb2LVI:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?i=Vjl-mKRNB_U:irgISEb2LVI:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=Vjl-mKRNB_U:irgISEb2LVI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=Vjl-mKRNB_U:irgISEb2LVI:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/android/~4/Vjl-mKRNB_U" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/android/~3/Vjl-mKRNB_U/new-sales-reports-on-google-play.html</link><author>noreply@blogger.com (Dirk Dougherty)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-fp2UoTwAZ8E/T2f7lHCLFYI/AAAAAAAABdE/DfUMZ0xPg9s/s72-c/sreports-sm.png" height="72" width="72" /><feedburner:origLink>http://android-developers.blogspot.com/2012/03/new-sales-reports-on-google-play.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6755709643044947179.post-2746875300506627058</guid><pubDate>Wed, 21 Mar 2012 21:00:00 +0000</pubDate><atom:updated>2012-03-21T14:06:15.703-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">SDK updates</category><category domain="http://www.blogger.com/atom/ns#">Announcements</category><title>Updated SDK Tools and ADT revision 17</title><description>&lt;p&gt;Today we are releasing an update to the SDK Tools and the Eclipse plugin. Revision 17 brings a lot of new features and bug fixes in various areas such as Lint, the build system as well as the emulator.&lt;/p&gt;&lt;p&gt;Lint is a static checker which analyzes Android projects for a variety of issues around correctness, security, performance, usability and accessibility, checking your XML resources, bitmaps, ProGuard configuration files, source files and even compiled bytecode. It can be run from within Eclipse or from the command line.&lt;br/&gt;New for r17:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Added check for Android API calls that require a version of Android higher than the minimum supported version. You can use the new &lt;span style="color: rgb(0, 112, 0); "&gt;@TargetApi&lt;/span&gt; annotation to specify local overrides for conditionally loaded code. For more information, &lt;a href="http://tools.android.com/recent/lintapicheck" target="_blank"&gt;read here&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Added over 40 new Lint rules for a total of over 80, including checks for &lt;a href="http://tools.android.com/recent/lintperformancechecks" target="_blank"&gt;performance&lt;/a&gt;, XML layouts, manifest and file handling. For a full list &lt;a href="http://tools.android.com/recent/newlintrules-1" target="_blank"&gt;read here&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Added ability to suppress Lint warnings in Java code with the new &lt;span style="color: rgb(0, 112, 0); "&gt;@SuppressLint&lt;/span&gt; annotation, and in XML files with the new &lt;span style="color: rgb(0, 112, 0); "&gt;tools:&lt;/span&gt; namespace prefix and &lt;span style="color: rgb(0, 112, 0); "&gt;ignore&lt;/span&gt; attribute. For more information, &lt;a href="http://tools.android.com/recent/ignoringlintwarnings" target="_blank"&gt;read here&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Improved HTML and XML reporting and Eclipse integration. For more information, &lt;a href="http://tools.android.com/recent/neweclipselintui" target="_blank"&gt;read here&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;We’ve also made improvements to the build systems for Eclipse and Ant:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Added strict dependency support for 3rd party Jar files. You can read more information &lt;a href="http://tools.android.com/recent/dealingwithdependenciesinandroidprojects" target="_blank"&gt;here&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Added support for custom views with custom attributes in libraries. Layouts using custom attributes must use the namespace URI &lt;span style="color: rgb(0, 112, 0); "&gt;http://schemas.android.com/apk/res-auto&lt;/span&gt; instead of the URI that includes the app package name. This URI is replaced with the app specific one at build time.&lt;/li&gt;&lt;li&gt;Added a feature that allows you to run some code only in debug mode. Builds now generate a class called &lt;span style="color: rgb(0, 112, 0); "&gt;BuildConfig&lt;/span&gt; containing a &lt;span style="color: rgb(0, 112, 0); "&gt;DEBUG&lt;/span&gt; constant that is automatically set according to your build type. You can check the (&lt;span style="color: rgb(0, 112, 0); "&gt;BuildConfig.DEBUG&lt;/span&gt;) constant in your code to run debug-only functions such as outputting debug logs.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The emulator is seeing some big improvements as well:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Thanks to contributions to AOSP from Intel, the emulator now supports running x86 system images in virtualization mode on Windows and Mac OS X. This allows the emulator running at near native speed. The drivers are available through the SDK Manager. Read more &lt;a href="http://developer.android.com/guide/developing/devices/emulator.html#accel-vm" target="_blank"&gt;here&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;After adding webcam support and sensor emulation, we are adding experimental support for Multi-Touch input through a tethered Android device. (Read more &lt;a href="http://tools.android.com/tips/hardware-emulation" target="_blank"&gt;here&lt;/a&gt;)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Finally, we are also releasing an updated Support Library with the following improvements:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="color: rgb(0, 112, 0);"&gt;ShareCompat&lt;/span&gt; provides easy helper classes for both sending and receiving content for social sharing apps.&lt;/li&gt;&lt;li&gt;&lt;span style="color: rgb(0, 112, 0);"&gt;NavUtils&lt;/span&gt; and &lt;span style="color: rgb(0, 112, 0);"&gt;TaskStackBuilder&lt;/span&gt; provide cross-version support for implementing the Android Design guidelines for navigating within your app including the action bar's "Up" button.&lt;/li&gt;&lt;li&gt;&lt;span style="color: rgb(0, 112, 0);"&gt;NotificationCompat.Builder&lt;/span&gt; provides a compatibility implementation of Android 3.0's &lt;span style="color: rgb(0, 112, 0);"&gt;Notification.Builder&lt;/span&gt; helper class for creating standardized system notifications.&lt;/li&gt;&lt;li&gt;A new Library Project adds support for &lt;span style="color: rgb(0, 112, 0); "&gt;GridLayout&lt;/span&gt; back to API level 7 and higher.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;You can get more information about these changes in the &lt;a href="http://developer.android.com/sdk/tools-notes.html" target="_blank"&gt;SDK Tools Release Notes&lt;/a&gt; and &lt;a href="http://developer.android.com/sdk/eclipse-adt.html" target="_blank"&gt;ADT Release Notes&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6755709643044947179-2746875300506627058?l=android-developers.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/android?a=TOloutFqMW8:yfbswI9mMhI:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?i=TOloutFqMW8:yfbswI9mMhI:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=TOloutFqMW8:yfbswI9mMhI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=TOloutFqMW8:yfbswI9mMhI:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/android/~4/TOloutFqMW8" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/android/~3/TOloutFqMW8/updated-sdk-tools-and-adt-revision-17.html</link><author>noreply@blogger.com (Xavier Ducrohet, Android SDK Tech Lead)</author><feedburner:origLink>http://android-developers.blogspot.com/2012/03/updated-sdk-tools-and-adt-revision-17.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6755709643044947179.post-4475335699969734409</guid><pubDate>Tue, 13 Mar 2012 16:15:00 +0000</pubDate><atom:updated>2012-03-13T09:44:13.023-07:00</atom:updated><title>Unifying Key Store Access in ICS</title><description>&lt;p&gt;&lt;i&gt;[This post is a group effort by Tony Chan, Fred Chung, Brian Carlstrom, and Kenny Root. — Tim Bray]&lt;/i&gt;&lt;/p&gt;&lt;p&gt;Android 4.0 (ICS) comes with &lt;a href="https://plus.google.com/u/0/116015738121164122619/posts/XCiRMwEEVuy"&gt;a number of enhancements&lt;/a&gt; that make it easier for people to bring their personal Android devices to work.   In this post, we’re going to have a look at the key store functionality.&lt;/p&gt;&lt;p&gt;Back in Android 1.6 (Donut), a system key store was added for use by VPN.  Although this was later expanded to support WiFi authentication, applications weren’t able to access it.&lt;/p&gt;&lt;p&gt;In the past, it was common practice for apps to maintain their own key store if they needed to authenticate a secure SSL web server, or authenticate the user to a server via a client certificate.  While this works, it can present manageability issues in an enterprise environment where multiple certificates may be shared across a number of apps such as Email and Browser.&lt;/p&gt;&lt;h3&gt;New in ICS: KeyChain &lt;/h3&gt;&lt;p&gt;To bridge the gap in ICS, there’s a new API named &lt;a href="http://developer.android.com/reference/android/security/KeyChain.html"&gt;KeyChain&lt;/a&gt; that regulates application access to the system key store and allows users to grant application access to the credentials stored there.  Additionally, this API enables applications to initiate installation of credentials from X.509 certificates and PKCS#12 key stores.&lt;/p&gt;&lt;a href="http://2.bp.blogspot.com/-f7QriOX9amI/T16HXPqp6-I/AAAAAAAABNY/1pt9zD49uFI/s1600/extract_cert_1.png"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 225px; height: 400px;" src="http://2.bp.blogspot.com/-f7QriOX9amI/T16HXPqp6-I/AAAAAAAABNY/1pt9zD49uFI/s400/extract_cert_1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5719157410219289570" /&gt;&lt;/a&gt;&lt;p&gt;The KeyChain API is rather simple.  To install a key store or a certificate, you retrieve an install intent, supply the raw bytes of the credentials, and use the intent to launch a system installation dialog.  If it’s a keystore, as in the example below, you’ll need provide the data in &lt;a href="http://en.wikipedia.org/wiki/PKCS12"&gt;PKCS#12&lt;/a&gt; format, and the user will have to know the PKCS#12 password.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  byte[] keystore = . . (read from a PKCS#12 keystore)

  Intent installIntent = KeyChain.createInstallIntent();
  installIntent.putExtra(KeyChain.EXTRA_PKCS12, keystore);
  startActivityForResult(installIntent, INSTALL_KEYSTORE_CODE);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The install intent launches a system dialog that prompts the user to enter the password for the keystore.  &lt;/p&gt;&lt;p&gt;This can also be used for installing organizational CA certificates which will then be trusted by all applications to authenticate to non-public servers with certificates issued by the same CA.&lt;/p&gt;&lt;p&gt;In ICS, Android no longer requires a separate password to protect the system credential storage.  Rather, it uses the screen lock password for this purpose, and the &lt;a href="http://developer.android.com/guide/topics/admin/device-admin.html"&gt;Android Device Administration API&lt;/a&gt; can be used for central policy enforcement. This means, for example, that the screen lock password can’t be removed as long as the secured credentials remain on the device.&lt;/p&gt;&lt;h3&gt;Accessing System Key Store Credentials&lt;/h3&gt;&lt;p&gt;Once the system key store is configured, the KeyChain API offers functions such as requesting a client certificate for authenticating with an SSL server.  The first time an application requests access, the user is prompted with a list of available certificates and can select one to grant access to that certificate to the application.  If the user chooses to allow access to a certificate, a string alias name for the certificate is returned to the application.  The application can then use the alias to access the certificate in the future without further user involvement.&lt;/p&gt;&lt;p&gt;The code below illustrates how an application can prompt the user to select a credential alias and grant access to the application.  KeyChain will remember this selection such that the same application can save the credential alias selection and have access to the same certificate in future.  For example, the Email application for ICS has implemented this feature in its Server Settings screen.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  KeyChain.choosePrivateKeyAlias(this,
    new KeyChainAliasCallback() {

        public void alias(String alias) {
            // Credential alias selected.  Remember the alias selection for future use.
            if (alias != null) saveAlias(alias);
        }
    },
    new String[] {"RSA", "DSA"}, // List of acceptable key types. null for any
    null,                        // issuer, null for any
    "internal.example.com",      // host name of server requesting the cert, null if unavailable
    443,                         // port of server requesting the cert, -1 if unavailable
    null);                       // alias to preselect, null if unavailable&lt;/code&gt;&lt;/pre&gt;&lt;a href="http://4.bp.blogspot.com/-z5bVnwKbMNk/T193IeaZ1gI/AAAAAAAABNw/c8snqQ3q05M/s1600/choose_cert_2.png"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 225px; height: 400px;" src="http://4.bp.blogspot.com/-z5bVnwKbMNk/T193IeaZ1gI/AAAAAAAABNw/c8snqQ3q05M/s400/choose_cert_2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5719421039270286850" /&gt;&lt;/a&gt;&lt;p&gt;Once an application has been granted access to the certificate, it can access the private key through the &lt;a href="http://developer.android.com/reference/android/security/KeyChain.html#getPrivateKey(android.content.Context, java.lang.String)"&gt;getPrivateKey()&lt;/a&gt; method.  It is worth noting that as with any &lt;a href="http://developer.android.com/reference/java/security/PrivateKey.html"&gt;PrivateKey&lt;/a&gt; objects, the application should not make assumptions about the encoding.  For example, on some implementations the PrivateKey object may just be an opaque representation of a key stored in a hardware key store.&lt;/p&gt;&lt;p&gt;Here’s a sample code snippet that demonstrates the use of private key retrieved from the key store for signing:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;    PrivateKey privateKey = KeyChain.getPrivateKey(context, savedAlias);
    if (privateKey != null) {
        ...
        Signature signature = Signature.getInstance("SHA1withRSA");
        signature.initSign(privateKey);
        ...
    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A common use of the private key is for SSL client authentication.  This can be implemented by using an &lt;a href="http://developer.android.com/reference/javax/net/ssl/HttpsURLConnection.html"&gt;HttpsURLConnection&lt;/a&gt; with a custom &lt;a href="http://developer.android.com/reference/javax/net/ssl/X509KeyManager.html"&gt;X509KeyManager&lt;/a&gt; that returns the PrivateKey retrieved from the KeyChain API.  The open source Email application for ICS uses KeyChain with an &lt;a href="http://developer.android.com/reference/javax/net/ssl/X509ExtendedKeyManager.html"&gt;X509ExtendedKeyManager&lt;/a&gt;.  To learn more, have a look at the source code (in SSLUtils.java).&lt;/p&gt;&lt;p&gt;This API provides a unified way to access the system key store credentials.  If your application uses client certificates (take note: enterprise email client or web browser developers) you should definitely look into the KeyChain API for your next update!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6755709643044947179-4475335699969734409?l=android-developers.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/android?a=_DcFkTmK7d4:KNYHra4iYGE:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?i=_DcFkTmK7d4:KNYHra4iYGE:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=_DcFkTmK7d4:KNYHra4iYGE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=_DcFkTmK7d4:KNYHra4iYGE:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/android/~4/_DcFkTmK7d4" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/android/~3/_DcFkTmK7d4/unifying-key-store-access-in-ics.html</link><author>noreply@blogger.com (Tim Bray)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-f7QriOX9amI/T16HXPqp6-I/AAAAAAAABNY/1pt9zD49uFI/s72-c/extract_cert_1.png" height="72" width="72" /><feedburner:origLink>http://android-developers.blogspot.com/2012/03/unifying-key-store-access-in-ics.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6755709643044947179.post-1770198571571621188</guid><pubDate>Tue, 06 Mar 2012 18:10:00 +0000</pubDate><atom:updated>2012-03-06T10:37:42.039-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Google Play</category><category domain="http://www.blogger.com/atom/ns#">Android Market</category><title>Introducing Google Play</title><description>&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;[This post is by Kenneth Lui, Android Developer Ecosystem. —Dirk Dougherty]&lt;/span&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;a href="http://3.bp.blogspot.com/-ZrvsOxe_OBA/T1W6xuCBMkI/AAAAAAAABZ4/uwCvJl0YRYs/s1600/gplay_logo_web_white.png" imageanchor="1" style="clear:left; float:left;margin-left:0em; margin-right:1em;margin-bottom:2.5em;margin-top:1.5em;"&gt;&lt;img itemprop="image" border="0" width="300" src="http://3.bp.blogspot.com/-ZrvsOxe_OBA/T1W6xuCBMkI/AAAAAAAABZ4/uwCvJl0YRYs/s400/gplay_logo_web_white.png" /&gt;&lt;/a&gt;&lt;/div&gt;For more than a year we’ve been focused on expanding the reach, content, and monetization opportunities of Android Market. We started by extending the store to users on the web and then went on to add books, movies, and music. The number of people who have visited, registered, and downloaded from the store has been amazing.&lt;br /&gt;
&lt;br /&gt;
&lt;span itemprop="description"&gt;Today we’re &lt;a href="http://googleblog.blogspot.com/2012/03/introducing-google-play-all-your.html"&gt;launching Google Play&lt;/a&gt;, an integrated destination for apps, books, movies, and music, accessible to users on Android devices and to anyone on the Web.&lt;/span&gt; As part of this launch, Google Play replaces and extends Android Market &amp;mdash; users everywhere can now find their favorite apps and games in Google Play, with other digital content, all in one place.&lt;br /&gt;
&lt;br /&gt;
We believe that with a strong brand, compelling offerings, and a seamless purchasing and consumption experience, Google Play will drive more traffic and revenue to the entire ecosystem.&lt;br /&gt;
&lt;br /&gt;
We’ll be investing in the brand to bring Google Play to as many people as possible, and we’ll also invest in the latest digital content to keep Google Play fresh, relevant, and engaging. Apps and games remain the core of Google Play, so we’ll continue investing in new ways to connect users with their favorite apps, and developers with new customers.&lt;br /&gt;
&lt;br /&gt;
&lt;p style="text-align: center;"&gt;&lt;iframe width="640" height="360" src="http://www.youtube.com/embed/g5SzWc8-X0M?rel=0" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;/p&gt;&lt;br /&gt;
As we grow and promote Google Play around the world, we’ll be marketing your apps and games at the same time. Our policies have not changed and our goal is still the same &amp;mdash; to create a great, open marketplace for distributing Android apps.&lt;br /&gt;
&lt;br /&gt;
Google Play is built on the same infrastructure as Android Market, so the transition for users and developers will be seamless. Users can sign into their existing accounts with the same credentials as before and purchase content using the same payment methods. As a developer, there’s no change needed to your published products and you can continue to use the same publishing tools to put your app in front of hundreds of millions of Android users. If your app was in Android Market yesterday, it’s in Google Play today. &lt;br /&gt;
&lt;br /&gt;
We’ll be rolling out Google Play to devices in a phased OTA update, starting today and continuing over the days to come. With the update, the Android Market app will upgrade to the Play Store app and the Music, Videos, and Books apps will upgrade to Play Music, Play Movies, and Play Books. This update is for devices running Android 2.2 or higher, and users on other devices will continue to have the same access to your apps as before. &lt;br /&gt;
&lt;br /&gt;
You can start sending customers to your products in Google Play right away. Check out the updated &lt;a href="http://www.android.com/developers/branding.html#google_play"&gt;“Get it on Google Play”&lt;/a&gt; badges and look for an email with more details on the transition. In the meantime, you can &lt;!--learn more about Google Play in the Official Google Blog--&gt; check out the Google Play web site at the link below and join the discussion on &lt;a href="https://plus.google.com/108967384991768947849/posts/6KE34877xjB"&gt;+Android&amp;nbsp;Developers&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;p style="margin-left:1.5em;margin-bottom:1.5em;"&gt;&lt;a href="http://play.google.com/about"&gt;http://play.google.com&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6755709643044947179-1770198571571621188?l=android-developers.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/android?a=csJwRSHwXME:miR2DpYdChQ:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?i=csJwRSHwXME:miR2DpYdChQ:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=csJwRSHwXME:miR2DpYdChQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=csJwRSHwXME:miR2DpYdChQ:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/android/~4/csJwRSHwXME" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/android/~3/csJwRSHwXME/introducing-google-play.html</link><author>noreply@blogger.com (Dirk Dougherty)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-ZrvsOxe_OBA/T1W6xuCBMkI/AAAAAAAABZ4/uwCvJl0YRYs/s72-c/gplay_logo_web_white.png" height="72" width="72" /><feedburner:origLink>http://android-developers.blogspot.com/2012/03/introducing-google-play.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6755709643044947179.post-2573571652292551746</guid><pubDate>Tue, 06 Mar 2012 01:00:00 +0000</pubDate><atom:updated>2012-03-05T19:09:20.754-08:00</atom:updated><title>Android Apps Break the 50MB Barrier</title><description>&lt;p&gt;Android applications have historically been limited to a maximum size of 50MB. This works for most apps, and smaller is usually better — every megabyte you add makes it harder for your users to download and get started. However, some types of apps, like high-quality 3D interactive games, require more local resources.&lt;/p&gt;&lt;p&gt;So today, we’re expanding the Android app size limit to 4GB.&lt;/p&gt;&lt;p&gt;The size of your APK file will still be limited to 50MB to ensure secure on-device storage, but you can now attach expansion files to your APK.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Each app can have two expansion files, each one up to 2GB, in whatever format you choose.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Android Market will host the files to save you the hassle and cost of file serving.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Users will see the total size of your app and all of the downloads before they install/purchase.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;On most newer devices, when users download your app from Android Market, the expansion files will be downloaded automatically, and the refund period won’t start  until the expansion files are downloaded. On older devices, your app will download the expansion files the first time it runs, via a downloader library which we’ve provided below.&lt;/p&gt;&lt;p&gt;While you can use the two expansion files any way you wish, we recommend that one serve as the initial download and be rarely if ever updated; the second can be smaller and serve as a “patch carrier,” getting versioned with each major release.&lt;/p&gt;&lt;h3&gt;Helpful Resources&lt;/h3&gt;&lt;p&gt;In order to make expansion file downloading as easy as possible for developers, we're providing sample code and libraries in the &lt;a href="http://developer.android.com/sdk/adding-components.html"&gt;Android SDK Manager&lt;/a&gt;.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;In the Google Market Licensing package, an updated License Verification Library (LVL). This minor update mostly adds the ability to obtain expansion file details from the licensing server.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;From the Google Market APK Expansion package, the downloader service example.  &lt;a href="http://developer.android.com/sdk/adding-components.html#InstallingComponents"&gt;The library&lt;/a&gt; makes it relatively simple to implement a downloader service in your application that follows many of our best practices, including resuming downloads and displaying a progress notification.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Because many developers may not be used to working with one or two large files for all of their secondary content, the example code also includes support for using a Zip file as the secondary file. The Zip example implements a reasonable patching strategy that allows for the main expansion file to “patch” the APK and the patch file to “patch” both the APK and the main expansion file by searching for asset files in all three places, in the order patch-&gt;main-&gt;APK. &lt;/p&gt;&lt;h3&gt;Expansion File Basics&lt;/h3&gt;&lt;p&gt;Expansion files have a specific naming convention and are located in a specific place for each app.  As expansion files are uploaded to the publisher site, they are assigned a version code based upon the version of the APK that they are associated with.  The naming convention and location are as follows:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Location: &lt;code&gt;&amp;lt;shared-storage&gt;/Android/obb/&amp;lt;package-name&gt;/&lt;/code&gt;&lt;br/&gt;Filename: &lt;code&gt;[main|patch].&amp;lt;expansion-version&gt;.&amp;lt;package-name&gt;.obb&lt;/code&gt;&lt;br/&gt;Example: &lt;code&gt;/sdcard/Android/obb/com.example.myapp/main.5.com.example.myapp.obb&lt;/code&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Expansion files are stored in shared storage. Unlike APK files, they can be read by any application.&lt;/p&gt;&lt;h3&gt;Downloading and Using the Expansion Files&lt;/h3&gt;&lt;p&gt;When the primary activity for the app is created, it should check to make sure the expansion files are available.  The downloader library provides helper functions (for example the “Helpers” class in the code below) to make this easy.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;boolean expansionFilesDelivered() {
    // get filename where main == true and version == 3
    String fileName = Helpers.getExpansionAPKFileName(this, true, 3);
    // does the file exist with FILE_SIZE?
    if (!Helpers.doesFileExist(this, fileName, FILE_SIZE, false)) {
        return false;
    }
    return true;
}&lt;/code&gt;&lt;/pre&gt;&lt;a href="http://1.bp.blogspot.com/-FoijusoKkCY/T1Tzxm_QJvI/AAAAAAAABNA/7qLq48ZwgdI/s1600/APKExpansion.png"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 372px; height: 400px;" src="http://1.bp.blogspot.com/-FoijusoKkCY/T1Tzxm_QJvI/AAAAAAAABNA/7qLq48ZwgdI/s400/APKExpansion.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5716461860644988658" /&gt;&lt;/a&gt;&lt;p&gt;If the file does not exist, fire up the downloader service with &lt;code&gt;DownloaderClientMarshaller.startDownloadServiceIfRequired()&lt;/code&gt;. The downloader will perform an LVL check against the server.  This check will deliver the names of the files, file sizes, and the file URLs.&lt;/p&gt;&lt;p&gt;Once that check has been completed, it will begin downloading the files.  You don’t have to use our download solution, but you might want to because we:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Include a notification UI that provides progress and estimated completion time in layouts customized for ICS and pre-ICS devices&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Resume large files safely&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Handle redirection with appropriate limits&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Run in the background as a service&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Pause and resume downloads when WiFi is not available&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Enjoy! We can’t wait to see what kinds of things developers do with this! For more information about how to use expansion files with your app, read the &lt;a href="http://developer.android.com/guide/market/expansion-files.html "&gt;APK Expansion Files&lt;/a&gt; developer guide.&lt;/p&gt;&lt;p&gt;&lt;i&gt;[This post wasn’t actually written by anyone, but bashed out by a posse of engineering and product-management people. Heavy bashers included Dan Galpin, Ilya Firman, Andy Stadler, Michael Siliski, and Ellie Powers.]&lt;/i&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6755709643044947179-2573571652292551746?l=android-developers.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/android?a=fvyBkdevz0M:M02-9K2fyqo:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?i=fvyBkdevz0M:M02-9K2fyqo:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=fvyBkdevz0M:M02-9K2fyqo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=fvyBkdevz0M:M02-9K2fyqo:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/android/~4/fvyBkdevz0M" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/android/~3/fvyBkdevz0M/android-apps-break-50mb-barrier.html</link><author>noreply@blogger.com (Tim Bray)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-FoijusoKkCY/T1Tzxm_QJvI/AAAAAAAABNA/7qLq48ZwgdI/s72-c/APKExpansion.png" height="72" width="72" /><feedburner:origLink>http://android-developers.blogspot.com/2012/03/android-apps-break-50mb-barrier.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6755709643044947179.post-5432342374374599349</guid><pubDate>Wed, 29 Feb 2012 22:05:00 +0000</pubDate><atom:updated>2012-02-29T14:47:20.951-08:00</atom:updated><title>Android Design V2: Now with stencils</title><description>&lt;img style="border: 5px solid #ddd; float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 150px; " src="http://1.bp.blogspot.com/-wjQccEThR14/T05phaDTH7I/AAAAAAAABLk/zIOLXcxUG5Q/s400/faaborg.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5714620999829495730" /&gt;&lt;p&gt;&lt;i&gt;[This post is by Android designer &lt;a href="https://plus.google.com/102905316931749515082/posts"&gt;Alex Faaborg&lt;/a&gt;, on behalf of the entire User Experience team. —Tim Bray]&lt;/i&gt;&lt;/p&gt;&lt;p&gt;When we initially released &lt;a href="http://developer.android.com/design/index.html"&gt;&lt;i&gt;Android Design&lt;/i&gt;&lt;/a&gt;, by far the number one request we received was for us to release stencils as well.  The fine folks on the Android User Experience team are pleased today to release some official Android Design stencils for your mockup-creating pleasure.  &lt;/p&gt;&lt;a href="http://4.bp.blogspot.com/-gkhwmjszXQ4/T05qjoQROKI/AAAAAAAABLw/oMSw2FzdFb8/s1600/stencilCrop.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 320px;" src="http://4.bp.blogspot.com/-gkhwmjszXQ4/T05qjoQROKI/AAAAAAAABLw/oMSw2FzdFb8/s320/stencilCrop.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5714622137513359522" /&gt;&lt;/a&gt;&lt;p&gt;With these stencils you can now drag and drop your way to beautifully designed Ice Cream Sandwich (Android 4.0) applications, with grace and ease. The stencils feature the rich typography, colors, interactive controls, and icons found throughout Ice Cream Sandwich, along with some phone and tablet outlines to frame your meticulously crafted creations. &lt;/p&gt;&lt;p&gt;Currently we have stencils available for those venerable interactive design powerhouses Adobe® Fireworks®, and Omni® OmniGraffle® and we may expand to other applications® in the future.  The source files for the various icons and controls are also available, created in Adobe® Photoshop®, and Adobe® Illustrator®. &lt;a href="http://developer.android.com/design/downloads"&gt;Here are the downloads&lt;/a&gt;.  &lt;/p&gt;&lt;p&gt;We’ll be updating these stencils over time so, as always, please send in your feedback!&lt;/p&gt;&lt;p&gt;Happy mockup making,&lt;br/&gt;— Your friendly Android Design Droids&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6755709643044947179-5432342374374599349?l=android-developers.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/android?a=wf2vbq7C3CM:2fjXUqmbCXQ:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?i=wf2vbq7C3CM:2fjXUqmbCXQ:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=wf2vbq7C3CM:2fjXUqmbCXQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=wf2vbq7C3CM:2fjXUqmbCXQ:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/android/~4/wf2vbq7C3CM" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/android/~3/wf2vbq7C3CM/android-design-v2-now-with-stencils.html</link><author>noreply@blogger.com (Tim Bray)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-wjQccEThR14/T05phaDTH7I/AAAAAAAABLk/zIOLXcxUG5Q/s72-c/faaborg.jpg" height="72" width="72" /><feedburner:origLink>http://android-developers.blogspot.com/2012/02/android-design-v2-now-with-stencils.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6755709643044947179.post-8609330893032820930</guid><pubDate>Tue, 28 Feb 2012 19:12:00 +0000</pubDate><atom:updated>2012-02-28T18:43:33.224-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Android Market</category><title>New App Stats for Publishers on Android Market</title><description>&lt;br /&gt;
If you've published an app on Android Market, you’ve probably used Application Statistics to help tune your development and marketing efforts. Application Statistics is a set of dashboards in the Developer Console that shows your app’s installation performance across key dimensions such as countries, platform versions, device models, and others. &lt;span itemprop="description"&gt;Today we are making Application Statistics even more powerful for publishers, adding new metrics, new ways to analyze your data, and a redesigned UI that’s much easier to use.&lt;/span&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-uCjSNT-yaGE/T01BDUEwzUI/AAAAAAAABZs/RM6u4SLP8Gk/s1600/app-stats2-user-installs-by-language.png" imageanchor="1" style="clear:right; float:right; margin-left:1em; margin-bottom:1em"&gt;&lt;img  itemprop="image" style="border:5px solid #ddd;" height="373" width="400" src="http://1.bp.blogspot.com/-uCjSNT-yaGE/T01BDUEwzUI/AAAAAAAABZs/RM6u4SLP8Gk/s400/app-stats2-user-installs-by-language.png" /&gt;&lt;/a&gt;&lt;/div&gt;First, we are adding important new installation metrics to the dashboards. You can now see your installations measured by unique users, as well as by unique devices. For user installations, you can view active installs, total installs, and daily installs and uninstalls. For devices, you can see active installs as well as daily installs, uninstalls, and upgrades.&lt;br /&gt;
&lt;br /&gt;
Along with the new metrics, we’re also introducing two new data dimensions &amp;mdash; &lt;em&gt;Carrier&lt;/em&gt; and &lt;em&gt;App Version&lt;/em&gt;. You can use them to track your app’s installation trends across mobile operators or monitor the launch metrics of specific app updates.&lt;br /&gt;
&lt;br /&gt;
To give you visibility over your installation data over &lt;em&gt;time&lt;/em&gt;, we’re adding timeline charts for all metrics and dimensions. At a glance, these charts highlight your app’s installation peaks and longer-term trends, which you can correlate to promotions, app improvements, or other factors. You can even focus in on data inside a dimension by adding specific points (such as individual platform versions or languages) to the timeline.&lt;br /&gt;
&lt;br /&gt;
Finally, we’re bringing you all of the new metrics, dimensions, and timelines in a completely redesigned UI that is faster, more compact, and easier to use. Each dimension is now displayed in dedicated tab, making it easier to click through your stats daily or as often as needed. If you track your stats in another tool, we’re also adding an export capability that lets you download your stats in a single CSV file. &lt;br /&gt;
&lt;br /&gt;
Check out the new Application Statistics next time you visit the &lt;a href="http://market.android.com/publish"&gt;Android Market Developer Console&lt;/a&gt;. We hope they’ll give you new insight into your app’s user base and installation performance. Watch for related announcements soon &amp;mdash; we are continuing to work on bringing you the reporting features you need to manage your products successfully on Android Market.&lt;br /&gt;
&lt;br /&gt;
Please feel free to share any new insights or tips on &lt;a href="https://plus.google.com/108967384991768947849/posts/apwwRdjAQQk
"&gt;+Android Developers&lt;/a&gt;!&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6755709643044947179-8609330893032820930?l=android-developers.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/android?a=CgfcIkHbXKc:wULHsT4bVjI:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?i=CgfcIkHbXKc:wULHsT4bVjI:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=CgfcIkHbXKc:wULHsT4bVjI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=CgfcIkHbXKc:wULHsT4bVjI:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/android/~4/CgfcIkHbXKc" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/android/~3/CgfcIkHbXKc/new-app-stats-for-publishers-on-android.html</link><author>noreply@blogger.com (Dirk Dougherty)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-uCjSNT-yaGE/T01BDUEwzUI/AAAAAAAABZs/RM6u4SLP8Gk/s72-c/app-stats2-user-installs-by-language.png" height="72" width="72" /><feedburner:origLink>http://android-developers.blogspot.com/2012/02/new-app-stats-for-publishers-on-android.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6755709643044947179.post-552000352514140667</guid><pubDate>Thu, 09 Feb 2012 15:20:00 +0000</pubDate><atom:updated>2012-02-09T08:06:11.668-08:00</atom:updated><title>Share With Intents</title><description>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_GTM_W5mVPTU/TQf98KOwFtI/AAAAAAAAAPU/GAn3Efe53UM/s1600/alexlucas.png"&gt;&lt;img style="border: 5px solid #ddd;  float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand; height: 120px;" src="http://2.bp.blogspot.com/_GTM_W5mVPTU/TQf98KOwFtI/AAAAAAAAAPU/GAn3Efe53UM/s400/alexlucas.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5550684275737630418" /&gt;&lt;/a&gt;&lt;p&gt;&lt;i&gt;[This post is by Alexander Lucas, an Android Developer Advocate bent on saving the world 5 minutes. —Tim Bray]&lt;/i&gt;&lt;/p&gt;&lt;p&gt;&lt;i&gt;[Please join &lt;a href="https://plus.google.com/108967384991768947849/posts/ExqhqWWqSP9"&gt;the discussion on Google+&lt;/a&gt;.]&lt;/i&gt;&lt;/p&gt;&lt;p&gt;Intents are awesome. They are my favorite feature of Android development.  They make all sorts of stuff easier.  Want to scan a barcode?  In the olden platforms, if you were lucky, this involved time and effort finding and comparing barcode-scanning libraries that handled as much as possible of camera interaction, image processing, an internal database of barcode formats, and UI cues to the user of what was going on.  If you weren’t lucky, it was a few months of research &amp;amp; haphazard coding to figure out how to do that yourself.&lt;/p&gt;&lt;p&gt;On Android, it’s a declaration to the system that you would like to scan a barcode.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public void scanSomething() {
    // I need things done!  Do I have any volunteers?
    Intent intent = new Intent("com.google.zxing.client.android.SCAN");

    // This flag clears the called app from the activity stack, so users arrive in the expected
    // place next time this application is restarted.
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);

    intent.putExtra("SCAN_MODE", "QR_CODE_MODE");
    startActivityForResult(intent, 0);
}
...
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
    if (requestCode == 0) {
        if (resultCode == RESULT_OK) {
            //  The Intents Fairy has delivered us some data!
            String contents = intent.getStringExtra("SCAN_RESULT");
            String format = intent.getStringExtra("SCAN_RESULT_FORMAT");
            // Handle successful scan
        } else if (resultCode == RESULT_CANCELED) {
            // Handle cancel
        }
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;See that?  That’s &lt;em&gt;nothing&lt;/em&gt;.  That’s 5 minutes of coding, 3 of which were just to look up the name of the result you wanted to pull.  And that was made possible because the Barcode Scanner application is designed to be able to scan barcodes for whatever other applications may need it.&lt;/p&gt;&lt;p&gt;More important, our app is completely decoupled from the BarcodeScanner app.  There’s no integration- in fact, neither application is checking to verify that the other exists.  If the user preferred, they could remove “Barcode Scanner” and replace it with a competing app.  As long as that app supported the same intent, functionality would remain the same.  This decoupling is important.  It’s the easy way.  It’s the &lt;a href="http://en.wikipedia.org/wiki/Larry_Wall#Virtues_of_a_programmer"&gt;lazy&lt;/a&gt; way.  It’s the Android way.&lt;/p&gt;&lt;h3&gt;Sharing Data Using Intents&lt;/h3&gt;&lt;p&gt;One of the most inherently useful Android intents is the Share intent.  You can let the user share data to any service they want, &lt;em&gt;without writing the sharing code yourself&lt;/em&gt;, simply by creating a share intent.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Intent intent=new Intent(android.content.Intent.ACTION_SEND);
intent.setType("text/plain");
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);

// Add data to the intent, the receiving app will decide what to do with it.
intent.putExtra(Intent.EXTRA_SUBJECT, “Some Subject Line”);
intent.putExtra(Intent.EXTRA_TEXT, “Body of the message, woot!”);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;... and starting it with a &lt;a href="http://developer.android.com/reference/android/content/Intent.html#createChooser(android.content.Intent,%20java.lang.CharSequence)"&gt;chooser&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;startActivity(Intent.createChooser(intent, “How do you want to share?”));&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;With these 5 lines of code, you get to bypass authenticating, credential storage/management, web API interaction via http posts, all sorts of things. Where by “bypass”, I mean “have something else take care of.”  Like the barcode scanning intent, all you really had to do was declare that you have something you’d like to share, and let the user choose from a list of takers.  You’re not limited to sending text, either.  Here’s how you’d create an intent to share an image:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;private Intent createShareIntent() {
    ...
    Intent shareIntent = new Intent(Intent.ACTION_SEND);
    shareIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
    shareIntent.setType("image/*");

    // For a file in shared storage.  For data in private storage, use a ContentProvider.
    Uri uri = Uri.fromFile(getFileStreamPath(pathToImage));
    shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
    return shareIntent;
}  &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note that just by using &lt;a href="http://developer.android.com/reference/android/content/Intent.html#setType(java.lang.String)"&gt;setType()&lt;/a&gt; to set a MIME type, you’ve filtered down the list of apps to those that will know what to do with an image file.&lt;/p&gt;&lt;h3&gt;Intents over Integration&lt;/h3&gt;&lt;p&gt;Think about this for a second.  By making the simple assumption that any user of any service (Task Manager, Social Network, Photo sharing site) already has some app on their phone that can share to that service, you can leverage the code that they’ve already written.  This has several awesome implications:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;i&gt;Less UI&lt;/i&gt; — You don’t have to clog up your UI with customized, clickable badges of services you support.  Just add a “share” button.  It’s okay, we’ve made sure all your users know what it does [insert smiley here].&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;i&gt;Leveraged UI&lt;/i&gt; — You can bet that every high-quality web service out there has spent serious time on the UI of their Android app’s “share” activity.  Don’t reinvent the wheel!  Just grab a couple and go for a ride.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Filtered for the user — If I don’t have a Foo-posting app on my phone, there’s a good chance I don’t care about posting to Foo.  Now I won’t see Foo icons everywhere that are useless to me.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;i&gt;Client App Ecosystem&lt;/i&gt; — Much like an email client, anyone can write a client for any service.  Users will use the ones they want, uninstall the ones they don’t.  Your app supports them all.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;i&gt;Forward Compatible with new services&lt;/i&gt; — If some swanky new service springs up out of nowhere with an Android Application, as long as that application knows how to receive the share intent, you already support it.  You don’t spend time in meetings discussing whether or not to wedge support for the new service into your impending Next Release(tm), you don’t burn engineering resources on implementing support as fast as possible, you don’t even upload a new version of anything to Android Market.  Above all, you don’t do any of that again next week, when another new service launches and the whole process threatens to repeat itself.  You just hang back and let your users download an application that makes yours even more useful.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Avoid One-Off Integrations&lt;/h3&gt;&lt;p&gt;For each pro of the Intent approach, integrating support to post to these services one-at-a-time has a corresponding con.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;i&gt;Bad for UI&lt;/i&gt; — If your photo-sharing app has a Foo icon, what you might not immediately understand is that while you’re trying to tell the user “We post to Foo!” what you’re really saying is “We don’t post to Bar, Baz, or let you send the photo over email, sms, or bluetooth.  If we did, there would be icons.  In fact, we probably axed those features because of the space the icons would take on our home screen.  Oh, and we’ll probably use some weird custom UI and make you authenticate through a browser, instead of the Foo client you already have installed.”  I’m not going to name names, but a lot of you are guilty of this.  It’s time to stop.  (I mean it.  Stop.)&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Potentially wasted effort — Let’s say you chose one service, and integrated it into your UI &lt;em&gt;perfectly&lt;/em&gt;.  Through weeks of back-and-forth with Foo’s staff, you’ve got the API and authentication mechanisms down pat, the flow is seamless, everything’s great.  Only problem is that you just wasted all that effort, because none of your user-base particularly cares for Foo.  Ouch!&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;i&gt;Not forward compatible for existing services&lt;/i&gt; — Any breaking changes in the API are your responsibility to fix, quickly, and that fix won’t be active until your users download a newer version of your app.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;i&gt;Won’t detect new services&lt;/i&gt; — This one really hurts.  If a brand new service Baz comes out, and you’ve actually got the engineering cycles to burn, you need to get the SDK, work out the bugs, develop a sharing UI, have an artist draw up your own “edgy” (ugh) but legally distinct version of the app’s logo so you can plaster it on your home screen, work out all the bugs, and launch.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;You will be judged harshly by your users.  And deservedly so.&lt;/p&gt;&lt;h3&gt;Ice Cream Sandwich makes it even easier&lt;/h3&gt;&lt;p&gt;With the release of ICS, a useful tool for sharing called &lt;a href="http://developer.android.com/reference/android/widget/ShareActionProvider.html"&gt;ShareActionProvider&lt;/a&gt; was added to the framework, making the sharing of data across Android applications even easier.  ShareActionProviders let you populate lists of custom views representing ACTION_SEND targets, facilitating (for instance) adding a “share” menu to the ActionBar, and connecting it to whatever data the user might want to send.&lt;/p&gt;&lt;p&gt;Doing so is pretty easy.  Configure the menu items in your Activity’s onCreateOptionsMenu method, like so:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Get the menu item.
    MenuItem menuItem = menu.findItem(R.id.menu_share);
    // Get the provider and hold onto it to set/change the share intent.
    mShareActionProvider = (ShareActionProvider) menuItem.getActionProvider();

    // Attach an intent to this ShareActionProvider.  You can update this at any time,
    // like when the user selects a new piece of data they might like to share.
    mShareActionProvider.setShareIntent(yourCreateShareIntentMethod());

    // This line chooses a custom shared history xml file. Omit the line if using
    // the default share history file is desired.
    mShareActionProvider.setShareHistoryFileName("custom_share_history.xml");
      . . .
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note that you can specify a history file, which will adapt the ordering of share targets based on past user choices.  One shared history file can be used throughout an application, or different history files can be used within the same application, if you want to use a separate history based on what kind of data the user wants to share.  In the above example, a custom history file is used.  If you wish to use the default history for the application, you can omit that line entirely.  &lt;/p&gt;&lt;p&gt;This will help optimize for an important feature of the ShareActionProvider:  The user’s most common ways to share float to the top of the drop-down, with the least used ones disappearing below the fold of the “See More” button.  The most commonly selected app will even become a shortcut right next to the dropdown, for easy one-click access!&lt;/p&gt;&lt;a href="http://2.bp.blogspot.com/-mVQddiSMz0I/TzL2y2Ny5uI/AAAAAAAABKo/ikNPtWiPu4w/s1600/Screenshot_2012-02-08-14-01-21.png"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 180px; height: 320px;" src="http://2.bp.blogspot.com/-mVQddiSMz0I/TzL2y2Ny5uI/AAAAAAAABKo/ikNPtWiPu4w/s320/Screenshot_2012-02-08-14-01-21.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5706895031239108322" /&gt;&lt;/a&gt;&lt;p&gt;You’ll also need to define a custom menu item in XML.  Here’s an example from the &lt;a href="http://developer.android.com/guide/topics/ui/actionbar.html#ShareActionProvider"&gt;ActionBar Dev Guide&lt;/a&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&gt;
&amp;lt;menu xmlns:android="http://schemas.android.com/apk/res/android"&gt;
    &amp;lt;item android:id="@+id/menu_share"
          android:title="@string/share"
          android:showAsAction="ifRoom"
          android:actionProviderClass="android.widget.ShareActionProvider" /&gt;
&amp;lt;/menu&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And with that, you can have an easy sharing dropdown that will look like the screenshot here. Note that you get the nice standard three-dots-two-lines “Share” glyph for free.&lt;/p&gt;&lt;h3&gt;Remember: Smart and Easy&lt;/h3&gt;&lt;p&gt;The share intent is the preferred method of sharing throughout the Android ecosystem. It’s how you share images from Gallery, links from the browser, and apps from Android Market. Intents are the easiest path to writing flexible applications that can participate in a rapidly expanding ecosystem, but they’re also the smart path to writing applications that will stay relevant to your users, letting them share their data to any service they want, no matter how often their preferences change over time.   So take a step back and stop worrying about if your user wants to tweet, digg, post, email, im, mms, bluetooth, NFC, foo, bar or baz something.  Just remember that they want to share it.  Android can take it from there.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6755709643044947179-552000352514140667?l=android-developers.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/android?a=yJ01r7896V0:TsMczEeU7Fw:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?i=yJ01r7896V0:TsMczEeU7Fw:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=yJ01r7896V0:TsMczEeU7Fw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=yJ01r7896V0:TsMczEeU7Fw:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/android/~4/yJ01r7896V0" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/android/~3/yJ01r7896V0/share-with-intents.html</link><author>noreply@blogger.com (Tim Bray)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_GTM_W5mVPTU/TQf98KOwFtI/AAAAAAAAAPU/GAn3Efe53UM/s72-c/alexlucas.png" height="72" width="72" /><feedburner:origLink>http://android-developers.blogspot.com/2012/02/share-with-intents.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6755709643044947179.post-6876646662488307059</guid><pubDate>Thu, 02 Feb 2012 20:31:00 +0000</pubDate><atom:updated>2012-02-02T12:31:04.546-08:00</atom:updated><title>Android Security Update</title><description>&lt;p&gt;Recently, there’s been a lot of news coverage of malware in the mobile space.  Over on our Mobile blog, Hiroshi Lockheimer, VP of Android engineering, has posted &lt;a href="http://googlemobile.blogspot.com/2012/02/android-and-security.html"&gt;Android and Security&lt;/a&gt;.  We think most Android developers will find it interesting reading.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6755709643044947179-6876646662488307059?l=android-developers.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/android?a=N67-3WbgXok:nefZC0pFC0U:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?i=N67-3WbgXok:nefZC0pFC0U:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=N67-3WbgXok:nefZC0pFC0U:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=N67-3WbgXok:nefZC0pFC0U:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/android/~4/N67-3WbgXok" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/android/~3/N67-3WbgXok/android-security-update.html</link><author>noreply@blogger.com (Tim Bray)</author><feedburner:origLink>http://android-developers.blogspot.com/2012/02/android-security-update.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6755709643044947179.post-2262704684721792677</guid><pubDate>Thu, 02 Feb 2012 16:30:00 +0000</pubDate><atom:updated>2012-02-02T08:46:07.246-08:00</atom:updated><title>New Social APIs in Android ICS</title><description>&lt;a href="http://3.bp.blogspot.com/-wevmqYoGX4k/TyoUmDOuBHI/AAAAAAAABJ8/QB7Rf5ccSmc/s1600/_MG_6086.jpg"&gt;&lt;img style="border: 5px solid #ddd; float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand; height: 100px;" src="http://3.bp.blogspot.com/-wevmqYoGX4k/TyoUmDOuBHI/AAAAAAAABJ8/QB7Rf5ccSmc/s200/_MG_6086.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5704394521952781426" /&gt;&lt;/a&gt;&lt;p&gt;&lt;i&gt;[This post is by &lt;a href="https://plus.google.com/u/0/107954099379890493913/posts"&gt;Daniel Lehmann&lt;/a&gt;, Tech Lead on the Android Apps team.&amp;nbsp;&amp;mdash;&amp;nbsp;Tim&amp;nbsp;Bray]&lt;/i&gt;&lt;/p&gt;&lt;p&gt;&lt;i&gt;[We’re trying something new; There’s a &lt;a href="https://plus.google.com/108967384991768947849/108967384991768947849/posts/URQQYg9cyii"&gt;post over on Google+&lt;/a&gt; where we’ll host a discussion of this article.  Daniel Lehmann has agreed to drop by and participate. Come on over and join in!]&lt;/i&gt;&lt;p&gt;With Android Ice Cream Sandwich, we set out to build software that supports emotional connections between humans and the devices they carry. We wanted to build the most personal device that the user has ever owned.&lt;/p&gt;&lt;p&gt;The first ingredient in our recipe is to show users the people that they care about most in a magazine-like way. High-resolution photos replace simple lists of text.&lt;/p&gt;&lt;a href="http://1.bp.blogspot.com/-1LN_CVbvm7Y/Tymru-Sq1II/AAAAAAAABI0/9JIBbvjjoNA/s1600/image00.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 225px;" src="http://1.bp.blogspot.com/-1LN_CVbvm7Y/Tymru-Sq1II/AAAAAAAABI0/9JIBbvjjoNA/s400/image00.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5704279226525078658" /&gt;&lt;/a&gt;&lt;p&gt;The second ingredient is to more prominently visualize their friends’ activities. We show updates from multiple sources wherever a contact is displayed, without the need to open each social networking app individually.&lt;/p&gt;&lt;p&gt;Android is an open platform, and in Ice Cream Sandwich we provide a rich new API to allow any social networking application to integrate with the system. This post explains how apps like Google+ use these APIs, and how other social networks can do the same.&lt;/p&gt;&lt;h3&gt;A few basics&lt;/h3&gt;&lt;p&gt;Since Eclair (Android 2.0),  the system has been able to join contacts from different sources. Android can notice if you are connected to the same person and different networks, and join those into aggregate contacts.&lt;/p&gt;&lt;a href="http://3.bp.blogspot.com/-FZaYd2fySUM/TymsgSSySgI/AAAAAAAABJM/hV1J_QvvNSA/s1600/Joining.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 355px;" src="http://3.bp.blogspot.com/-FZaYd2fySUM/TymsgSSySgI/AAAAAAAABJM/hV1J_QvvNSA/s400/Joining.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5704280073707866626" /&gt;&lt;/a&gt;&lt;p&gt;Essential terms to understand throughout the remainder of this post are:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;a href="http://developer.android.com/reference/android/provider/ContactsContract.RawContacts.html"&gt;&lt;i&gt;RawContact&lt;/i&gt;&lt;/a&gt; is a contact as it exists in one source, for example a friend in Skype.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;i&gt;Data&lt;/i&gt; rows exists for each piece of information that the raw contact contains (name, phone number, email address, etc.).&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;A &lt;i&gt;Contact&lt;/i&gt; joins multiple raw contacts into one aggregate. This is what the user perceives as a real contact in the People and Phone apps.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;A &lt;i&gt;sync adapter&lt;/i&gt; synchronizes its raw contacts with its cloud source. It can be bundled with a Market application (examples: Skype, Twitter, Google+).&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;While users deal with contacts, sync adapters work with their raw contact rows. They own the data inside a raw contact, but by design it is left up to Android to properly join raw contact rows with others.&lt;/p&gt;&lt;p&gt;Contacts sync adapters have a special xml file that describes their content, which is documented in the Android SDK. In the following paragraphs, we’ll assume this file is named contacts.xml.&lt;/p&gt;&lt;p&gt;The Android SDK also contains the application SampleSyncAdapter (and its source code) that implements everything mentioned in here in an easy to understand way.&lt;/p&gt;&lt;h3&gt;High resolution photos&lt;/h3&gt;&lt;p&gt;In Android versions prior to Honeycomb (3.0), contact photos used to be 96x96. Starting with ICS, they now have a thumbnail (which is the 96x96 version) and a display photo. The display photo’s maximum size can vary from device to device (On Galaxy Nexus and Nexus S, it is currently configured to be 256x256, but expect this to vary with future devices). The size as configured can be queried like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;private static int getPhotoPickSize(Context context) {
  // Note that this URI is safe to call on the UI thread.
  Cursor c = context.getContentResolver().query(DisplayPhoto.CONTENT_MAX_DIMENSIONS_URI,
      new String[]{ DisplayPhoto.DISPLAY_MAX_DIM }, null, null, null);
  try {
    c.moveToFirst();
    return c.getInt(0);
  } finally {
    c.close();
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This value is useful if you need to query the picture from the server (as you can specify the right size for the download). If you already have a high resolution picture, there is no need for any resizing on your side; if it is too big, the contacts provider will downsample it automatically.&lt;/p&gt;&lt;p&gt;Up until now, pictures were written using a &lt;a href="http://developer.android.com/reference/android/content/ContentValues.html"&gt;ContentValues&lt;/a&gt; object, just like all the other data rows of the raw contact. While this approach is still supported, it might fail when used with bigger pictures, as there is a size limit when sending ContentValues across process boundaries. The prefered way now is to use an &lt;a href="http://developer.android.com/reference/android/content/res/AssetFileDescriptor.html"&gt;AssetFileDescriptor&lt;/a&gt; and write them using a FileOutputStream instead:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;private static void saveBitmapToRawContact(Context context, long rawContactId, byte[] photo) throws IOException {
    Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
    Uri outputFileUri =
        Uri.withAppendedPath(rawContactUri, RawContacts.DisplayPhoto.CONTENT_DIRECTORY);
    AssetFileDescriptor descriptor = context.getContentResolver().openAssetFileDescriptor(
        outputFileUri, "rw");
    FileOutputStream stream = descriptor.createOutputStream();
    try {
      stream.write(photo);
    } finally {
      stream.close();
      descriptor.close();
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For best results, store uncompressed square photos and let the contacts provider take care of compressing the photo. It will create both a thumbnail and a display photo as necessary.&lt;/p&gt;&lt;p&gt;This API is available on API version 14+. For older versions, we recommend to fallback to the old method using ContentValues and assuming a constant size of 96x96.&lt;/p&gt;&lt;h3&gt;Update streams&lt;/h3&gt;&lt;p&gt;The API for update streams is the biggest new addition for contacts in Ice Cream Sandwich. Sync adapters can now enrich their contact data by providing a social stream that includes text and photos.&lt;/p&gt;&lt;a href="http://3.bp.blogspot.com/-dxfZhChtRd0/Tyms1JTH7wI/AAAAAAAABJY/H621VFXCJE4/s1600/Hier.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand; height: 150px;" src="http://3.bp.blogspot.com/-dxfZhChtRd0/Tyms1JTH7wI/AAAAAAAABJY/H621VFXCJE4/s320/Hier.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5704280432070618882" /&gt;&lt;/a&gt;&lt;p&gt;This API is intended to provide an entry point into your social app to increase user engagement. We chose to only surface the most recent few stream items, as we believe that your social app will always be the best way to interact with posts on your network.&lt;/p&gt;&lt;a href="http://1.bp.blogspot.com/-jXC4b6gTcxE/Tymt2TUwPKI/AAAAAAAABJk/I9dqeYnFjcM/s1600/image01.png"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 180px; height: 320px;" src="http://1.bp.blogspot.com/-jXC4b6gTcxE/Tymt2TUwPKI/AAAAAAAABJk/I9dqeYnFjcM/s320/image01.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5704281551453306018" /&gt;&lt;/a&gt;&lt;p&gt;&lt;a href="http://developer.android.com/reference/android/provider/ContactsContract.Contacts.StreamItems.html"&gt;StreamItems&lt;/a&gt; rows are associated with a raw contact row. They contain the newest updates of that raw contact, along with text, time stamp and comments. They can also have pictures, which are stored in &lt;a href="http://developer.android.com/reference/android/provider/ContactsContract.StreamItems.StreamItemPhotos.html"&gt;StreamItemPhotos&lt;/a&gt;. The number of stream items per raw contact has a limit, which on the current Nexus devices is set to 5, but expect this number to change with future devices. The limit can be queried like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;private static int getStreamItemLimit(Context context) {
  // Note that this URI is safe to call on the UI thread.
  Cursor c = context.getContentResolver().query(StreamItems.CONTENT_LIMIT_URI,
      new String[]{ StreamItems.MAX_ITEMS }, null, null, null);
  try {
    c.moveToFirst();
    return c.getInt(0);
  } finally {
    c.close();
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;When displayed in the People app, stream items from all participating raw contacts will be intermixed and shown chronologically.&lt;/p&gt;&lt;p&gt;The following function shows how to add a stream item to an existing raw contact:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;private static void addContactStreamItem(Context context, long rawContactId, String text,
    String comments, long timestamp, String accountName, String accountType){
  ContentValues values = new ContentValues();
  values.put(StreamItems.RAW_CONTACT_ID, rawContactId);
  values.put(StreamItems.TEXT, "Breakfasted at Tiffanys");
  values.put(StreamItems.TIMESTAMP, timestamp);
  values.put(StreamItems.COMMENTS, comments);
  values.put(StreamItems.ACCOUNT_NAME, accountName);
  values.put(StreamItems.ACCOUNT_TYPE, accountType);
  context.getContentResolver().insert(StreamItems.CONTENT_URI, values);
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can also specify an action that should be executed when a stream item or one of its photos is tapped. To achieve this, specify the receiving Activities in your contacts.xml using the tags &lt;code&gt;viewStreamItemActivity&lt;/code&gt; and &lt;code&gt;viewStreamItemPhotoActivity&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&amp;lt;ContactsAccountType
  xmlns:android="http://schemas.android.com/apk/res/android"
  viewStreamItemActivity="com.example.activities.ViewStreamItemActivity”
  viewStreamItemPhotoActivity="com.example.activities.ViewStreamItemPhotoActivity"&gt;
  &amp;lt;!-- Description of your data types --&gt;
&amp;lt;/ContactsAccountType&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Update streams are available on API version 15+ and are intended to replace the StatusUpdate API. For previous versions, we recommend that you fall back to the StatusUpdates API, which only shows a single text item and no pictures.&lt;/p&gt;&lt;h3&gt;“Me” profile&lt;/h3&gt;&lt;p&gt;Ice Cream Sandwich is the first version of Android that supports the “Me” contact, which is prominently shown at the top of the list of the new People app. This simplifies use-cases that used to be a multi-tap process in previous versions — for example, sharing personal contact data with another person or “navigating home” in a navigation app. Also it allows applications to directly address the user by name and show their photo.&lt;/p&gt;&lt;p&gt;The “Me” profile is protected by the new permissions &lt;code&gt;READ_PROFILE&lt;/code&gt; and &lt;code&gt;WRITE_PROFILE&lt;/code&gt;. The new functionality is powerful; &lt;code&gt;READ_PROFILE&lt;/code&gt; lets developers access users’ personally identifying information.  Please make sure to inform the user on why you require this permission.&lt;/p&gt;&lt;p&gt;The entry point to the new API is &lt;a href="http://developer.android.com/reference/android/provider/ContactsContract.Profile.html"&gt;ContactsContract.Profile&lt;/a&gt; and is available on API version 14+.&lt;/p&gt;&lt;h2&gt;Add connection&lt;/h2&gt;&lt;p&gt;Previously, connecting with users on a social network involved opening the respective social networking app, searching for the person and then connecting (“Friend”, “Follow” etc.). Ice Cream Sandwich has a much slicker approach: When looking at an existing contact in the People application, the user can decide to add this person to another network as well. For example, the user might want to follow a person on Google+ that they already have as a contact in Gmail.&lt;/p&gt;&lt;a href="http://1.bp.blogspot.com/-IsWg8KGPrGs/TymuwS08A4I/AAAAAAAABJw/K-iaBsUYM00/s1600/image00.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 180px; height: 320px;" src="http://1.bp.blogspot.com/-IsWg8KGPrGs/TymuwS08A4I/AAAAAAAABJw/K-iaBsUYM00/s320/image00.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5704282547752272770" /&gt;&lt;/a&gt;&lt;p&gt;Once the user taps one of the “Add connection” commands, the app is launched and can look for the person using the information that is already in the contact. Search criteria are up to the app, but good candidates are name, email address or phone number.&lt;/p&gt;&lt;p&gt;To specify your “Add connection” menu item, use the attributes &lt;code&gt;inviteContactActivity&lt;/code&gt; and &lt;code&gt;inviteContactActionLabel&lt;/code&gt; in your contacts.xml:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&amp;lt;ContactsAccountType
  xmlns:android="http://schemas.android.com/apk/res/android"
  inviteContactActivity="com.example.activities.InviteContactActivity"
  inviteContactActionLabel="@string/invite_action_label"&gt;
  &amp;lt;!-- Description of your data types --&gt;
&amp;lt;/ContactsAccountType&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Be sure to use the same verb as you typically use for adding connections, so that in combination with your app icon the user understands which application is about to be launched.&lt;/p&gt;&lt;p&gt;The “Add connection” functionality is available on API version 14+.&lt;/p&gt;&lt;h3&gt;Contact-view notification&lt;/h3&gt;&lt;p&gt;High-resolution pictures need a lot of space, and social streams quickly become outdated. It is therefore not a good idea to keep the whole contacts database completely in sync with the social network. A well-written sync adapter should take importance of contacts into account; as an example, starred contacts are shown with big pictures, so high-resolution pictures are more important. Your network might also have its own metrics that can help to identify important contacts.&lt;/p&gt;&lt;p&gt;For all other contacts, you can register to receive a notification which is sent by the People app to all sync adapters that contribute to a contact whenever the contact’s detail page is opened. At that point, you can provide additional information. As an example, when the Google+ sync adapter receives this notification, it pulls in the high-resolution photo and most recent social stream posts for that user and writes them to the contacts provider. This can be achieved by adding the &lt;code&gt;viewContactNotifyService&lt;/code&gt; attribute to contacts.xml:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&amp;lt;ContactsAccountType
  xmlns:android="http://schemas.android.com/apk/res/android"
  viewContactNotifyService="com.example.notifier.NotifierService"&gt;
  &amp;lt;!-- Description of your data types --&gt;
&amp;lt;/ContactsAccountType&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;When this Intent is launched, its &lt;code&gt;data&lt;/code&gt; field will point to the URI of the raw contact that was opened.&lt;/p&gt;&lt;p&gt;These notifications are available with API version 14+.&lt;/p&gt;&lt;h3&gt;Summary&lt;/h3&gt;&lt;p&gt;With Ice Cream Sandwich, we improved key areas around high resolution photos and update streams, and simplified the creation of new connections.&lt;/p&gt;&lt;p&gt;Everything outlined in here is done using open APIs that can be implemented by any network that wants to participate. We’re excited to see how developers take advantage of these new features!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6755709643044947179-2262704684721792677?l=android-developers.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/android?a=IK2pKxJiuhU:osBlJukLWCQ:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?i=IK2pKxJiuhU:osBlJukLWCQ:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=IK2pKxJiuhU:osBlJukLWCQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=IK2pKxJiuhU:osBlJukLWCQ:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/android/~4/IK2pKxJiuhU" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/android/~3/IK2pKxJiuhU/new-social-apis-in-android-ics.html</link><author>noreply@blogger.com (Tim Bray)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-wevmqYoGX4k/TyoUmDOuBHI/AAAAAAAABJ8/QB7Rf5ccSmc/s72-c/_MG_6086.jpg" height="72" width="72" /><feedburner:origLink>http://android-developers.blogspot.com/2012/02/new-social-apis-in-android-ics.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6755709643044947179.post-8753602663961406489</guid><pubDate>Mon, 30 Jan 2012 18:00:00 +0000</pubDate><atom:updated>2012-01-30T11:03:30.324-08:00</atom:updated><title>Android Developers on Google+</title><description>&lt;a href="http://1.bp.blogspot.com/-mh0HQ8xUFhU/TybSV8Wd-4I/AAAAAAAABH4/5qdXX_PyYVw/s1600/RUNE4063.jpg"&gt;&lt;img style="border: 5px solid #ddd;float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 200px; height: 200px;" src="http://1.bp.blogspot.com/-mh0HQ8xUFhU/TybSV8Wd-4I/AAAAAAAABH4/5qdXX_PyYVw/s200/RUNE4063.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5703477252530764674" /&gt;&lt;/a&gt;&lt;p&gt;&lt;i&gt;[This post is by &lt;a href="https://plus.google.com/111169963967137030210/posts"&gt;Reto Meier&lt;/a&gt;, Android Developer Relations Tech Lead.&amp;nbsp;&amp;mdash;&amp;nbsp;Tim&amp;nbsp;Bray]&lt;/i&gt;&lt;/p&gt;&lt;p&gt;I’ve been fortunate enough to be involved with Android since the 0.9 preview SDK was released to developers back in 2007. A lot has changed since then, but one thing that hasn’t is the rapid pace at which new tools, resources, and information have become available for us Android developers. Just look at the last few months. &lt;/p&gt;&lt;p&gt;In December &lt;a href="http://developer.android.com/training"&gt;Android Training&lt;/a&gt; launched, with its first set of classes designed to demonstrate the best practices behind building great Android Apps.&lt;/p&gt;&lt;p&gt;Earlier this month, the &lt;a href="http://developer.android.com/design"&gt;&lt;cite&gt;Android design&lt;/cite&gt;&lt;/a&gt; site went live — offering a place to learn about the principles, building blocks, and patterns you need to make good design decisions when creating your Android app interfaces.&lt;/p&gt;&lt;a href="http://2.bp.blogspot.com/-nyTsKF68CBA/TybSlNRJq3I/AAAAAAAABIE/W230SOsvqzU/s1600/AndroidDev-2.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 200px; height: 200px;" src="http://2.bp.blogspot.com/-nyTsKF68CBA/TybSlNRJq3I/AAAAAAAABIE/W230SOsvqzU/s400/AndroidDev-2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5703477514769902450" /&gt;&lt;/a&gt;&lt;p&gt;We’ve got a lot more planned in the coming year, so to help you keep abreast of all the latest Android developer news we’re launching the &lt;a href="https://plus.google.com/108967384991768947849/"&gt;+Android Developers&lt;/a&gt; page on Google+!&lt;/p&gt;&lt;p&gt;One of my favourite things about Google+ is the quality of conversation around posts, so &lt;a href="https://plus.google.com/108967384991768947849/"&gt;+Android Developers&lt;/a&gt; will focus on being a place for the people behind the Android developer experience, and Android developers all around the world, to meet and discuss the latest in Android app development.&lt;/p&gt;&lt;p&gt;We’ll be posting development tips, discussing updates to the SDK and developer tools, highlighting new Android training classes, and posting video and pics from Android developer events around the world.&lt;/p&gt;&lt;p&gt;We’ll also be using Google+ Hangouts to help us all interact even more closely. Starting with weekly broadcast office-hours on Hangouts On Air to answer Android development questions. These will happen every Wednesday at 2pm Pacific Time (10pm UTS) in Mountain View—expect to see these hangouts in more time zones as our teams in London, Sydney, and Tokyo get involved. Each hangout will be &lt;a href="http://www.youtube.com/playlist?list=PL7383D9AADA6E6D55"&gt;recorded for YouTube&lt;/a&gt;, so if you can’t join us live you won’t miss out.&lt;/p&gt;&lt;p&gt;It turns out that hangouts are a lot of fun, so we’ll be doing more of these that feature interviews with Google engineers and 3rd party Android app developers willing to share their tips and experiences.&lt;/p&gt;&lt;p&gt;We’re looking forward to interacting with you even more closely, so add us to your circles, join the conversation by commenting on posts, and join the hangouts. We can't wait to hear what you have to say.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6755709643044947179-8753602663961406489?l=android-developers.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/android?a=FzjTV3ElJcs:atI7g-yrrZc:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?i=FzjTV3ElJcs:atI7g-yrrZc:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=FzjTV3ElJcs:atI7g-yrrZc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=FzjTV3ElJcs:atI7g-yrrZc:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/android/~4/FzjTV3ElJcs" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/android/~3/FzjTV3ElJcs/android-developers-on-google.html</link><author>noreply@blogger.com (Tim Bray)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-mh0HQ8xUFhU/TybSV8Wd-4I/AAAAAAAABH4/5qdXX_PyYVw/s72-c/RUNE4063.jpg" height="72" width="72" /><feedburner:origLink>http://android-developers.blogspot.com/2012/01/android-developers-on-google.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6755709643044947179.post-7750059148144062785</guid><pubDate>Thu, 26 Jan 2012 20:10:00 +0000</pubDate><atom:updated>2012-03-07T22:22:56.293-08:00</atom:updated><title>Say Goodbye to the Menu Button</title><description>&lt;a href="http://4.bp.blogspot.com/-iuj3Ow47b_k/TyG1PTXTodI/AAAAAAAABGo/Z5kHmVtOUF0/s1600/RUNE4057.jpg"&gt;&lt;img style="border: 5px solid #ddd; float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 200px; height: 164px;" src="http://4.bp.blogspot.com/-iuj3Ow47b_k/TyG1PTXTodI/AAAAAAAABGo/Z5kHmVtOUF0/s200/RUNE4057.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5702037877728453074" /&gt;&lt;/a&gt;&lt;p&gt;&lt;i&gt;[This post is by Scott Main, lead tech writer for &lt;a href="http://developer.android.com"&gt;developer.android.com&lt;/a&gt;.&amp;nbsp;&amp;mdash;&amp;nbsp;Tim&amp;nbsp;Bray]&lt;/i&gt;&lt;/p&gt;&lt;p&gt;Before Android 3.0 (Honeycomb), all Android-powered devices included a dedicated Menu button. As a developer, you could use the Menu button to display whatever options were relevant to the user, often using the activity’s built-in options menu. Honeycomb removed the reliance on physical buttons, and introduced the &lt;a href="http://developer.android.com/reference/android/app/ActionBar.html"&gt;ActionBar&lt;/a&gt; class as the standard solution to make actions from the user options immediately visible and quick to invoke. In order to provide the most intuitive and consistent user experience in your apps, you should migrate your designs away from using the Menu button and toward using the action bar. This isn’t a new concept — the action bar pattern has been around on Android even before Honeycomb — but as Ice Cream Sandwich rolls out to more devices, it’s important that you begin to migrate your designs to the action bar in order to promote a consistent Android user experience.&lt;/p&gt;&lt;p&gt;You might worry that it’s too much work to begin using the action bar, because you need to support versions of Android older than Honeycomb. However, it’s quite simple for most apps because you can continue to support the Menu button on pre-Honeycomb devices, but also provide the action bar on newer devices with only a few lines of code changes.&lt;/p&gt;&lt;a href="http://1.bp.blogspot.com/-KIyVJ4DBLdw/TyGbNsLn4hI/AAAAAAAABFs/xgLPIAaEP6I/s1600/image01.png"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 230px; height: 400px;" src="http://1.bp.blogspot.com/-KIyVJ4DBLdw/TyGbNsLn4hI/AAAAAAAABFs/xgLPIAaEP6I/s400/image01.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5702009262728274450" /&gt;&lt;/a&gt;&lt;p&gt;If I had to put this whole post into one sentence, it’d be: Set &lt;a href="http://developer.android.com/guide/topics/manifest/uses-sdk-element.html#target"&gt;&lt;code&gt;targetSdkVersion&lt;/code&gt;&lt;/a&gt; to 14 and, if you use the options menu, surface a few actions in the action bar with &lt;code&gt;showAsAction="ifRoom"&lt;/code&gt;.&lt;/p&gt;&lt;h3&gt;Don’t call it a menu&lt;/h3&gt;&lt;p&gt;Not only should your apps stop relying on the hardware Menu button, but you should stop thinking about your activities using a “menu button” at all. Your activities should provide buttons for important user actions directly in the action bar (or elsewhere on screen). Those that can’t fit in the action bar end up in the &lt;i&gt;action overflow&lt;/i&gt;.&lt;/p&gt;&lt;p&gt;In the screenshot here, you can see an action button for Search and the action overflow on the right side of the action bar.&lt;/p&gt;&lt;p&gt;Even if your app is built to support versions of Android older than 3.0 (in which apps traditionally use the options menu panel to display user options/actions), when it runs on Android 3.0 and beyond, there’s no Menu button. The button that appears in the system/navigation bar represents the action overflow for legacy apps, which reveals actions and user options that have “overflowed off the screen.” &lt;/p&gt;&lt;p&gt;This might seem like splitting hairs over terminology, but the name &lt;i&gt;action overflow&lt;/i&gt; promotes a different way of thinking. Instead of thinking about a menu that serves as a catch-all for various user options, you should think more about which user options you want to display on the screen as actions. Those that don't need to be on the screen can overflow off the screen. Users can reveal the overflow and other options by touching an overflow button that appears alongside the on-screen action buttons.&lt;/p&gt;&lt;h3&gt;Action overflow button for legacy apps&lt;/h3&gt;&lt;p&gt;If you’ve already developed an app to support Android 2.3 and lower, then you might have noticed that when it runs on a device without a hardware Menu button (such as a Honeycomb tablet or Galaxy Nexus), the system adds the action overflow button beside the system navigation. &lt;/p&gt;&lt;a href="http://1.bp.blogspot.com/-u-3KNfy5n9M/TyG235X2rGI/AAAAAAAABHM/g_qGEXBdJW8/s1600/image00.png"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 400px; height: 49px;" src="http://1.bp.blogspot.com/-u-3KNfy5n9M/TyG235X2rGI/AAAAAAAABHM/g_qGEXBdJW8/s400/image00.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5702039674637692002" /&gt;&lt;/a&gt;&lt;!--&lt;a href="http://3.bp.blogspot.com/-OEFZwRHwsFA/TyGbZ_-MsnI/AAAAAAAABF4/rq9uuGlQm8Q/s1600/image00.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 49px;" src="http://3.bp.blogspot.com/-OEFZwRHwsFA/TyGbZ_-MsnI/AAAAAAAABF4/rq9uuGlQm8Q/s400/image00.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5702009474199106162" /&gt;&lt;/a&gt;--&gt;&lt;p&gt;This is a compatibility behavior for legacy apps designed to ensure that apps built to expect a Menu button remain functional. However, this button doesn’t provide an ideal user experience. In fact, in apps that don’t use an options menu anyway, this action overflow button does nothing and creates user confusion. So you should update your legacy apps to remove the action overflow from the navigation bar when running on Android 3.0+ and begin using the action bar if necessary. You can do so all while remaining backward compatible with the devices your apps currently support.&lt;/p&gt;&lt;p&gt;If your app runs on a device without a dedicated Menu button, the system decides whether to add the action overflow to the navigation bar based on which API levels you declare to support in the &lt;a href="http://developer.android.com/guide/topics/manifest/uses-sdk-element.html"&gt;&lt;code&gt;&amp;lt;uses-sdk&gt;&lt;/code&gt;&lt;/a&gt; manifest element. The logic boils down to:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;If you set either &lt;code&gt;minSdkVersion&lt;/code&gt; or &lt;code&gt;targetSdkVersion&lt;/code&gt; to 11 or higher, the system &lt;em&gt;will not&lt;/em&gt; add the legacy overflow button. &lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Otherwise, the system &lt;em&gt;will&lt;/em&gt; add the legacy overflow button when running on Android 3.0 or higher.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The only exception is that if you set &lt;code&gt;minSdkVersion&lt;/code&gt; to 10 or lower, set &lt;code&gt;targetSdkVersion&lt;/code&gt; to 11, 12, or 13, and you do not use &lt;a href="http://developer.android.com/reference/android/app/ActionBar.html "&gt;ActionBar&lt;/a&gt;, the system &lt;em&gt;will&lt;/em&gt; add the legacy overflow button when running your app &lt;em&gt;on a handset&lt;/em&gt; with Android 4.0 or higher. &lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;That exception might be a bit confusing, but it’s based on the belief that if you designed your app to support pre-Honeycomb handsets and Honeycomb tablets, it probably expects handset devices to include a Menu button (but it supports tablets that don’t have one).&lt;/p&gt;&lt;p&gt;So, to ensure that the overflow action button never appears beside the system navigation, you should set the &lt;code&gt;targetSdkVersion&lt;/code&gt; to 14. (You can leave &lt;code&gt;minSdkVersion&lt;/code&gt; at something much lower to continue supporting older devices.)&lt;/p&gt;&lt;h3&gt;Migrating to the action bar&lt;/h3&gt;&lt;p&gt;If you have activities that use the options menu (they implement &lt;a href="http://developer.android.com/reference/android/app/Activity.html#onCreateOptionsMenu(android.view.Menu)"&gt;onCreateOptionsMenu()&lt;/a&gt;), then once the legacy overflow button disappears from the system/navigation bar (because you’ve set &lt;code&gt;targetSdkVersion&lt;/code&gt; to 14), you need to provide an alternative means for the user to access the activity’s actions and other options. Fortunately, the system provides such a means by default: the action bar.&lt;/p&gt;&lt;p&gt;Add &lt;code&gt;showAsAction="ifRoom"&lt;/code&gt; to the &lt;code&gt;&amp;lt;item&gt;&lt;/code&gt; elements representing the activity’s most important actions to show them in the action bar when space is available. For help deciding how to prioritize which actions should appear in the action bar, see &lt;cite&gt;Android Design’s&lt;/cite&gt; &lt;a href="http://developer.android.com/design/patterns/actionbar.html"&gt;Action Bar guide&lt;/a&gt;.&lt;/p&gt;&lt;a href="http://1.bp.blogspot.com/-sUzHJNpXDkw/TyGwS1y-asI/AAAAAAAABGc/5_dEJ8DfhCA/s1600/icon_samples.png"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 315px; height: 60px;" src="http://1.bp.blogspot.com/-sUzHJNpXDkw/TyGwS1y-asI/AAAAAAAABGc/5_dEJ8DfhCA/s400/icon_samples.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5702032440952777410" /&gt;&lt;/a&gt;&lt;p&gt;To further provide a consistent user experience in the action bar, we suggest that you use action icons designed by the Android UX Team where appropriate. The available icons support common user actions such as Refresh, Delete, Attach, Star, Share and more, and are designed for the light and dark Holo themes; they’re available on the &lt;cite&gt;Android Design&lt;/cite&gt;   &lt;a href="http://developer.android.com/design/downloads/index.html"&gt;downloads page&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;If these icons don’t accommodate your needs and you need to create your own, you should follow the &lt;a href="http://developer.android.com/design/style/iconography.html"&gt;Iconography design guide&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;Removing the action bar&lt;/h3&gt;&lt;p&gt;If you don’t need the action bar, you can remove it from your entire app or from individual activities. This is appropriate for apps that never used the options menu or for apps in which the action bar doesn’t meet design needs (such as games). You can remove the action bar using a theme such as &lt;code&gt;Theme.Holo.NoActionBar&lt;/code&gt; or &lt;code&gt;Theme.DeviceDefault.NoActionBar&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;In order to use such a theme and remain backward compatible, you can use Android’s resource system to define different themes for different platform versions, as described by Adam Powell’s post, &lt;a href="http://android-developers.blogspot.com/2012/01/holo-everywhere.html"&gt;Holo Everywhere&lt;/a&gt;. All you need is your own theme, which you define to inherit different platform themes depending on the current platform version.&lt;/p&gt;&lt;p&gt;For example, here’s how you can declare a custom theme for your application:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&amp;lt;application android:theme="@style/NoActionBar"&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Or you can instead declare the theme for individual &lt;code&gt;&amp;lt;activity&gt;&lt;/code&gt; elements.&lt;/p&gt;&lt;p&gt;For pre-Honeycomb devices, include the following theme in &lt;code&gt;res/values/themes.xml&lt;/code&gt; that inherits the standard platform theme:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&amp;lt;resources&gt;
    &amp;lt;style name="NoActionBar" parent="@android:style/Theme"&gt;
        &amp;lt;!-- Inherits the default theme for pre-HC (no action bar) --&gt;
    &amp;lt;/style&gt;
&amp;lt;/resources&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For Honeycomb and beyond, include the following theme in &lt;code&gt;res/values-v11/themes.xml&lt;/code&gt; that inherits a &lt;code&gt;NoActionBar&lt;/code&gt; theme:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&amp;lt;resources&gt;
    &amp;lt;style name="NoActionBar" parent="@android:style/Theme.Holo.NoActionBar"&gt;
        &amp;lt;!-- Inherits the Holo theme with no action bar; no other styles needed. --&gt;
    &amp;lt;/style&gt;
&amp;lt;/resources&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;At runtime, the system applies the appropriate version of the &lt;code&gt;NoActionBar&lt;/code&gt; theme based on the system’s API version.&lt;/p&gt;&lt;h3&gt;Summary&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Android no longer requires a dedicated Menu button, some devices don’t have one, and you should migrate away from using it. &lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Set &lt;a href="http://developer.android.com/guide/topics/manifest/uses-sdk-element.html#target"&gt;&lt;code&gt;targetSdkVersion&lt;/code&gt;&lt;/a&gt; to 14, then test your app on Android 4.0. &lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Add &lt;code&gt;showAsAction="ifRoom"&lt;/code&gt; to menu items you’d like to surface in the action bar.&lt;/p&gt;&lt;/li&gt;&lt;p&gt;&lt;li&gt;If the ActionBar doesn’t work for your app, you can remove it with &lt;code&gt;Theme.Holo.NoActionBar&lt;/code&gt; or &lt;code&gt;Theme.DeviceDefault.NoActionBar&lt;/code&gt;.&lt;/li&gt;&lt;/p&gt;&lt;/ul&gt;&lt;p&gt;For information about how you should design your action bar, see &lt;cite&gt;Android Design’s&lt;/cite&gt; &lt;a href="http://developer.android.com/design/patterns/actionbar.html"&gt;Action Bar guide&lt;/a&gt;. More information about implementing the action bar is also available in the &lt;a href="http://developer.android.com/guide/topics/ui/actionbar.html"&gt;Action Bar developer guide&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6755709643044947179-7750059148144062785?l=android-developers.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/android?a=2N-PP9COf0M:1fvrpPf08ss:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?i=2N-PP9COf0M:1fvrpPf08ss:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=2N-PP9COf0M:1fvrpPf08ss:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=2N-PP9COf0M:1fvrpPf08ss:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/android/~4/2N-PP9COf0M" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/android/~3/2N-PP9COf0M/say-goodbye-to-menu-button.html</link><author>noreply@blogger.com (Tim Bray)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-iuj3Ow47b_k/TyG1PTXTodI/AAAAAAAABGo/Z5kHmVtOUF0/s72-c/RUNE4057.jpg" height="72" width="72" /><feedburner:origLink>http://android-developers.blogspot.com/2012/01/say-goodbye-to-menu-button.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6755709643044947179.post-2318375095485779407</guid><pubDate>Mon, 16 Jan 2012 23:37:00 +0000</pubDate><atom:updated>2012-01-16T15:44:15.437-08:00</atom:updated><title>Southern-hemisphere Developer Labs</title><description>&lt;p&gt;We’ve just scheduled Android Developer Labs for Melbourne (January 31), Sydney (February 3), and Auckland (February 8).  The material is not introductory; it’s aimed at people with existing apps who want to make them better in the era of Ice Cream Sandwich and tablets.  You’ll want to show up with the SDK installed, and a couple of devices.&lt;/p&gt;&lt;p&gt;If this describes you, drop by the &lt;a href="https://sites.google.com/site/androiddeveloperlabs/"&gt;ADL page&lt;/a&gt; and sign up.  You should hurry, because these are not large-scale events and there are more qualified people than there are seats.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6755709643044947179-2318375095485779407?l=android-developers.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/android?a=7cdK06U-jSg:MyFdhTCeqRc:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?i=7cdK06U-jSg:MyFdhTCeqRc:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=7cdK06U-jSg:MyFdhTCeqRc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=7cdK06U-jSg:MyFdhTCeqRc:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/android/~4/7cdK06U-jSg" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/android/~3/7cdK06U-jSg/southern-hemisphere-developer-labs.html</link><author>noreply@blogger.com (Tim Bray)</author><feedburner:origLink>http://android-developers.blogspot.com/2012/01/southern-hemisphere-developer-labs.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6755709643044947179.post-5428686436183648102</guid><pubDate>Thu, 12 Jan 2012 21:00:00 +0000</pubDate><atom:updated>2012-01-12T16:34:42.460-08:00</atom:updated><title>Introducing the Android Design site</title><description>&lt;a href="http://4.bp.blogspot.com/-mvxnJ_jo-Do/Tw3RY2z9a5I/AAAAAAAABCU/aOnMTHkF7MI/s1600/sg.png"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 320px; height: 291px;" src="http://4.bp.blogspot.com/-mvxnJ_jo-Do/Tw3RY2z9a5I/AAAAAAAABCU/aOnMTHkF7MI/s320/sg.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5696439328654060434" /&gt;&lt;/a&gt;&lt;p&gt;&lt;i&gt;[This post is by &lt;a href="https://plus.google.com/110879635926653430880/posts"&gt;Christian Robertson&lt;/a&gt;,  who  leads the Android visual design group. He is also the designer of the Roboto font family.&amp;nbsp;—Tim Bray]&lt;/i&gt;&lt;/p&gt;&lt;p&gt;Ice Cream Sandwich (Android 4.0) is our biggest redesign yet&amp;nbsp;—&amp;nbsp;both for users and developers. We’ve enhanced the UI framework with new interactions and styles that will let you create Android apps that are simpler and more beautiful than ever before.&lt;/p&gt;&lt;p&gt;To help you in that mission, we’re introducing &lt;a href="http://developer.android.com/design/"&gt;&lt;cite&gt;Android Design&lt;/cite&gt;&lt;/a&gt;: the place to learn about principles, building blocks, and patterns for creating world-class Android user interfaces. Whether you’re a UI professional or a developer playing that role, these docs show you how to make good design decisions, big and small.&lt;/p&gt;&lt;p&gt;The Android User Experience Team is committed to helping you design amazing apps that people love, and this is just the beginning. In the coming months, we’ll expand &lt;cite&gt;Android Design&lt;/cite&gt; with more in-depth content. And watch this blog for a series of posts about design, and invitations to Google+ hangouts on the topics you care about most.&lt;/p&gt;&lt;p&gt;So head on over to &lt;a href="http://developer.android.com/design/"&gt;&lt;cite&gt;Android Design&lt;/cite&gt;&lt;/a&gt;, and make something amazing!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6755709643044947179-5428686436183648102?l=android-developers.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/android?a=iHQNI_dgb2w:nCP2ztVbQok:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?i=iHQNI_dgb2w:nCP2ztVbQok:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=iHQNI_dgb2w:nCP2ztVbQok:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=iHQNI_dgb2w:nCP2ztVbQok:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/android/~4/iHQNI_dgb2w" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/android/~3/iHQNI_dgb2w/introducing-android-design-site.html</link><author>noreply@blogger.com (Tim Bray)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-mvxnJ_jo-Do/Tw3RY2z9a5I/AAAAAAAABCU/aOnMTHkF7MI/s72-c/sg.png" height="72" width="72" /><feedburner:origLink>http://android-developers.blogspot.com/2012/01/introducing-android-design-site.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6755709643044947179.post-5058038089639562398</guid><pubDate>Tue, 10 Jan 2012 21:43:00 +0000</pubDate><atom:updated>2012-01-10T15:28:09.269-08:00</atom:updated><title>Levels in Renderscript</title><description>&lt;p&gt;&lt;i&gt;[This post is by &lt;a href="https://plus.google.com/113680924389579925739/posts"&gt;R. Jason Sams&lt;/a&gt;, an Android Framework engineer who specializes in graphics, performance tuning, and software architecture.&amp;nbsp;—Tim Bray]&lt;/i&gt;&lt;/p&gt;&lt;a href="http://1.bp.blogspot.com/-1AN0Pp29JF8/Twy_hmUcPhI/AAAAAAAABBk/e9VKCVmrytY/s1600/jsams.jpg"&gt;&lt;img style="border: 5px solid #ddd; float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 320px; height: 201px;" src="http://1.bp.blogspot.com/-1AN0Pp29JF8/Twy_hmUcPhI/AAAAAAAABBk/e9VKCVmrytY/s320/jsams.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5696138212659707410" /&gt;&lt;/a&gt;&lt;p&gt;For ICS, Renderscript (RS) has been updated with several new features to simplify adding compute acceleration to your application.  RS is interesting for compute acceleration when you have large buffers of data on which you need to do significant processing.  In this example we will look at applying a levels/saturation operation on a bitmap.&lt;/p&gt;&lt;p&gt;In this case, saturation is implemented by multiplying every pixel by a color matrix Levels are typically implemented with several operations.  &lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;Input levels are adjusted.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Gamma correction.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Output levels are adjusted.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Clamp to the valid range.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;A simple implementation of this might look like:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;for (int i=0; i &amp;lt; mInPixels.length; i++) {
    float r = (float)(mInPixels[i] &amp;amp; 0xff);
    float g = (float)((mInPixels[i] &gt;&gt; 8) &amp;amp; 0xff);
    float b = (float)((mInPixels[i] &gt;&gt; 16) &amp;amp; 0xff);

    float tr = r * m[0] + g * m[3] + b * m[6];
    float tg = r * m[1] + g * m[4] + b * m[7];
    float tb = r * m[2] + g * m[5] + b * m[8];
    r = tr;
    g = tg;
    b = tb;

    if (r &amp;lt; 0.f) r = 0.f;
    if (r &gt; 255.f) r = 255.f;
    if (g &amp;lt; 0.f) g = 0.f;
    if (g &gt; 255.f) g = 255.f;
    if (b &amp;lt; 0.f) b = 0.f;
    if (b &gt; 255.f) b = 255.f;

    r = (r - mInBlack) * mOverInWMinInB;
    g = (g - mInBlack) * mOverInWMinInB;
    b = (b - mInBlack) * mOverInWMinInB;

    if (mGamma != 1.0f) {
        r = (float)java.lang.Math.pow(r, mGamma);
        g = (float)java.lang.Math.pow(g, mGamma);
        b = (float)java.lang.Math.pow(b, mGamma);
    }

    r = (r * mOutWMinOutB) + mOutBlack;
    g = (g * mOutWMinOutB) + mOutBlack;
    b = (b * mOutWMinOutB) + mOutBlack;

    if (r &amp;lt; 0.f) r = 0.f;
    if (r &gt; 255.f) r = 255.f;
    if (g &amp;lt; 0.f) g = 0.f;
    if (g &gt; 255.f) g = 255.f;
    if (b &amp;lt; 0.f) b = 0.f;
    if (b &gt; 255.f) b = 255.f;

    mOutPixels[i] = ((int)r) + (((int)g) &amp;lt;&amp;lt; 8) + (((int)b) &amp;lt;&amp;lt; 16)
                    + (mInPixels[i] &amp;amp; 0xff000000);
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This code assumes a bitmap has been loaded and transferred to an integer array for processing.  Assuming the bitmaps are already loaded, this is simple.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;        mInPixels = new int[mBitmapIn.getHeight() * mBitmapIn.getWidth()];
        mOutPixels = new int[mBitmapOut.getHeight() * mBitmapOut.getWidth()];
        mBitmapIn.getPixels(mInPixels, 0, mBitmapIn.getWidth(), 0, 0,
                            mBitmapIn.getWidth(), mBitmapIn.getHeight());&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Once the data is processed with the loop, putting it back into the bitmap to draw is simple.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;        mBitmapOut.setPixels(mOutPixels, 0, mBitmapOut.getWidth(), 0, 0,
                             mBitmapOut.getWidth(), mBitmapOut.getHeight());&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The full code of the application is around 232 lines when you include code to compute the constants for the filter kernel, manage the controls, and display the image.  On the devices I have laying around this takes about 140-180ms to process an 800x423 image.&lt;/p&gt;&lt;a href="http://2.bp.blogspot.com/-6jVhUd2Tyk4/TwzHq8NEgtI/AAAAAAAABBw/1kLwL4oY2Xw/s1600/city2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 600px; " src="http://2.bp.blogspot.com/-6jVhUd2Tyk4/TwzHq8NEgtI/AAAAAAAABBw/1kLwL4oY2Xw/s400/city2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5696147169246216914" /&gt;&lt;/a&gt;&lt;p&gt;What if that is not fast enough?  &lt;/p&gt;&lt;p&gt;Porting the kernel of this image processing to RS (available at &lt;a href="http://code.google.com/p/android-renderscript-samples/source/browse/Levels"&gt;android-renderscript-samples&lt;/a&gt;) is quite simple.  The pixel processing kernel above, reimplemented for RS looks like:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;void root(const uchar4 *in, uchar4 *out, uint32_t x, uint32_t y) {
    float3 pixel = convert_float4(in[0]).rgb;
    pixel = rsMatrixMultiply(&amp;amp;colorMat, pixel);
    pixel = clamp(pixel, 0.f, 255.f);
    pixel = (pixel - inBlack) * overInWMinInB;
    if (gamma != 1.0f)
        pixel = pow(pixel, (float3)gamma);
    pixel = pixel * outWMinOutB + outBlack;
    pixel = clamp(pixel, 0.f, 255.f);
    out-&gt;xyz = convert_uchar3(pixel);
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It takes far fewer lines of code because of the built-in support for vectors of floats, matrix operations, and format conversions.  Also note that there is no loop present.&lt;/p&gt;&lt;p&gt;The setup code is slightly more complex because you also need to load the script.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;        mRS = RenderScript.create(this);
        mInPixelsAllocation = Allocation.createFromBitmap(mRS, mBitmapIn,
                                                          Allocation.MipmapControl.MIPMAP_NONE,
                                                          Allocation.USAGE_SCRIPT);
        mOutPixelsAllocation = Allocation.createFromBitmap(mRS, mBitmapOut,
                                                           Allocation.MipmapControl.MIPMAP_NONE,
                                                           Allocation.USAGE_SCRIPT);
        mScript = new ScriptC_levels(mRS, getResources(), R.raw.levels);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This code creates the RS context.  It then uses this context to create two memory allocations to hold the RS copy of the bitmap data.  Last, it loads the script to process the data.&lt;/p&gt;&lt;p&gt;Also in the source there are a few small blocks of code to copy the computed constants to the script when they change.  Because we reflect the globals from the script this is easy.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;        mScript.set_inBlack(mInBlack);
        mScript.set_outBlack(mOutBlack);
        mScript.set_inWMinInB(mInWMinInB);
        mScript.set_outWMinOutB(mOutWMinOutB);
        mScript.set_overInWMinInB(mOverInWMinInB);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Earlier we noted that there was no loop to process all the pixels.  The RS code that processes the bitmap data and copies the result back looks like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;        mScript.forEach_root(mInPixelsAllocation, mOutPixelsAllocation);
        mOutPixelsAllocation.copyTo(mBitmapOut);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The first line takes the script and processes the input allocation and places the result in the output allocation.  It does this by calling the natively compiled version of the script above once for each pixel in the allocation.  However, unlike the dalvik implementation, the primitives will automatically launch extra threads to do the work.  This, combined with the performance of native code can produce large performance gains.  I’ll show the results with and without the gamma function working because it adds a lot of cost.&lt;/p&gt;&lt;h4&gt;800x423 image&lt;/h4&gt;&lt;table&gt;&lt;tr&gt;&lt;th&gt;Device&lt;/th&gt;&lt;th&gt;Dalvik&lt;/th&gt;&lt;th&gt;RS&lt;/th&gt;&lt;th&gt;Gain&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th&gt;Xoom&lt;/th&gt;&lt;td&gt;174ms&lt;/td&gt;&lt;td&gt;39ms&lt;/td&gt;&lt;td&gt;4.5x&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th&gt;Galaxy Nexus&lt;/th&gt;&lt;td&gt;139ms&lt;/td&gt;&lt;td&gt;30ms&lt;/td&gt;&lt;td&gt;4.6x&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th&gt;Tegra 30 device&lt;/th&gt;&lt;td&gt;136ms&lt;/td&gt;&lt;td&gt;19ms&lt;/td&gt;&lt;td&gt;7.2x&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;h4&gt;800x423 image with gamma correction&lt;/h4&gt;&lt;table&gt;&lt;tr&gt;&lt;th&gt;Device&lt;/th&gt;&lt;th&gt;Dalvik&lt;/th&gt;&lt;th&gt;RS&lt;/th&gt;&lt;th&gt;Gain&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th&gt;Xoom&lt;/th&gt;&lt;td&gt;994ms&lt;/td&gt;&lt;td&gt;259ms&lt;/td&gt;&lt;td&gt;3.8x&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th&gt;Galaxy Nexus&lt;/th&gt;&lt;td&gt;787ms&lt;/td&gt;&lt;td&gt;213ms&lt;/td&gt;&lt;td&gt;3.7x&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;th&gt;Tegra 30 device&lt;/th&gt;&lt;td&gt;783ms&lt;/td&gt;&lt;td&gt;104ms&lt;/td&gt;&lt;td&gt;7.5x&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;p&gt;These large gains represent a large return on the simple coding investment shown above.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6755709643044947179-5058038089639562398?l=android-developers.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/android?a=MwdUsePnIWE:RIVcqQJP4yw:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?i=MwdUsePnIWE:RIVcqQJP4yw:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=MwdUsePnIWE:RIVcqQJP4yw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=MwdUsePnIWE:RIVcqQJP4yw:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/android/~4/MwdUsePnIWE" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/android/~3/MwdUsePnIWE/levels-in-renderscript.html</link><author>noreply@blogger.com (Tim Bray)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-1AN0Pp29JF8/Twy_hmUcPhI/AAAAAAAABBk/e9VKCVmrytY/s72-c/jsams.jpg" height="72" width="72" /><feedburner:origLink>http://android-developers.blogspot.com/2012/01/levels-in-renderscript.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6755709643044947179.post-8646760043976821672</guid><pubDate>Tue, 03 Jan 2012 21:35:00 +0000</pubDate><atom:updated>2012-01-03T14:01:28.323-08:00</atom:updated><title>Holo Everywhere</title><description>&lt;p&gt;&lt;i&gt;[This post is by &lt;a href="https://plus.google.com/107708120842840792570/posts"&gt;Adam Powell&lt;/a&gt;, an Android Framework engineer who cares about style. —Tim Bray]&lt;/i&gt;&lt;/p&gt;&lt;p&gt;Android 4.0 showcases the Holo theme family, further refined since its debut in Android 3.0. But as most developers know, a new system theme for some Android devices isn’t a new or uncommon event. For developers new system themes mean more design targets for their apps. Using system themes means developers can take advantage of a user’s existing expectations and it can save a lot of production time, but only if an app designer can reliably predict the results. Before Android 4.0 the variance in system themes from device to device could make it difficult to design an app with a single predictable look and feel. We set out to improve this situation for the developer community in Ice Cream Sandwich and beyond.&lt;/p&gt;&lt;div style="float:left; margin: 5px 20px 10px 0;"&gt;&lt;img style="margin:0 0 0 0;width: 240px; height: 400px;" src="http://3.bp.blogspot.com/-Ih4mfw7ugas/TwNnpaoc79I/AAAAAAAABAE/BmBauVfE7OA/s400/Screenshot_2011-11-17-22-19-53.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5693508315147726802" /&gt;&lt;p style="text-align: center;"&gt;Theme.Holo&lt;/p&gt;&lt;/div&gt;&lt;p&gt;If you’re not already familiar with Android’s style and theme system, you should read &lt;a href="http://developer.android.com/guide/topics/ui/themes.html"&gt;Styles and Themes&lt;/a&gt; before continuing.&lt;/p&gt;&lt;h3&gt;Compatibility Standard&lt;/h3&gt;&lt;p&gt;In Android 4.0, Holo is different. We’ve made the inclusion of the unmodified Holo theme family a compatibility requirement for devices running Android 4.0 and forward. If the device has Android Market it will have the Holo themes as they were originally designed.&lt;/p&gt;&lt;p&gt;This standardization goes for all of the public Holo widget styles as well. The Widget.Holo styles will be stable from device to device, safe for use as parent styles for incremental customizations within your app.&lt;/p&gt;&lt;p&gt;The Holo theme family in Android 4.0 consists of the themes Theme.Holo, Theme.Holo.Light, and Theme.Holo.Light.DarkActionBar. Examples of these themes in action are shown in the screenshots lining this post.&lt;/p&gt;&lt;p&gt;To use a Holo theme, explicitly request one from your manifest on your activity or application element, e.g. &lt;code&gt;android:theme="@android:style/Theme.Holo"&lt;/code&gt;. Your app will be displayed using the unmodified theme on all compatible Android 4.0 devices. The Holo themes may also be used as stable parent themes for app-level theme customizations.&lt;/p&gt;&lt;h3&gt;What about device themes?&lt;/h3&gt;&lt;p&gt;We have no desire to restrict manufacturers from building their own themed experience across their devices. In fact we’ve gone further to make this even easier. In Android 4.0’s API (level 14) we’ve added a new public theme family to complement the Holo family introduced in Android 3.0: DeviceDefault. DeviceDefault themes are aliases for the device’s native look and feel. The DeviceDefault theme family and widget style family offer ways for developers to target the device’s native theme with all customizations intact.&lt;/p&gt;&lt;div style="float:right;margin: 5px 0 10px 20px;"&gt;&lt;img style="margin:0 0 0 0;width: 240px; height: 400px;" src="http://1.bp.blogspot.com/-Mi2BW-8T8eY/TwNpdVemR_I/AAAAAAAABAc/-oOTaZ5M4_A/s400/Screenshot_2011-11-17-22-23-18.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5693510306629044210" /&gt;&lt;p style="text-align: center;"&gt;Theme.Holo.Light&lt;/p&gt;&lt;/div&gt;&lt;p&gt; Formally separating these theme families will also make future merges easier for manufacturers updating to a new platform version, helping more devices update more quickly. Google’s Nexus devices alias DeviceDefault to the unmodified Holo themes.&lt;/p&gt;&lt;h3&gt;Making use of your chosen theme&lt;/h3&gt;&lt;p&gt;We’ve added a number of theme attributes to report common metrics and color palette info to apps that want to fit in with a theme. These include highlight colors, default padding and margins for common UI elements such as list items, and more. Apps that wish to integrate with their chosen theme (both Holo and DeviceDefault included) can refer to these theme attributes as in the examples below:&lt;/p&gt;&lt;p&gt;Sample button with system-supplied touch highlight:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&amp;lt;ImageButton android:id="@+id/my_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/button_icon"
    android:background="?android:attr/selectableItemBackground" /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Sample widget with a custom pressedHighlightColor attribute, value retrieved from the system theme:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&amp;lt;MyWidget android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    myapp:pressedHighlightColor="?android:attr/colorPressedHighlight" /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Sample list item layout using system-supplied metrics and text appearance:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&amp;lt;LinearLayout android:layout_width="match_parent"
    android:layout_height="?android:attr/listPreferredItemHeight"
    android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
    android:paddingRight="?android:attr/listPreferredItemPaddingRight"&gt;
    &amp;lt;TextView android:id="@+id/text"
        android:textAppearance="?android:attr/textAppearanceListItem" /&gt;
    &amp;lt;!-- Other views here --&gt;
&amp;lt;/LinearLayout&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div style="float:left; margin: 5px 20px 10px 0;"&gt;&lt;img style="margin:0 0 0 0;width: 240px; height: 400px;" src="http://1.bp.blogspot.com/-99NqKnTQ2Ew/TwNp6O1LBVI/AAAAAAAABAo/TIQZ27oOhd4/s400/Screenshot_2011-11-17-22-24-28.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5693510803060884818"  /&gt;&lt;p style="text-align: center;"&gt;Theme.Holo.Light.DarkActionBar&lt;br/&gt;(Available in API level 14 and above)&lt;/p&gt;&lt;/div&gt;&lt;h3&gt;Defaults for Older Apps&lt;/h3&gt;&lt;p&gt;If an app does not explicitly request a theme in its manifest, Android 4.0 will determine the default theme based on the app’s targetSdkVersion to maintain the app’s original expectations: For values less than 11, &lt;code&gt;@android:style/Theme&lt;/code&gt;; between 11 and 13 &lt;code&gt;@android:style/Theme.Holo&lt;/code&gt;; and for 14 and higher &lt;code&gt;@android:style/Theme.DeviceDefault&lt;/code&gt;.&lt;/p&gt;&lt;h3&gt;Using Holo while supporting Android 2.x&lt;/h3&gt;&lt;p&gt;Most Android developers will still want to support 2.x devices for a while as updates and new devices continue to roll out. This doesn’t stop you from taking advantage of newer themes on devices that support them though. Using Android’s resource system you can define themes for your app that are selected automatically based on the platform version of the device it’s running on.&lt;/p&gt;&lt;p&gt;&lt;em&gt;Theme.Holo and Theme.Holo.Light have been available since API level 11, but Theme.Holo.Light.DarkActionBar is new in API level 14.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;res/values/themes.xml:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&amp;lt;resources&gt;
    &amp;lt;style name="MyTheme" parent="&lt;b&gt;@android:style/Theme&lt;/b&gt;"&gt;
        &amp;lt;!-- Any customizations for your app running on pre-3.0 devices here --&gt;
    &amp;lt;/style&gt;
&amp;lt;/resources&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;res/values-v11/themes.xml:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&amp;lt;resources&gt;
    &amp;lt;style name="MyTheme" parent="&lt;b&gt;@android:style/Theme.Holo&lt;/b&gt;"&gt;
        &amp;lt;!-- Any customizations for your app running on devices with Theme.Holo here --&gt;
    &amp;lt;/style&gt;
&amp;lt;/resources&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Finally, in AndroidManifest.xml:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&amp;lt;!-- [...] --&gt;
    &amp;lt;application android:name="MyApplication"
            android:label="@string/application_label"
            android:icon="@drawable/app_icon"
            android:hardwareAccelerated="true"
            android:theme="@style/MyTheme"&gt;
&amp;lt;!-- [...] --&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can go as far with this idea as you like, up to and including defining your own theme attributes with different values across configurations for use in your other resources. To learn more about Android’s resource system, see &lt;a href="http://developer.android.com/guide/topics/resources/index.html"&gt;Application Resources&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;Final Thoughts&lt;/h3&gt;&lt;p&gt;Android apps running on 4.0 and forward can use the Holo themes and be assured that their look and feel will not change when running on a device with a custom skin. Apps that wish to use the device’s default styling can do so using the DeviceDefault themes that are now in the public API. These changes let you spend more time on your design and less time worrying about what will be different from one device to another. Finally, Android’s resource system allows you to support features from the latest platform version while offering graceful fallback on older devices.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6755709643044947179-8646760043976821672?l=android-developers.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/android?a=_qkac7tku-4:_YSl4q5ifZ8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?i=_qkac7tku-4:_YSl4q5ifZ8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=_qkac7tku-4:_YSl4q5ifZ8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=_qkac7tku-4:_YSl4q5ifZ8:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/android/~4/_qkac7tku-4" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/android/~3/_qkac7tku-4/holo-everywhere.html</link><author>noreply@blogger.com (Tim Bray)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-Ih4mfw7ugas/TwNnpaoc79I/AAAAAAAABAE/BmBauVfE7OA/s72-c/Screenshot_2011-11-17-22-19-53.png" height="72" width="72" /><feedburner:origLink>http://android-developers.blogspot.com/2012/01/holo-everywhere.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-6755709643044947179.post-7567337483684147968</guid><pubDate>Mon, 19 Dec 2011 18:55:00 +0000</pubDate><atom:updated>2011-12-19T14:04:57.515-08:00</atom:updated><title>Watch out for XmlPullParser.nextText()</title><description>&lt;a href="http://4.bp.blogspot.com/-vhNi2_GZQ9U/ToOhtHmmCPI/AAAAAAAAAr0/kfHjHZKQdVE/s1600/jessehawaii.jpg"&gt;&lt;img style="border: 5px solid #ddd; float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 150px; height: 149px;" src="http://4.bp.blogspot.com/-vhNi2_GZQ9U/ToOhtHmmCPI/AAAAAAAAAr0/kfHjHZKQdVE/s200/jessehawaii.jpg" border="0" alt="Jesse Wilson" id="BLOGGER_PHOTO_ID_5657543353414584562" /&gt;&lt;/a&gt;&lt;p&gt;&lt;i&gt;[This post is by &lt;a href="http://www.publicobject.com/"&gt;Jesse Wilson&lt;/a&gt; from the Dalvik team. —Tim Bray]&lt;/i&gt;&lt;/p&gt;&lt;p&gt;Using &lt;a href="http://developer.android.com/reference/org/xmlpull/v1/XmlPullParser.html"&gt;XmlPullParser&lt;/a&gt; is an efficient and maintainable way to parse XML on Android. Historically Android has had two implementations of this interface:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;KXmlParser, via &lt;a href="http://developer.android.com/reference/org/xmlpull/v1/XmlPullParserFactory.html#newPullParser()"&gt;XmlPullParserFactory.newPullParser()&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;ExpatPullParser, via &lt;a href="http://developer.android.com/reference/android/util/Xml.html#newPullParser()"&gt;Xml.newPullParser()&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The implementation from &lt;code&gt;Xml.newPullParser()&lt;/code&gt; had a bug where calls to &lt;code&gt;nextText()&lt;/code&gt; didn’t always advance to the &lt;code&gt;END_TAG&lt;/code&gt; as the documentation promised it would. As a consequence, some apps may be working around the bug with extra calls to &lt;code&gt;next()&lt;/code&gt; or &lt;code&gt;nextTag()&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;    public void parseXml(Reader reader)
            throws XmlPullParserException, IOException {
        XmlPullParser parser = Xml.newPullParser();
        parser.setInput(reader);

        parser.nextTag();
        parser.require(XmlPullParser.START_TAG, null, "menu");
        while (parser.nextTag() == XmlPullParser.START_TAG) {
            parser.require(XmlPullParser.START_TAG, null, "item");
            String itemText = parser.nextText();
            &lt;b&gt;parser.nextTag(); // this call shouldn’t be necessary!&lt;/b&gt;
            parser.require(XmlPullParser.END_TAG, null, "item");
            System.out.println("menu option: " + itemText);
        }
        parser.require(XmlPullParser.END_TAG, null, "menu");
    }

    public static void main(String[] args) throws Exception {
        new Menu().parseXml(new StringReader("&amp;lt;?xml version='1.0'?&gt;"
                + "&amp;lt;menu&gt;"
                + "  &amp;lt;item&gt;Waffles&amp;lt;/item&gt;"
                + "  &amp;lt;item&gt;Coffee&amp;lt;/item&gt;"
                + "&amp;lt;/menu&gt;"));
    }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In Ice Cream Sandwich we changed &lt;code&gt;Xml.newPullParser()&lt;/code&gt; to return a KxmlParser and deleted our ExpatPullParser class. This fixes the &lt;code&gt;nextTag()&lt;/code&gt; bug. Unfortunately, apps that currently work around the bug may crash under Ice Cream Sandwich:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;org.xmlpull.v1.XmlPullParserException: expected: END_TAG {null}item (position:START_TAG &amp;lt;item&gt;@1:37 in java.io.StringReader@40442fa8) 
     at org.kxml2.io.KXmlParser.require(KXmlParser.java:2046)
     at com.publicobject.waffles.Menu.parseXml(Menu.java:25)
 at com.publicobject.waffles.Menu.main(Menu.java:32)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The fix is to call &lt;code&gt;nextTag()&lt;/code&gt; after a call to &lt;code&gt;nextText()&lt;/code&gt; only if the current position is not an &lt;code&gt;END_TAG&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  while (parser.nextTag() == XmlPullParser.START_TAG) {
      parser.require(XmlPullParser.START_TAG, null, "item");
      String itemText = parser.nextText();
      if (parser.getEventType() != XmlPullParser.END_TAG) {
          parser.nextTag();
      }
      parser.require(XmlPullParser.END_TAG, null, "item");
      System.out.println("menu option: " + itemText);
  }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The code above will parse XML correctly on all releases. If your application uses &lt;code&gt;nextText()&lt;/code&gt; extensively, use this helper method in place of calls to &lt;code&gt;nextText()&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  private String safeNextText(XmlPullParser parser)
          throws XmlPullParserException, IOException {
      String result = parser.nextText();
      if (parser.getEventType() != XmlPullParser.END_TAG) {
          parser.nextTag();
      }
      return result;
  }&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Moving to a single XmlPullParser simplifies maintenance and allows us to spend more energy on improving system performance.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6755709643044947179-7567337483684147968?l=android-developers.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/android?a=gEupS9k-CQI:2Ufc2X6nwng:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?i=gEupS9k-CQI:2Ufc2X6nwng:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=gEupS9k-CQI:2Ufc2X6nwng:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/android?a=gEupS9k-CQI:2Ufc2X6nwng:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/android?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/android/~4/gEupS9k-CQI" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/android/~3/gEupS9k-CQI/watch-out-for-xmlpullparsernexttext.html</link><author>noreply@blogger.com (Tim Bray)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-vhNi2_GZQ9U/ToOhtHmmCPI/AAAAAAAAAr0/kfHjHZKQdVE/s72-c/jessehawaii.jpg" height="72" width="72" /><feedburner:origLink>http://android-developers.blogspot.com/2011/12/watch-out-for-xmlpullparsernexttext.html</feedburner:origLink></item></channel></rss>

