Author Archives: Android Developers

Google Play Billing Library 1.0 released

Posted by Neto Marin, Developer Advocate

In June we announced the developer preview for a new Google Play Billing Library. Today, we are pleased to announce the official release of the Play Billing Library 1.0. This library simplifies the development process for Google Play Billing, allowing you to focus your efforts on your app.

Thank you for your valuable feedback and suggestions that helped us reach the 1.0 release. Watch the video below for a quick overview of the library's features.

Before you start

With Play Billing, you can receive payments from users around the world via a payment system they trust and you can take advantage of features and reports in the Play Console to manage and earn more revenue.

If you have never implemented in-app billing in your apps, or you want to know what you can offer using Play Billing Library, read the In-app Billing Overview to familiarize yourself with concepts and terminology that make it easier for you to implement In-app Billing using the Play Billing Library.

Getting started

Play Billing Library is available through Maven repository, and adding Play Billing Library to your project is simple as adding the following dependency into your app's build.gradle file:

dependencies {
    ...
    compile 'com.android.billingclient:billing:1.0'
}

The Play Billing Library 1.0 automatically adds the com.android.vending.BILLING permission to your APK. This means you no longer need to manually include it in your application module's manifest.

BillingClient and PurchasesUpdatedListener

These classes are the most important pieces when integrating the library into your Android app. The BillingClient is the bridge between your app and Google Play. You will use it for listing available products, starting the billing flow for in-app products or subscriptions (i.e. opening the payment interface), getting user purchases, and creating or modifying subscriptions.

When creating your BillingClient instance, you'll need to set a PurchasesUpdatedListener. This allows your app to receive updates from the In-app Billing API, including transaction results after the billing flow, as well as purchases completed outside of your app, e.g. user redeemed a Promo Code or bought a product on another device.

The following code demonstrates how you could override the )">onPurchasesUpdated() method of your PurchasesUpdatedListener:

@Override
void onPurchasesUpdated(@BillingResponse int responseCode,
        List<Purchase> purchases) {
    if (responseCode == BillingResponse.OK
            && purchases != null) {
        for (Purchase purchase : purchases) {
            handlePurchase(purchase);
        }
    } else if (responseCode == BillingResponse.USER_CANCELED) {
        // Handle an error caused by a user canceling the purchase flow.
    } else {
        // Handle any other error codes.
    }
}

You can implement the PurchasesUpdatedListener in your Activity or in any other class you want, according to your app's architecture. And here's the code for creating the BillingClient instance, and setting the PurchasesUpdatedListener:

mBillingClient = BillingClient.newBuilder(mContext)
                              .setListener(mPurchasesUpdatedListener)
                              .build();

Listing and selling products

To sell products in your app, first, you need to add them using the Play Console. For more details about how to add in-app products see the page Administering In-app Billing.

Attention: If this is a brand new app, before adding the products you must publish it to the alpha or beta distribution channel. For more information, see Draft Apps are No Longer Supported.

To get a list of product details with prices for current user, call , com.android.billingclient.api.SkuDetailsResponseListener)">querySkuDetailsAsync(). You must also specify a listener which implements the SkuDetailsResponseListener interface. You can then override the onSkuDetailsResponse() method which notifies the listener when the query finishes, as illustrated by the following sample code:

List<String> skuList = new ArrayList<> ();
skuList.add("premiumUpgrade");
skuList.add("gas");
mBillingClient.querySkuDetailsAsync(SkuType.INAPP , skuList,
    new SkuDetailsResponseListener() {
        @Override
        public void onSkuDetailsResponse(SkuDetailsResult result) {
            // Process the result.
        }
    })

After the user chooses a product to buy, you'll need to start the billing flow and handle the transaction result. To start a purchase request from your app, call the launchBillingFlow() method on the Play Billing Library client. You must call the launchBillingFlow() method (and all the other methods from BillingClient) from the UI thread.

The launchBillingFlow() method needs BillingFlowParams object that contains relevant data for completing the purchase, such as the product ID of the item to purchase and the product type (in this case, SkuType.INAPP). To get an instance of BillingFlowParams, construct it with newBuilder() method:

BillingFlowParams.Builder builder = BillingFlowParams
                                       .newBuilder()
                                       .setSku(skuId).setType(SkuType.INAPP);
int responseCode = mBillingClient.launchBillingFlow(builder.build());

As we mentioned earlier, the transaction result will be sent to the )">onPurchasesUpdated() method. For details how to process the data received on )">onPurchasesUpdated() and how to handle a purchase, check the section Purchase an item in our training guide.

Consuming products

By default, all in-app products are managed. It means that Google Play tracks the product ownership and doesn't allow to buy multiple times. To be able to buy a product again, you must consume the product before it becomes available again.

It's common to implement consumption for in-app products which users may want to purchase multiple times, such as in-game currency or equipment. You typically don't want to implement consumption for in-app products that user purchases once and provide a permanent effect, such as a premium upgrade.

To consume a product, call the consumeAsync() method on the Play Billing Library client and pass in the purchaseToken String value returned when you made the purchase. The consumption result is returned via onConsumeResponse() method of the ConsumeResponseListener interface, that you must override to handle the consumption result.

The following example illustrates consuming a product using the associated purchaseToken:

ConsumeResponseListener listener = new ConsumeResponseListener() {
    @Override
    public void onConsumeResponse(@BillingResponse int responseCode, 
                                  String outToken) {
        if (responseCode == BillingResponse.OK) {
            // Handle the success of the consume operation.
            // For example, increase the number of player's coins,
            // that provide temporary benefits
        }
    }
};
mBillingClient.consumeAsync(purchaseToken, listener);

Sample updated: Trivial Drive V2

With a new library comes a refreshed sample! To help you to understand how to implement in-app billing in your app using the new Play Billing Library, we've rewritten the Trivial Drive sample from the ground up.

Since we released Trivial Drive back in 2013, many new features, devices, and platforms have been added to the Android ecosystem. To reflect this evolution, the Trivial Drive v2 sample now runs on Android TV and Android Wear.

What's next?

Before integrating within your app, you can try the Play Billing Library with the codelab published during Google I/O 2017: Buy and Subscribe: Monetize your app on Google Play.

In this codelab, you will start with a simplified version of Trivial Drive V2 that lets users to "drive" and then you will add in-app billing to it. You'll learn how to integrate purchases and subscriptions as well as the best practices for developing reliable apps that handle purchases.

Get more info on the Play Billing Library and the official reference for classes and methods documentation on the Android Developers website. For a step-by-step guide to implementing the Play Billing Library in your project, visit the library's training class.

We still want your feedback

If you have issues or questions, file a bug report on the Google Issue Tracker, and for issues and suggestions on the sample (like a bug or a new feature), contact us on the Trivial Drive issues page.

For technical questions on implementation, library usage, and best practices, you can use the tags google-play and play-billing-library on StackOverflow or visit the communities on our Google+ page.

Android Things Hackster Contest

Posted by Dave Smith, Developer Advocate for IoT

Android Things lets you build professional, mass-market products on a trusted platform, without previous knowledge of embedded system design. With Android Things you get a turnkey hardware solution and an easy-to-use software development platform based on Android Studio and the Android SDK -- making it easy to build designs that scale to production. Android Things is currently in developer preview and we'd love to see what you can build with our latest release.

Today we are announcing a contest with Hackster and NXP for developers to showcase their use of Android Things with other Google developer platforms. Project ideas should be added to Google's Hackster.io Community by including Android Things as a software component, then registered through the contest page.

Idea Submissions

Submit your project ideas starting today. Ideas submitted by September 29, 2017 are eligible to receive one of 120 Pico Pi i.MX6UL Kits to use in the final design. During this phase, projects do not need to be complete; we just want to see your amazing ideas! We are looking for concepts in the following categories:

  • Smart Home
  • Robotics
  • Smart City
  • Industrial IoT / Manufacturing
  • Retail
  • Entertainment

Project Submissions

Final projects must be submitted by Oct 31, 2017. Your project does not need to be one of the chosen recipients of a Pico kit to be eligible for the grand prize. Winners will receive support from Avnet, Dragon Innovation and Kickstarter to take their ideas from prototype to production. See the contest page for more details.

We are eager to see the projects that you come up with. More importantly, we're excited to see how your work can inspire other developers to create something great with Android Things. To learn more about the benefits of Android Things, watch the recording from the Bootstrapping IoT Products with Android Things webinar. You can also join Google's IoT Developers Community on Google+, a great resource to get updates, ask questions, and discuss ideas.

SafetyNet Verify Apps API, Google Play Protect at your fingertips

Posted by William Luh, Software Engineer

Google Play Protect, which includes the Verify Apps security feature, helps keep users safe from harmful apps. Google Play Protect is available on all Android devices with Google Play installed and provides users with peace of mind and insights into the state of their device security.

App developers can get similar security insights into the installed apps landscape on user devices from the SafetyNet Verify Apps API. This new suite of APIs lets developers determine whether a user's device is protected by Google Play Protect, encourage users not already using Google Play Protect to enable it, and identify any known potentially harmful apps (PHAs) that are installed on the device.

These APIs are especially useful for developers of apps that may be impacted by installed PHAs on the same device as their app. Determining that Google Play Protect is enabled with isVerifyAppsEnabled() gives developers additional assurance that a device is more likely to be clean. If a device doesn't have Google Play Protect enabled, developers can request that the user enable Google Play Protect with enableVerifyApps(). With Google Play Protect enabled, developers can use the listHarmfulApps() method to determine whether there are any potentially harmful apps installed on a user's device. This easy-to-use suite of features does not require API keys and requesting quota.

Enterprise-focused apps in particular may benefit from using the Verify Apps API. Enterprise apps are designed to safeguard a company's data from the outside world. These apps often implement strict enforcements, such as ensuring the mobile device is approved by the enterprise and requiring a strong password for lockscreens. If any of the criteria are not satisfied, the enterprise may revoke credentials and remove sensitive data from the device. Having a mechanism to enforce Google Play Protect and scan for PHAs is another tool to help enterprise app developers keep enterprise data and devices safe.

For better protection, developers should use the attestation API along with the new Verify Apps API. Use the attestation API first to establish that the device has not been modified from a known state. Once the Android system can be trusted, the results from the Verify Apps API can be trusted. Existing attestation API users may find additional benefits in using the Verify Apps API as it may be able to detect on-device PHAs. In general, using multiple signals for anti-abuse detection is encouraged.

To learn how to use this API in your app, check out the developer docs.

Google and Ideas United Launch Program to Support Inclusivity in Game Design

Posted by Daraiha Greene, CS Education in Media Program Manager, Multicultural Strategy, and Kate Brennan and Mathilde Cohen Solal, Google Play

Today, we are thrilled to announce Infinite Deviation: Games. Infinite Deviation is an initiative created by Google Computer Science (CS) in Media and Ideas United in order to tackle issues of representation by bringing creativity and computer science together in unexpected ways -- ensuring that representations of computer scientists are inclusive of women, people of color, the LGBTQIA+ community, people with disabilities, and other underrepresented groups. Last year, Infinite Deviation produced a series of narrative short films to dispel stereotypes in computer science and is excited to collaborate with Google Play to bring the Infinite Deviation program to gaming.

Currently only 23% of people in the gaming industry identify as women and only 3% of game developers are African-American. From ensuring women are represented in video games to giving young girls the chance to create their own games, Google Play is committed to bringing new, diverse voices to gaming. The program gives game designers from all backgrounds the chance to pitch an original mobile game concept and have it developed, published, and promoted in partnership with Google Play. Applicants can submit their mobile game concepts until October 9.

The top three ideas will be chosen by a panel of industry experts and designers will receive the resources and support they need to bring their games to life on Google Play. Games will be judged on creativity and innovation, as well as their ability to tell original stories that resonate with underrepresented audiences.

Participants must have less than two years of professional game design experience in order to be eligible. For more information on the program, including how to apply, you can visit InfiniteDeviation.com.

By promoting original games that resonate with underrepresented audiences, we hope the program creates more favorable perceptions of computer science, bust biases, and nurture acceptance through an activity many enjoy.

Helping indie developers get discovered on Google Play

Posted by Adriana Puchianu, Google Play Developer Marketing

There are increasing growth opportunities for indie game developers, but being one can still feel daunting in today's crowded gaming industry. We've been working hard to help indie developers find an audience and to recognize them for their creativity and innovation. We launched the Indie Corner as a destination for exciting new games along with longstanding indie masterpieces. Since launch, more than 380 games have been featured. Earlier this year, we launched Android Excellence which showcases apps and games that deliver incredible user experiences on Android, while providing another opportunity to be discovered on Google Play.

We've also held several indie games contests across the globe, giving indies the chance to showcase their games and find new audiences. In April, we selected the winner of the second Indie Games Festival in South Korea and we recently announced the top 20 finalists of this year's San Francisco event. Come and see the finalists in person on September 23rd, it's free to attend and open to the public. Soon we'll be bringing back the second Indie Games Contest in Europe too.

Watch François Alliot, the developer of Reigns, an indie game showcased in Android Excellence and the winner of last year's Indie Games Contest in Europe, share how he built a successful games business in the video below.

And, finally, check out our recent Q&A with Spry Fox, makers of the popular game Alphabear, to learn more about what it’s like to be an indie game developer.

How useful did you find this blogpost?

Introducing Android Native Development Kit r16

Posted by Dan Albert, Android NDK Tech Lead

The latest version of the Android Native Development Kit (NDK), Android NDK r16 Beta 1, is now available for download. It is also available in the SDK manager via Android Studio.

NDK r16 is a big milestone for us, because it's the first release that we're ready to recommend that people start migrating to libc++! More on this later.

We've also updated libc++ and its related projects, so this release has improved support for C++1z. Keep in mind that until C++1z becomes C++17, everything included is subject to change.

You can find the release notes for this release here.

libc++ and libandroid_support

The NDK has a library called libandroid_support that backports libc APIs that libc++ depends on that weren't available on older releases. The reason we've been unable to endorse libc++ (as implemented in the NDK) until now has been a lack of confidence in this library. The focus of r16 was to rewrite this library for improved stability.

Since libandroid_support is now a smaller library, your app's behavior should more closely match the behavior of the system. As an example, libandroid_support previously included an alternative implementation of part of stdio. While some features got backported to ICS, it also meant that any bugs in the alternate implementation would be present on all OS releases since the bug was baked into your app. In the new version of libandroid_support, we've removed this so you'll be missing some features on older devices (almost exclusively things that no one uses, like %a support in format strings), but your apps using libc++ will be smaller and more reliable for not having these features.

Switching to libc++

So, why should you switch to libc++? First and foremost, the other STLs will not be supported going forward (this has been noted in our roadmap for quite some time). We've been using libc++ for the Android platform since Lollipop, and that's been a change that our engineers have been overwhelmingly happy with. We were able to make this transition in the platform earlier than we could in the NDK because we didn't need libandroid_support, and could instead just update libc in place.

In contrast to the other STLs currently available in the NDK, libc++ fully supports C++11, C++14, and most of C++1z! Stlport hasn't had an update since 2008, and gnustl (what we call GNU's libstdc++, to avoid confusion with Bionic's libstdc++, which isn't an STL) historically hasn't worked very well with Clang, particularly in headers that are closely tied to compiler builtins like and .

We'll most likely be making libc++ the default in the next NDK release, but for now you can opt-in if you're not using it already by following the instructions below.

Like the other STLs, libc++ is available as both a static and shared library. Which one you should use depends on your specific circumstances as described in our docs, but tl;dr use the static version if you have one and only one shared library in your application, and use the shared one in all other cases.

ndk-build

Add the following to your Application.mk file:

APP_STL := c++_shared
CMake

Pass the following when invoking CMake:

-DANDROID_STL=c++_shared

If you're using CMake via Gradle, add the following to your build.gradle:

externalNativeBuild {
    cmake {
        arguments "-DANDROID_STL=c++_shared"
    }
}
Standalone Toolchain

When you create your standalone toolchain, pass --stl=libc++.

The Future of libandroid_support

If you've read our roadmap, you've seen that we've planned to expand libandroid_support to backport as much of libc/libm as possible. Whenever we've spoken with people about this, we've received lukewarm responses at best. Given that this doesn't seem to be a thing that people are interested in, and that it would be something that increases library size (and therefore APK size, which is something everyone seems very interested in), we no longer plan to do this.

If we've misinterpreted your response or if we haven't heard from you and this is something you want, please let us know!

_FILE_OFFSET_BITS=64

tl;dr: Don't set _FILE_OFFSET_BITS=64 if you want to keep the behavior present in old NDKs.

Historically, setting _FILE_OFFSET_BITS=64 in the NDK did nothing. This feature was not present in the deprecated headers at all. With unified headers, the NDK now has up to date headers with support for this feature.

_FILE_OFFSET_BITS=64 is a macro you can define in your application to get support for a 64-bit off_t in 32-bit code. This works by both making off_t 64-bit (by default it is 32-bit in 32-bit code) and by implicitly replacing calls to APIs like lseek with calls to lseek64.

Support for _FILE_OFFSET_BITS=64 was not added to Android in a single release. One API, lseek64, has always been in bionic. Most APIs were added in Lollipop, and a few more were not added until later releases.

If you're targeting a release that does not support the 64-bit off_t variant of a function you are using and have set _FILE_OFFSET_BITS=64, the function will not be available. This is in contrast to the behavior for r15 and r15b (but matches r15c) where the functions were wrongly exposed with a 32-bit off_t that would be silently truncated.

Note that the 64-bit off_t APIs are still available without _FILE_OFFSET_BITS=64 under different names. For example, instead of lseek, call lseek64. Instead of off_t, use off64_t.

Finally, since this feature is new to the NDK with unified headers, if you just want to return to the pre-unified headers behavior, all you need to do is stop setting _FILE_OFFSET_BITS=64.

For more information about off_t ABI details in bionic, see the Bionic 32-bit ABI bugs doc.

Optimize your Android apps for Chromebooks

Posted by Cheryl Lindo Jones, Mobile App Solutions Consultant, Google Play

As more Chromebooks are enabled with Google Play, now is a great time to optimize your Android app for Chromebooks to reach a larger audience. The changes made to optimize for large screens will benefit mobile devices that are able to project to desktop monitors, like the Samsung Galaxy S8. The current list of Chromebooks that can access the Play Store continues to grow.

There are several differences to consider when optimizing your Android app or game for Chromebooks:

  • Larger screen sizes and higher resolutions
  • Multi-window and resizable-window support
  • Different hardware input methods: keyboard, trackpad, mouse, stylus
  • Convertible Chromebooks enabling use in laptop and tablet modes

Chromebook users can change screen resolutions, switch between various input methods, and convert from laptop to tablet mode at any time, so Android apps and games should handle all of these situations gracefully.

Discoverability on Google Play

If Android apps or games require hardware not available in a Chromebook (like cellular capability or GPS), those titles will not show up on Google Play for Chromebook users, similar to Play on Android tablets. Developers should maximize discoverability on Google Play by doing the following:

Set requested permissions and uses-features in the manifest to ensure compatibility with Chromebooks. Not all Chromebooks will have touchscreens, GPS, or rear-facing cameras which are typical for smartphones. Update the manifest so that sensors and hardware not commonly found on Chromebooks are not required. Example:

<uses-feature android:name="android.hardware.touchscreen"
    android:required="false" />

Additionally, to educate Chromebook users on any Chrome OS-specific features that have been implemented, for example supporting additional input methods like keyboard, trackpad, and stylus, or supporting large, high-resolution screens with a responsive layout, developers should update the app description on Google Play. It would also be useful to provide screenshots showcasing how well the app or game works on the larger screen, or how the title works on a Chromebook specifically.

Optimizing functionality

While most apps and games already work fairly well on Chromebooks without any changes, it is still a good idea to explore how to provide an optimized, consistent experience for Chromebook users.

Large screens and resizable windows

Chromebook users will be more inclined to multitask, opening multiple apps and/or games at once, taking advantage of the screen size, and operating in a manner consistent with a desktop or laptop form factor. Unlike on Android phones, they can also change the screen resolution to fit more onto the screen, or enlarge the fonts, UI, and graphics, if needed. Multi-window support and fully resizable window support are key for this usage. Graphics, fonts, layout, and touch targets should be adjusted accordingly as the screen resolution and orientation changes.

It is also important to note that just because an app or game window is not in focus, it does not mean that it is not visible. For example, if a video app is open in an inactive window, it should continue to play content "in the background" because it could still be visible along side another app window. To fully support multi-window usage in this case, pause video in onStop(), and resume in onStart().

Targeting Android N (API level 24 and higher) will signal to the Chrome OS window manager that compatibility restrictions should not be used. This allows for more flexibility and control on the developer's part for supporting window resizing.

The system will handle window management best if Android N is targeted, but for pre-N API support, windows can be toggled between either a default size selected at app launch, or a full-screen mode with either the window bar visible, or with window UI hidden in immersive full-screen mode.

When handling different windowing modes, it is important to know that the window area for an app or game will be offset by the presence or absence of the window control bar. The app should not assume that the activity will always be at (0,0) in the window. Adjust the layout and touch targets accordingly. It is somewhat common to see apps or games become unresponsive after a window resize or orientation change because it did not gracefully handle the presence of the window control bar, or the higher resolution settings of a Chromebook screen.

Orientation support

Because of the laptop form-factor, Chromebook users expect landscape to be the default orientation for apps on Chromebooks. However, Android apps often assume that portrait is the default orientation to support, due to the typical way users interact with their smartphones. To offer flexibility to users, it is highly recommended to support both portrait and landscape orientations. Some Chromebooks are convertible, so users can change between laptop and tablet modes at will, switching between portrait and landscape orientation, according to what feels comfortable for a given use case.

Most importantly, if possible, do not require a restart if the orientation or window size changes. If a user is in the process of filling out a form, creating or editing some content, or in the middle of a level in a game and loses progress because of an window change -- intentional or not -- it would be a poor user experience.

Developers can monitor window configuration changes using onConfigurationChanged() and dynamically handle those changes by adding this line to the activity's manifest:

android:configChanges="screenSize|smallestScreenSize|orientation|screenLayout".

If it is absolutely necessary to require a restart upon changes to the window, at least restore state by using the onSaveInstanceState() method so that work or state is not lost.

Additionally, it is important to be consistent with the app's orientation as the user is navigating through activities. Currently, the system forces Android apps to follow the orientation of the root activity to help maintain consistency. However, this may result in a situation where, perhaps an app starts out in landscape orientation, and a login screen normally laid out for portrait orientation pops up, and now does not look optimized due to an unresponsive layout. Also, it is still possible to have a case where a springboard activity starts out in an orientation that is different from the primary orientation of the app. Please keep these possible scenarios in mind when designing the layout for activities.

Finally, developers should be aware of the differences in handling cameras and orientation on Chromebooks. Obviously, Android phones have front-facing and rear-facing cameras that are situated at the top of a portrait-oriented screen. The front-facing cameras on Chromebooks are situated at the top of a landscape-oriented screen. Many Chromebooks do not have rear-facing cameras. If an app requires a camera, it would be best to use android.hardware.camera.any to access the front-facing camera, if a rear-facing one is not available. Again, developers should target Android N and, if possible allow the app to be resizable so that the system can take care of properly orienting the camera previews.

Supporting multiple input methods

Chromebook users are used to interacting with webpages and apps using a keyboard and trackpad. Effectively supporting these two input methods for an Android app means:

  • Supporting hotkeys for commands that a desktop app user may be familiar with
  • Using arrow and tab keys and a trackpad to navigate an activity
  • Allowing hover and opening context menus
  • Supporting other trackpad gestures to enhance productivity in desktop/laptop mode

Something as simple as hitting return to send text in a messaging app, or allowing a user to navigate fields by hitting the tab key will make an app feel more efficient and cohesive on a Chromebook.

While there is a compatibility mode for Chrome OS to emulate touchscreen scrolling and other touch events, it would be best to optimize an Android app by declaring

<uses-feature
    android:name="android.hardware.type.pc"
    android:required="false" />

in the manifest to disable compatibility mode in order to further define custom support for keyboard and trackpad.

Similarly, the system can guess at giving focus to the right views when navigating via the tab or arrow keys on a keyboard. But for best performance, specify how keyboard navigation should be handled in the activity manifest using the android:nextFocusForward attribute for tab navigation, and android:nextFocusUp, android:nextFocusDown, android:nextFocusLeft, android:nextFocusRight attributes for arrow key navigation.

On a related note, some Chromebooks do not have touchscreens, therefore well-optimized Android apps on Chrome should not assume the user can perform typical swipe and multi-touch tap gestures to navigate through an app or game. If primary functionality cannot be performed using only a keyboard or trackpad, the user experience will be severely impacted on non-touchscreen Chromebooks. Try to "translate" existing touchscreen tap and swipe gestures into something that can be easily done on a trackpad or using the keyboard.

Newer Chromebooks are gaining stylus support, allowing for richer interactions for sketchbook and note-taking apps, photo editors, games, and more. Developers are encouraged to use available APIs to support pressure-sensitivity, tilt, and eraser inputs. To enable users to comfortably rest their hands on the screen while writing, drawing, or playing games with the stylus, support palm rejection. The system will attempt to ignore input from a user's resting palm, but in case such erroneous touch events are registered, Android apps should gracefully handle ACTION_CANCEL events to erase the erroneous inputs.

By supporting all of these additional input methods, users will be able to take full advantage of the laptop mode for Chromebooks to work more efficiently, or to be more creative.

Learn more

While a lot was covered in this article, we have additional resources for you to learn more about optimizing their apps and games for Chromebooks. Read our Medium post with tips to get your app running great on Chromebooks and watch our session at Google I/O 2017, Android Apps for Chromebooks and Large Screen Devices. There is also training material on the Android developers website for building apps for Chrome OS. If you have any questions, reach out to the Android developer community and post with the hashtag #AndroidAppsOnChromeOS.

How useful did you find this blogpost?

Enroll for app signing in the Google Play Console & secure your app using Google’s robust security infrastructure

Posted by Kobi Glick, Product Manager, Google Play

Every app on Android is signed with a key. This key is used to ensure the app's integrity by checking that updates are signed with the same signature. In the past, the burden of securely holding the signing key has always been with the developer. We're now offering an app signing service on Google Play that can help you if you lose or compromise your key.

Until recently, losing your key would make it impossible to update your app with a new version. A compromised key would be a serious issue too: a third-party could maliciously replace an authentic app or corrupt it. Unfortunately in such cases, the only solution was to publish a new app, with a new package name and key, and ask all of your users to install it.

App signing in the Play Console allows us to offer help in such circumstances. For existing apps, it requires transferring your app signing key to Google Play. For new apps, we can generate your app signing key. Once enrolled in app signing, you sign your APK with an upload key, which we use to authenticate your identity. We'll then strip that signature and re-sign your app with the app signing key.

The app signing key is now securely managed by Google Play meaning that you are only responsible for managing your upload key. If your upload key is compromised or lost, our developer operations team can assist by verifying your identity and resetting your upload key. We'll still re-sign with the same app signing key, allowing the app to update as usual.

Rest assured, your key will be fully protected by Google's robust cloud security infrastructure and will benefit from the ongoing investment we're making to our security systems. In the future, we plan to offer developers who sign with Google Play automatic optimizations to enhance their app distribution. Stay tuned for more news in this area!

Learn more about how app signing works in the help center or watch the session about app signing from Google I/O 2017. Get started on securing your app in the release management section of the Play Console.

How useful did you find this blogpost?

Create stickers for Gboard on Google Play

Posted by Alan Ni, Associate Product Manager, Gboard

Messaging is getting more and more expressive -- today you can say I love you with an emoji, a gif, or a sticker. Millions of users share expressive content every day on Android devices using Gboard as their default keyboard. We want to push expression even further by allowing developers to create their own stickers for Gboard. Some of our early partners include Bitmoji, Disney, and even our own Allo team. Once published, your stickers could be seen and shared by millions of users around the world.

Using the Firebase App Indexing API, you'll be able index any sticker assets you create, publish your app to the Play Store, and get featured in the Gboard Sticker collection. Once a user downloads your sticker pack from the Play store, they'll be able to send those stickers directly from their keyboard in any Android app that supports image insertion!

Getting Started with Stickers

To kick things off, you'll need to add the Firebase App Indexing library. Visit the Firebase Getting Started Guide for details. Once you've set up Firebase App Indexing, read through our sticker guide to learn how to index those stickers. Next, create your sticker assets!

You should build and index stickers on first run after update or install to minimize the lag between a user installing the app and seeing the stickers in Gboard. Our sample app should give an idea of the end-to-end flow.

Making your Stickers Searchable

Users often look for stickers via searching on keywords. That means you'll want to add appropriate keywords to allow users to find your stickers and you can use the put method to add keywords. In the code snippet below, you'll see that a Snoopy sticker is tagged with the keywords: "bye", "snoopy", "see ya", and "good bye".

new Indexable.Builder("Sticker")
   .setName("Bye")
   // add url for sticker asset 
   .setImage("http://www.snoopysticker.com?id=1234")
   // see: Support links to your app content section
   .setUrl("http://sticker/canonical/image/bye")
   // Set the accessibility label for the sticker.
   .setDescription("A sticker for Bye")
   // Add search keywords.
   .put("keywords", "bye", "snoopy", "see ya", "good bye")
   .put("isPartOf",
        new Indexable.Builder("StickerPack")
          .setName("Snoopy Pack")
          .build())
   .build())};

For larger sticker packs, you'll want to make sure you've tagged stickers with keywords so that they're easier for users to find. We've come up with a list of common English phrases/keywords you can use to tag your stickers. But don't forget to internationalize your stickers -- to do this you'll want to first detect the device language and then index keywords that correspond to that language.

Get Featured in the Sticker Collection

Finally, share your stickers with the world! To be featured in our Sticker Collection on the Play Store, fill out this form. But first, make sure to thoroughly test the sticker pack using the latest build of Gboard, If your app has high-quality stickers and is working well with Gboard, we'll add it to our sticker collection; this is the best way to get it seen by millions of Gboard users!

We're really excited to see what sticker packs you're able to build.

Android Developer Story: Zalando increases installs and revenue by focusing on app quality

Posted by Adriana Puchianu

Based in Berlin, Zalando is Europe's leading online fashion platform. With more than 70% of its traffic now coming from mobile, the company has invested a lot in improving the quality of its app to provide a good user experience. Investing in bridging the online and the offline worlds, as well as providing a seamless cross-platform experience, has had positive results on their user engagement and revenue. Using features like A/B testing, the pre-launch report and the new release dashboard from the Google Play Console, Zalando saw a 6% increase in installs and a 15% increase in the users' lifetime value.

Watch Rushil Dave, Senior Product Specialist and Meritxell Rivera, Android Developer discuss how the company has improved user experience and key revenue and engagement metrics by investing in app quality for their Zalando app.

How useful did you find this blogpost?