9/29/17

Keystore Key Attestation

Posted by Shawn Willden, Software Engineer


Android's keystore has been available for many years, providing app developers
with a way to use cryptographic keys for authentication and encryption. Keystore
keeps the key material out of the app's process space, so that the app cannot
inadvertently reveal it to the user where it could be phished, leak it through
some other channel, or have it compromised in the event of a compromise of the
app. Many devices also provide hardware-based security for keystore keys in
secure hardware, which keeps the key material out of the Android system
entirely, so that the key material cannot be leaked even by a Linux kernel
compromise. In the vast majority of Android devices, secure hardware is a
special mode of the main CPU, with hardware-enforced isolation from the Linux
kernel and Android userspace. Alternatively, some devices use a separate secure
microprocessor.



Android provides APIs that allow the app to determine whether a given keystore
key is in secure hardware, but these APIs could be unreliable if the operating
system has been compromised. Key attestation provides a way for a device's
secure hardware to verify that an asymmetric key is in secure hardware,
protected against compromise of the Android OS.


History of Keystore



Keystore was originally introduced in Android 4.0 and keys were encrypted with
the user's passcode. In Android 4.1 the infrastructure to use device secure
hardware was added.



Up until Android 6.0, Keystore supported RSA and ECDSA. In Android 6.0, Keystore
was significantly enhanced, adding support for AES and HMAC. Also, other crucial
elements of cryptographic operations, such as RSA paddinghref="#fn1" rel="footnote">1 and AES block chaininghref="#fn2" rel="footnote">2 modes were moved into secure hardware.



In Android 6.0, Keystore also gained the ability to restrict the ways in which a
particular key could be used. The most obviously useful restriction that can be
applied is user authentication binding. This allows a key's usage to be
"bound" to the user's passcode—their PIN, pattern, or password—or fingerprint.
For passcode authentication binding, the app developer can specify a timeout in
seconds. If more than the specified time has elapsed since the user last entered
their passcode, the secure hardware refuses any requests to use the key.
Fingerprint-bound keys require a new user authentication each time the key is
used.



Other, more technical, restrictions can be applied to Android 6.0+ keys as well.
In particular, at point of key creation or import, it is necessary to specify
the cryptographic purposes (encrypt, decrypt, sign, or verify) for which the key
may be used, as well as padding and block modes, digests, source of entropy for
initialization vectors or nonces, and other details of the cryptographic
operation. Because the specified information is permanently and
cryptographically bound to the key material, Keystore won't allow the key to be
used in any other way. Therefore, an attacker who gains control of the app or
the system can't misuse the key. To help prevent attacks, developers should
specify the narrowest possible range of uses for a given key.



One of the most important changes to Android Keystore was introduced in Android
7.0. New devices that launch with Android 7.0+ with a secure lock screen must
have secure hardware and support hardware-based passcode authentication and
keystore keys. Prior to Android 7.0, secure hardware support was widespread, but
over the next few years it will become universal.



In Android 8.0, key attestation was made mandatory for all new devices that ship
with Google Play installed.


Why use key attestation?



Suppose you're developing an app to provide a bank's customers with access to
their bank balance, transaction history, and bill pay system. Security is
important; you don't want anyone who picks up the user's phone to have access to
their the bank account. One approach would be to use the user's web site
password. But that's often inconvenient for the user because web sites often
demand long, complex passwords, which are inconvenient on a small touchscreen.



With Android Keystore, you can generate an asymmetric authentication key, such
as a 256-bit ECDSA key, and have each user sign in with their complex web
password once, then register the public key in the bank's customer account
database. Each time they open the app, you can execute a challenge-response
authentication protocol using that ECDSA key. Further, if you make the key
authentication-bound, the user can authenticate with their lock screen passcode
or fingerprint each time they open the app. That allows them to use the simpler
and more convenient authentication mechanism on their phone.



If an attacker compromises Android and attempts to extract the key, they
shouldn't be able to because the key is in secure hardware.



As an app developer, key attestation allows you to verify on your server that
the ECDSA key your app requested actually lives in secure hardware. Note that
there's little point in using the attestation in your app itself; if the Android
OS is uncompromised and trustworthy, then you can just use the href="https://developer.android.com/reference/android/security/keystore/KeyInfo.html">KeyInfo
class introduced in 6.0 to discover whether the key is in secure hardware. If it
is compromised, then that API and any attempt you make to validate the
attestation on device are both unreliable.



Note that key attestation is distinct from href="https://developer.android.com/training/safetynet/attestation.html">SafetyNet
attestation. They're the same concept, but attest to different things and
come from different places. Keystore key attestation affirms that a crypto key
lives in secure hardware and has specific characteristics. SafetyNet attestation
affirms that a device is real (not an emulator) and that it's running known
software. SafetyNet uses Keystore key attestation under the covers, so if you
want to know about device integrity use that. If you want to confirm that your
key is in secure hardware, use key attestation.



For details and sample code, see the href="https://developer.android.com/training/articles/security-key-attestation.html">key
attestation training article on developer.android.com.


Notes







  1. Keystore supports the recommended OAEP and PSS padding modes for RSA encryption and
    signing, respectively, as well as the older PKCS#1 v1.5 modes. rev="footnote">↩



  2. Keystore supports GCM, CBC and ECB block chaining modes. rev="footnote">↩

Read more

9/26/17

Announcing the Winners from the Indie Games Festival in San Francisco

Posted by Kacey Fahey, Developer Marketing, Google Play


At the Google Play Indie Games Festival over the weekend, we welcomed hundreds
of attendees to try out and enjoy a diverse range of amazing games from the
indie community. The competition was very tough, and in the end, we recognized
three winners:



  • href="https://play.google.com/store/apps/details?id=com.noodlecake.flippinglegend">Flipping
    Legend by Hiding Spot
  • href="https://play.google.com/store/apps/details?id=com.bluewizard.slayawaycamp&hl=en">Slayaway
    Camp by Blue Wizard Digital
  • Tiny Bubbles by Pine Street Codeworks (coming soon!)







We'd also like to congratulate the rest of the Top 10 developers and all of the
finalists who shared their games to make for such a fun and exciting event.
Check out the great href="https://play.google.com/store/apps/collection/promotion_30023d4_games_indie_games_festival_2017">collection
of games on Google Play.



Here are the other seven games that rounded out the Top 10:



  • href="https://play.google.com/store/apps/details?id=com.robotogames.ageofrivals">Age
    of Rivals by Roboto Games
  • href="https://play.google.com/store/apps/details?id=io.v2g.beastbrawlers">Beast
    Brawlers - PvP Arena by V2 Games Inc.
  • href="https://play.google.com/store/apps/details?id=com.CovensMapTest.RainCrow&e=-EnableAppDetailsPageRedesign">Covens
    by Raincrow Studios, LLC
  • href="https://play.google.com/store/apps/details?id=com.headupgames.crashycars">Crashy
    Cars by pixelbizarre
  • href="https://play.google.com/store/apps/details?id=com.HappySquareStudio.JigsawStory1&hl=en">Jigsaw
    Story by Happy Square Studio Inc
  • href="https://play.google.com/store/apps/details?id=com.gorillabeangames.loterialatinbingo">Loteria
    Latin Bingo by Gorilla Bean Games
  • href="https://play.google.com/store/apps/details?id=com.rac7.SplitterCritters&hl=en">Splitter
    Critters by RAC7


The day started with time for attendees to play the 20 finalists' games. They
experienced different genres and styles of gameplay and were encouraged to talk
with the developers about their work and what it's like to make mobile games for
a living. The event brought together kids, adults, gaming enthusiasts and
non-gamers, and was a great representation of the fun experiences mobile games
create.



In the afternoon, attendees voted for their favorites and the Top 10 moved on to
the presentation round. These developers had three minutes to deliver their best
pitch to the panel of judges. After the judges voted, results were in and the
three winners and seven runners up were named.



If you like indie games and want to keep up with our favorite indie picks, visit
the Indie Corner on Google Play.



How useful did you find this blogpost?



href="https://docs.google.com/forms/d/e/1FAIpQLScLTlzFd_aV-3rAdBqO1QxwCsuAcDCIM6fJFXyNcyf7zElVXg/viewform?usp=pp_url&entry.753333049=1%E2%98%85+%E2%80%93+Not+at+all&entry.2056663615&entry.646747778=SFindiefest-07/17" style=color:gold;>★
href="https://docs.google.com/forms/d/e/1FAIpQLScLTlzFd_aV-3rAdBqO1QxwCsuAcDCIM6fJFXyNcyf7zElVXg/viewform?usp=pp_url&entry.753333049=2%E2%98%85+%E2%80%93+Not+very&entry.2056663615&entry.646747778=SFindiefest-07/17" style=color:gold;>★
href="https://docs.google.com/forms/d/e/1FAIpQLScLTlzFd_aV-3rAdBqO1QxwCsuAcDCIM6fJFXyNcyf7zElVXg/viewform?usp=pp_url&entry.753333049=3%E2%98%85+%E2%80%93+Somewhat&entry.2056663615&entry.646747778=SFindiefest-07/17" style=color:gold;>★
href="https://docs.google.com/forms/d/e/1FAIpQLScLTlzFd_aV-3rAdBqO1QxwCsuAcDCIM6fJFXyNcyf7zElVXg/viewform?usp=pp_url&entry.753333049=4%E2%98%85+%E2%80%93+Very&entry.2056663615&entry.646747778=SFindiefest-07/17" style=color:gold;>★
href="https://docs.google.com/forms/d/e/1FAIpQLScLTlzFd_aV-3rAdBqO1QxwCsuAcDCIM6fJFXyNcyf7zElVXg/viewform?usp=pp_url&entry.753333049=5%E2%98%85+%E2%80%93+Extremely&entry.2056663615&entry.646747778=SFindiefest-07/17" style=color:gold;>★






Read more

9/19/17

Google Play Billing Library 1.0 released

Posted by Neto Marin, Developer Advocate


In June we announced the href="https://android-developers.googleblog.com/2017/06/money-made-easily-with-new-google-play.html">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 href="https://developer.android.com/google/play/billing/billing_overview.html">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:




class="prettyprint">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 href="https://developer.android.com/reference/com/android/billingclient/api/BillingClient.html">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 href="https://developer.android.com/reference/com/android/billingclient/api/BillingClient.html">BillingClient
instance, you'll need to set a href="https://developer.android.com/reference/com/android/billingclient/api/PurchasesUpdatedListener.html">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 href="https://developer.android.com/reference/com/android/billingclient/api/PurchasesUpdatedListener.html#onPurchasesUpdated(int,
java.util.List)">onPurchasesUpdated()

method of your href="https://developer.android.com/reference/com/android/billingclient/api/PurchasesUpdatedListener.html">PurchasesUpdatedListener:



class="prettyprint">@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 href="https://developer.android.com/reference/com/android/billingclient/api/PurchasesUpdatedListener.html">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 href="https://developer.android.com/reference/com/android/billingclient/api/BillingClient.html">BillingClient
instance, and setting the href="https://developer.android.com/reference/com/android/billingclient/api/PurchasesUpdatedListener.html">PurchasesUpdatedListener:



class="prettyprint">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 href="https://developer.android.com/google/play/billing/billing_admin.html">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 href="https://developer.android.com/google/play/billing/billing_testing.html#draft_apps">Draft
Apps are No Longer Supported.



To get a list of product details with prices for current user, call href="https://developer.android.com/reference/com/android/billingclient/api/BillingClient.html#querySkuDetailsAsync(java.lang.String,
java.util.List,
com.android.billingclient.api.SkuDetailsResponseListener)">querySkuDetailsAsync()
.
You must also specify a listener which implements the href="https://developer.android.com/reference/com/android/billingclient/api/SkuDetailsResponseListener.html">SkuDetailsResponseListener
interface. You can then override the href="https://developer.android.com/reference/com/android/billingclient/api/SkuDetailsResponseListener.html#onSkuDetailsResponse(com.android.billingclient.api.SkuDetails.SkuDetailsResult)">onSkuDetailsResponse()
method which notifies the listener when the query finishes, as illustrated by
the following sample code:



class="prettyprint">
List<String> skuList = new ArrayList<> ();
skuList.add("premiumUpgrade");
skuList.add("gas");
SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
params.setSkusList(skuList).setType(SkuType.INAPP);
mBillingClient.querySkuDetailsAsync(params.build(),
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 href="https://developer.android.com/reference/com/android/billingclient/api/BillingClient.html#launchBillingFlow(android.app.Activity,
com.android.billingclient.api.BillingFlowParams)">launchBillingFlow()

method on the Play Billing Library client. You must call the href="https://developer.android.com/reference/com/android/billingclient/api/BillingClient.html#launchBillingFlow(android.app.Activity,
com.android.billingclient.api.BillingFlowParams)">launchBillingFlow()

method (and all the other methods from href="https://developer.android.com/reference/com/android/billingclient/api/BillingClient.html">BillingClient)
from the UI thread.


The href="https://developer.android.com/reference/com/android/billingclient/api/BillingClient.html#launchBillingFlow(android.app.Activity,
com.android.billingclient.api.BillingFlowParams)">launchBillingFlow()

method needs href="https://developer.android.com/reference/com/android/billingclient/api/BillingFlowParams.html">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, href="https://developer.android.com/reference/com/android/billingclient/api/BillingClient.SkuType.html#INAPP">SkuType.INAPP).
To get an instance of href="https://developer.android.com/reference/com/android/billingclient/api/BillingFlowParams.html">BillingFlowParams,
construct it with href="https://developer.android.com/reference/com/android/billingclient/api/BillingClient.html#newBuilder()">newBuilder()
method:



class="prettyprint">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 href="https://developer.android.com/reference/com/android/billingclient/api/PurchasesUpdatedListener.html#onPurchasesUpdated(int,
java.util.List)">onPurchasesUpdated()

method. For details how to process the data received on href="https://developer.android.com/reference/com/android/billingclient/api/PurchasesUpdatedListener.html#onPurchasesUpdated(int,
java.util.List)">onPurchasesUpdated()

and how to handle a purchase, check the section href="https://developer.android.com/training/play-billing-library/purchase-iab-products.html#purchase">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 href="https://developer.android.com/reference/com/android/billingclient/api/BillingClient.html#consumeAsync(java.lang.String,
com.android.billingclient.api.ConsumeResponseListener)">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 href="https://developer.android.com/reference/com/android/billingclient/api/ConsumeResponseListener.html#onConsumeResponse(int,
java.lang.String)">onConsumeResponse()
method of the href="https://developer.android.com/reference/com/android/billingclient/api/ConsumeResponseListener.html">ConsumeResponseListener
interface, that you must override to handle the consumption result.


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




class="prettyprint">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 href="https://github.com/googlesamples/android-play-billing/tree/master/TrivialDrive">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 href="https://github.com/googlesamples/android-play-billing/tree/master/TrivialDrive_v2">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: href="https://codelabs.developers.google.com/codelabs/play-billing-codelab">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 href="https://developer.android.com/google/play/billing/billing_library.html">Play
Billing Library and the href="https://developer.android.com/reference/com/android/billingclient/classes.html">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 href="https://developer.android.com/training/play-billing-library/index.html">library's
training class.



For more details about the Play Billing Library 1.0 release, check out the href="https://developer.android.com/google/play/billing/billing_library_releases_notes.html">Releases Notes page, where you can find updates, bug fixes and behavior changes on the library since the Developer Preview release.


We still want your feedback



If you have issues or questions, file a href="https://issuetracker.google.com/issues/new?component=311487&template=1014446">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 href="https://github.com/googlesamples/android-play-billing/issues">Trivial
Drive issues page.



For technical questions on implementation, library usage, and best practices,
you can use the tags href="https://stackoverflow.com/questions/tagged/google-play">google-play
and href="https://stackoverflow.com/questions/tagged/play-billing-library">play-billing-library
on StackOverflow or visit the href="https://plus.google.com/+AndroidDevelopers/palette">communities on our
Google+ page.

Read more

9/16/17

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 href="https://android-developers.googleblog.com/2017/08/android-things-developer-preview-5.html">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 href="https://www.hackster.io/Google">Google's Hackster.io Community by
including href="https://www.hackster.io/google/products/android-things">Android Things
as a software component, then registered through the href="https://www.hackster.io/contests/Google">contest page.







Idea Submissions



Submit your project ideas starting today. Ideas submitted by September 29, 2017
are eligible to receive one of 120 href="https://shop.technexion.com/pico-pi-imx6ul.html">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 href="https://www.hackster.io/contests/Google">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 href="https://youtu.be/FMGOGEgOEXc">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.



Read more

9/15/17

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 href="https://developer.android.com/training/safetynet/verify-apps.html">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 href="https://source.android.com/security/reports/Google_Android_Security_PHA_classifications.pdf">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 href="https://android-developers.googleblog.com/2017/04/safetynet-attestation-building-block.html">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 href="https://developer.android.com/training/safetynet/verify-apps.html">developer
docs.

Read more

9/13/17

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. href="http://infinitedeviation.com">Infinite Deviation is an
initiative created by Google Computer Science (CS) in Media and href="http://ideasunited.com/">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 href="https://c.ymcdn.com/sites/www.igda.org/resource/resmgr/files__2016_dss/IGDA_DSS_2016_Summary_Report.pdf">23%
of people in the gaming industry identify as women and only href="http://www.newsweek.com/2016/10/21/video-games-race-black-protagonists-509328.html">3%
of game developers are African-American. From ensuring women are represented
in href="https://www.blog.google/products/google-play/wonder-woman-partnership/">video
games to giving young girls the chance to href="https://www.blog.google/products/google-play/wonder-woman-partnership/">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 href="http://infinitedeviation.com/games">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.



Read more

9/9/17

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 href="https://play.google.com/store/info/topic?id=topic_b000054_games_indie_corner_tp&hl=en_GB&e=-EnableAppDetailsPageRedesign">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 href="https://play.google.com/store/apps/collection/promotion_30028e5_android_excellence_collection_games">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. href="https://goo.gl/5y63JF">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 href="https://play.google.com/store/apps/details?id=com.devolver.reigns">Reigns,
an indie game showcased in href="https://play.google.com/store/apps/collection/promotion_30028e5_android_excellence_collection_games">Android
Excellence and the winner of last year's href="https://events.withgoogle.com/indie-games-contest-europe/">Indie Games
Contest in Europe, share how he built a successful games business in the
video below.






And, finally, check out our recent href="https://medium.com/googleplaydev/a-q-a-session-with-indie-game-developer-spry-fox-23cac57c29da">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?
href="https://docs.google.com/forms/d/e/1FAIpQLScLTlzFd_aV-3rAdBqO1QxwCsuAcDCIM6fJFXyNcyf7zElVXg/viewform?usp=pp_url&entry.753333049=1%E2%98%85+%E2%80%93+Not+at+all&entry.2056663615&entry.646747778=reigns-09/17" style="color:gold;" >★
href="https://docs.google.com/forms/d/e/1FAIpQLScLTlzFd_aV-3rAdBqO1QxwCsuAcDCIM6fJFXyNcyf7zElVXg/viewform?usp=pp_url&entry.753333049=2%E2%98%85+%E2%80%93+Not+very&entry.2056663615&entry.646747778=reigns-09/17" style="color:gold;" >★
href="https://docs.google.com/forms/d/e/1FAIpQLScLTlzFd_aV-3rAdBqO1QxwCsuAcDCIM6fJFXyNcyf7zElVXg/viewform?usp=pp_url&entry.753333049=3%E2%98%85+%E2%80%93+Somewhat&entry.2056663615&entry.646747778=reigns-09/17" style="color:gold;" >★
href="https://docs.google.com/forms/d/e/1FAIpQLScLTlzFd_aV-3rAdBqO1QxwCsuAcDCIM6fJFXyNcyf7zElVXg/viewform?usp=pp_url&entry.753333049=4%E2%98%85+%E2%80%93+Very&entry.2056663615&entry.646747778=reigns-09/17" style="color:gold;" >★
href="https://docs.google.com/forms/d/e/1FAIpQLScLTlzFd_aV-3rAdBqO1QxwCsuAcDCIM6fJFXyNcyf7zElVXg/viewform?usp=pp_url&entry.753333049=5%E2%98%85+%E2%80%93+Extremely&entry.2056663615&entry.646747778=reigns-09/17" style="color:gold;" >★





Read more

9/8/17

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
<atomic> and <type_traits>.


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
.

Read more

9/7/17

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 href="https://android-developers.googleblog.com/2016/05/bring-your-android-app-to-chromebooks.html">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 href="https://www.chromium.org/chromium-os/chrome-os-systems-supporting-android-apps">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 href="https://developer.android.com/topic/arc/manifest.html">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 href="https://developer.android.com/guide/topics/ui/multi-window.html#lifecycle">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 href="https://developer.android.com/topic/arc/window-management.html">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 href="https://developer.android.com/topic/arc/input-compatibility.html#compatibility_mode">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 href="https://developer.android.com/training/keyboard-input/navigation.html">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 href="https://developer.android.com/topic/arc/input-compatibility.html#stylus">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, href="https://www.youtube.com/watch?v=v6QH89i4YCI">Android Apps for Chromebooks
and Large Screen Devices. There is also training material on the Android
developers website for href="https://developer.android.com/topic/arc/index.html">building apps for
Chrome OS. If you have any questions, reach out to the href="https://plus.google.com/+AndroidDevelopers">Android developer
community and post with the hashtag #AndroidAppsOnChromeOS.



How useful did you find this blogpost?



href="https://docs.google.com/forms/d/e/1FAIpQLScLTlzFd_aV-3rAdBqO1QxwCsuAcDCIM6fJFXyNcyf7zElVXg/viewform?usp=pp_url&entry.753333049=1%E2%98%85+%E2%80%93+Not+at+all&entry.2056663615&entry.646747778=ChromeOS-09/17" style="color:gold;" >★
href="https://docs.google.com/forms/d/e/1FAIpQLScLTlzFd_aV-3rAdBqO1QxwCsuAcDCIM6fJFXyNcyf7zElVXg/viewform?usp=pp_url&entry.753333049=2%E2%98%85+%E2%80%93+Not+very&entry.2056663615&entry.646747778=ChromeOS-09/17" style="color:gold;" >★
href="https://docs.google.com/forms/d/e/1FAIpQLScLTlzFd_aV-3rAdBqO1QxwCsuAcDCIM6fJFXyNcyf7zElVXg/viewform?usp=pp_url&entry.753333049=3%E2%98%85+%E2%80%93+Somewhat&entry.2056663615&entry.646747778=ChromeOS-09/17" style="color:gold;" >★
href="https://docs.google.com/forms/d/e/1FAIpQLScLTlzFd_aV-3rAdBqO1QxwCsuAcDCIM6fJFXyNcyf7zElVXg/viewform?usp=pp_url&entry.753333049=4%E2%98%85+%E2%80%93+Very&entry.2056663615&entry.646747778=ChromeOS-09/17" style="color:gold;" >★
href="https://docs.google.com/forms/d/e/1FAIpQLScLTlzFd_aV-3rAdBqO1QxwCsuAcDCIM6fJFXyNcyf7zElVXg/viewform?usp=pp_url&entry.753333049=5%E2%98%85+%E2%80%93+Extremely&entry.2056663615&entry.646747778=ChromeOS-09/17" style="color:gold;" >★




Read more

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 href="https://cloud.google.com/security/whitepaper">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 href="https://support.google.com/googleplay/android-developer/answer/7384423?hl=en-GB">how
app signing works in the help center or href="https://www.youtube.com/watch?v=5tdGAP927dk">watch the session about app
signing from Google I/O 2017. Get started on securing your app in the href="https://play.google.com/apps/publish">release management section of
the Play Console.



How useful did you find this blogpost?
href="https://docs.google.com/forms/d/e/1FAIpQLScLTlzFd_aV-3rAdBqO1QxwCsuAcDCIM6fJFXyNcyf7zElVXg/viewform?entry.753333049=1%E2%98%85+%E2%80%93+Not+at+all&entry.656324858&entry.1348260426=appsign-06/17&entry.1170596605&entry.646747778=appsign-06/17" style="color:gold;">★
href="https://docs.google.com/forms/d/e/1FAIpQLScLTlzFd_aV-3rAdBqO1QxwCsuAcDCIM6fJFXyNcyf7zElVXg/viewform?entry.753333049=2%E2%98%85+%E2%80%93+Not+very&entry.656324858&entry.1348260426=appsign-06/17&entry.1170596605&entry.646747778=appsign-06/17" style="color:gold;">★
href="https://docs.google.com/forms/d/e/1FAIpQLScLTlzFd_aV-3rAdBqO1QxwCsuAcDCIM6fJFXyNcyf7zElVXg/viewform?entry.753333049=3%E2%98%85+%E2%80%93+Somewhat&entry.656324858&entry.1348260426=appsign-06/17&entry.1170596605&entry.646747778=appsign-06/17" style="color:gold;">★
href="https://docs.google.com/forms/d/e/1FAIpQLScLTlzFd_aV-3rAdBqO1QxwCsuAcDCIM6fJFXyNcyf7zElVXg/viewform?entry.753333049=4%E2%98%85+%E2%80%93+Very&entry.656324858&entry.1348260426=appsign-06/17&entry.1170596605&entry.646747778=appsign-06/17" style="color:gold;">★
href="https://docs.google.com/forms/d/e/1FAIpQLScLTlzFd_aV-3rAdBqO1QxwCsuAcDCIM6fJFXyNcyf7zElVXg/viewform?entry.753333049=5%E2%98%85+%E2%80%93+Extremely&entry.656324858&entry.1348260426=appsign-06/17&entry.1170596605&entry.646747778=appsign-06/17" style="color:gold;">★




Read more

9/2/17

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 href="https://play.google.com/store/apps/collection/promotion_30029ba_stickers_apps_gboard?e=-EnableAppDetailsPageRedesign">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
href="https://firebase.google.com/docs/app-indexing/android/app">fohref="https://firebase.google.com/docs/app-indexing/android/app">r href="https://firebase.google.com/docs/app-indexing/android/app">dehref="https://firebase.google.com/docs/app-indexing/android/app">tahref="https://firebase.google.com/docs/app-indexing/android/app">ilhref="https://firebase.google.com/docs/app-indexing/android/app">s. Once
you've set up Firebase App Indexing, read through our href="http://firebase.google.com/docs/app-indexing/android/personal-content#gboard-stickers">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 href="https://github.com/firebase/quickstart-android/tree/master/app-indexing">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
href="https://docs.google.com/spreadsheets/d/1ssgxg52qsqQgcTMtGqPsuJL2RUBIj_vt5onVW3yFDOE/edit?usp=sharing">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 href="https://goo.gl/forms/otRBKpqKj6hTbUX92">this form.
But first, make sure to thoroughly test the sticker pack using the
latest build of href="https://play.google.com/store/apps/details?id=com.google.android.inputmethod.latin&hl=en&e=-EnableAppDetailsPageRedesign">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.



Read more

9/1/17

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

Posted by Adriana Puchianu


Based in Berlin, href="https://play.google.com/store/apps/details?id=de.zalando.mobile">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 href="https://play.google.com/store/apps/details?id=de.zalando.mobile">Zalando
app.



How useful did you find this blogpost?


href="https://docs.google.com/forms/d/e/1FAIpQLScLTlzFd_aV-3rAdBqO1QxwCsuAcDCIM6fJFXyNcyf7zElVXg/viewform?usp=pp_url&entry.753333049=1%E2%98%85+%E2%80%93+Not+at+all&entry.2056663615&entry.646747778=zalando-09/17" style="color:gold;" >★
href="https://docs.google.com/forms/d/e/1FAIpQLScLTlzFd_aV-3rAdBqO1QxwCsuAcDCIM6fJFXyNcyf7zElVXg/viewform?usp=pp_url&entry.753333049=2%E2%98%85+%E2%80%93+Not+very&entry.2056663615&entry.646747778=zalando-09/17" style="color:gold;" >★
href="https://docs.google.com/forms/d/e/1FAIpQLScLTlzFd_aV-3rAdBqO1QxwCsuAcDCIM6fJFXyNcyf7zElVXg/viewform?usp=pp_url&entry.753333049=3%E2%98%85+%E2%80%93+Somewhat&entry.2056663615&entry.646747778=zalando-09/17" style="color:gold;" >★
href="https://docs.google.com/forms/d/e/1FAIpQLScLTlzFd_aV-3rAdBqO1QxwCsuAcDCIM6fJFXyNcyf7zElVXg/viewform?usp=pp_url&entry.753333049=4%E2%98%85+%E2%80%93+Very&entry.2056663615&entry.646747778=zalando-09/17" style="color:gold;" >★
href="https://docs.google.com/forms/d/e/1FAIpQLScLTlzFd_aV-3rAdBqO1QxwCsuAcDCIM6fJFXyNcyf7zElVXg/viewform?usp=pp_url&entry.753333049=5%E2%98%85+%E2%80%93+Extremely&entry.2056663615&entry.646747778=zalando-09/17" style="color:gold;" >★




Read more

Updates to Google Play policy promote standalone Android Wear apps

Posted by Hoi Lam, Lead Developer
Advocate, Android Wear






Strava - a standalone wear app available to both Android and iOS users



Android Wear 2.0 represents the the latest evolution of the Android Wear
platform. It introduced the concept of href="https://developer.android.com/training/wearables/apps/standalone-apps.html">standalone
apps that can connect to the network directly and work independently of a
smartphone. This is critical to providing apps not only to our Android users,
but also iOS users - which is increasingly important as we continue to expand
our diverse ecosystem of watches and users. In addition, Wear 2.0 brought
multi-APK support to Wear apps, which reduces the APK size of your phone apps,
and makes it possible for iOS users to experience your Wear apps.



Today, we are announcing that multi-APKs will also work for Android Wear 1.0
watches, so you can now reach all of your users without needing to bundle your
Wear app within your phone app's APK. Additionally, the Google Play Store policy
will change to promote the use of multi-APKs and standalone apps. This covers
all types of apps that are designed to run on the watch, including watch faces,
complication data providers as well as launchable apps.


Policy change



The policy change will be effective from the 18th of January, 2018. At this
time, the following apps will lose the "Enhanced for Android Wear" badge in the
Google Play Store and will not be eligible to be listed in the top charts in the
Play Store for Android Wear:


  • Mobile apps that support Wear notification enhancements but do not have a
    separate Wear app.
  • Wear apps that are bundled with mobile apps instead of using
    multi-APK.


Since multi-APK is now supported by devices running Wear 1.0 and 2.0, developers
embedding their Wear app APKs in phone APKs should unbundle their Wear APK
and href="https://developer.android.com/training/wearables/apps/packaging.html">upload
it to the Play Store as a multi-APK. This will allow them to continue to
qualify for the "Enhanced for Android Wear" badge as well as be eligible to
appear in the Android Wear top charts. The two APKs can continue to share the
same package name.



In addition to providing top app charts, we periodically put together curated
featured collections. To be eligible for selection for these collections,
developers will need to make their Wear apps function independently from the
phone, as a standalone app. These apps will need to work on watches that are
paired with both iOS and Android phones.


What are standalone apps?



href="https://developer.android.com/training/wearables/apps/standalone-apps.html">Standalone
apps are Wear apps that do not require a phone app to run. The app either
does not require network access or can access the network directly without the
phone app - something that is supported by Android Wear 2.0.



To mark your app as standalone, put the following meta-data tag in the
AndroidManifest.xml:




<application>
...
<meta-data
android:name="com.google.android.wearable.standalone"
android:value="true" />
...
</application>


In some rare cases, the user experience may be enhanced by the syncing of data
between the phone and watch. For example, a cycling app can use the watch to
display the current pace, and measure the user's heart rate, while displaying a
map on the phone. In this scenario, we recommend that developers ensure that
their Wear apps function without a phone and treat the phone experience as
optional as far as the Wear apps are concerned. In these cases, a Wear app is
still considered standalone and should be marked as such in its
AndroidManifest.xml file.


Wear what you want



From the beginning, Android Wear has been about wear what you want -- the
styles, watches, and apps you want to wear. This latest policy change lets you
highlight your Android Wear apps, giving users even more choice about what apps
they want on their watches.



Read more
loading...