Category Archives: Android Developers Blog

An Open Handset Alliance Project

Video Playback with the Google Assistant on Android TV

Posted by Benjamin Baxter, Developer Programs Engineer

How to integrate the Google Assistant in a TV app

Earlier this year, we announced that the Google Assistant will be coming to Android TV and it has arrived. The Google Assistant on Android TV will allow users to discover, launch and control media content, control smart devices like light bulbs, and much more. Your Assistant also understands that you're interacting on a TV, so you'll get the best experience possible while watching your favorite movies and TV shows.

The Google Assistant has a built-in capability to understand commands like "Watch The Incredibles", and media controls, like pause, fast forward, etc. This article will walk through how to integrate the Google Assistant into your application.

There are no new APIs needed to integrate with the Google Assistant. You just need to follow the pattern that the Google Assistant expects from your app. If you want to experiment and play with the APIs and the Assistant, you can download this sample from github.

Discovery

The Google Assistant has made some changes to improve finding information on Android TV.

There are a few ways to expose your content to users through the Google Assisant.

Server side integration. (Requires registration and onboarding)

You need to provide your content catalog to Google. This data is ingested and available to the Google Assistant outside of your app.

This is not specific for Google Assistant. It will also enable other Google services such as search and discovery on Google Search, Google Play, Google Home App, and Android TV.

Client side integration. (Available to all apps)

If your app is already searchable, then you only need to handle the EXTRA_START_PLAYBACK flag, which we go into more detail later. Content will auto-play if the app name is explicitly specified in the search results or if the user is already in your app.

Once your app is searchable, you can test by asking the Assistant or, if you are in a loud area, test quietly by running the following adb command:

adb shell am start -a "android.search.action.GLOBAL_SEARCH" --es query \"The Incredibles\" 

Each app that responds to the search query will have a row displaying their search results. Notice that YouTube and the sample app, Assistant Playback, each receive their own rows for content that match the search query.

For specific searches such as "Play Big Buck Bunny", the Assistant will present a card with a button for each app that exactly matched the search query. In the screenshot below, you can see the sample app, Assistant Playback, shows up as an option to watch Big Buck Bunny.

There are times when the Google Assistant will launch an app directly to start playing content. An example of when this occurs is when content is exclusive to the app; "Play the Netflix original House of Cards".

Launching

When the user selects a video from search results, an intent is sent to your app. The priority order for the intent actions are as follows:

  1. Intent specified in the cursor returned from the search (SUGGEST_COLUMN_INTENT_ACTION).
  2. Intent specific in the searchable.xml file with the searchSuggestIntentAction value.
  3. Defaults to ACTION_VIEW.

In addition, the Assistant will also pass an extra to signal if playback should begin immediately. You app should be able to handle the intent and expect a boolean extra called EXTRA_START_PLAYBACK.

import static android.support.v4.content.IntentCompat.EXTRA_START_PLAYBACK;

public class SearchableActivity extends Activity {

   @Override
   protected void onCreate(@Nullable Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       if (getIntent() != null) {
           // Retrieve video from getIntent().getData().

           boolean startPlayback = getIntent().getBooleanExtra(EXTRA_START_PLAYBACK, false);
           Log.d(TAG, "Should start playback? " + (startPlayback ? "yes" : "no"));

           if (startPlayback) {
               // Start playback.
               startActivity(...);
           } else {
               // Show details for movie.
               startActivity(...);
           }
       }
       finish();
   }
}

You can test this by modifying and running the following adb command. If your app has a custom action, then replace android.intent.action.VIEW with the custom action. Replace the value of the -d argument with the URI you return from the Assistant's query.

adb shell 'am start -a android.intent.action.VIEW --ez
android.intent.extra.START_PLAYBACK true -d <URI> -f 0x14000000'

The -f argument is the logical OR value from FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP. This will force your activity to be freshly launched.

For example, in the sample app, you can run the following command to launch playback of "Big Buck Bunny" as if the assistant had launched it.

adb shell 'am start -a android.intent.action.VIEW --ez
android.intent.extra.START_PLAYBACK true -d 
content://com.example.android.assistantplayback/video/2 -n
com.example.android.assistantplayback/.SearchableActivity -f 0x14000000'

The URI above is defined by the value of android:searchSuggestIntentData in searchable.xml (content://com.example.android.assistantplayback/video/) in addition to the value of SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID (2) returned from the query.

Note that intents may be cached by the Google Assistant up to 7 days. Your app could receive a request to play content that is no longer available. The intent handler should be designed to be stateless and not rely on any previously knowledge to handle the deep link. Your app should gracefully handle this situation. One solution would be to show an error message and let the user land on your main activity or another relevant activity.

Playback

If your app implements MediaSession correctly, then your app should work right away with no changes.

The Google Assistant assumes that your app handles transport controls. The Assistant uses the TransportControls to send media commands to your app's MediaSession. Video apps must support the following controls wherever possible:

  • Play/Pause/Stop
  • Previous/Next
  • Rewind/Fast Forward (implemented with seekTo())

You can easily get a hook for these controls by implementing a MediaSession.Callback. If you play videos using PlaybackTransportControlGlue, then all your callback needs to do it sync the glue and the MediaSession. Otherwise use this callback to sync your player.

public class MyMediaSessionCallback extends MediaSessionCompat.Callback {

   private final PlaybackTransportControlGlue<?> mGlue;

   public MediaSessionCallback(PlaybackTransportControlGlue<?> glue) {
       mGlue = glue;
   }

   @Override
   public void onPlay() {
       Log.d(TAG, "MediaSessionCallback: onPlay()");
       mGlue.play();
       updateMediaSessionState(...);
   }

   @Override
   public void onPause() {
       Log.d(TAG, "MediaSessionCallback: onPause()");
       mGlue.pause();
       updateMediaSessionState(...);
   }

   @Override
   public void onSeekTo(long position) {
       Log.d(TAG, "MediaSessionCallback: onSeekTo()");
       mGlue.seekTo(position);
       updateMediaSessionState(...);
   }

   @Override
   public void onStop() {
       Log.d(TAG, "MediaSessionCallback: onStop()");
       // Handle differently based on your use case.
   }

   @Override
   public void onSkipToNext() {
       Log.d(TAG, "MediaSessionCallback: onSkipToNext()");
       playAndUpdateMediaSession(...);
   }

   @Override
   public void onSkipToPrevious() {
       Log.d(TAG, "MediaSessionCallback: onSkipToPrevious()");
       playAndUpdateMediaSession(...);
   }
}

Continue learning

Check out the following articles and training documents to continue learning about MediaSession and Video apps.

To play around with the Google Assistant on Android TV, download the sample app and run it on Nvidia Shield running Android M or above.

If you would like to continue the discussion, leave a response or talk to me on Twitter.

Android Excellence: congratulations to the new apps and games for Fall 2017

Posted by Kacey Fahey, Developer Marketing, Google Play

Android Excellence recognizes some of the highest quality apps and games on Google Play. With a strong focus on great design, an engaging user experience, and strong app performance, this set of apps and games show the diversity of content on Google Play. Whether you're trying to better manage personal finances with Money Lover or want to experience the thrill of stunt-racing with stunning graphics and real-time challenges in Asphalt 8, there's something for everyone to enjoy.

One new awardee is Bring!, a simple-to-use app that helps manage your grocery lists. Use the existing catalog of items or add your own product photos, then share your lists and message in-app to let others know when it's time to shop. If you're looking for a new game to play, Karma. Incarnation 1. is a "wonderfully weird, puzzle-filled indie adventure game." With beautiful hand-drawn art, you guide the story's hero through moments of humor and challenge to be reunited with his love.

Congratulations to the new Android Excellence apps and games for Fall 2017.

New Android Excellence apps New Android Excellence games
Agoda Asphalt 8
AlarmMon Bubble Witch 3 Saga
Bring! Castle Creeps
CastBox Crab War
Email by Edison Crash of Cars
Eve Dan the Man
Fotor Dawn of Titans
Mint Dream Defense
Money Lover Iron Marines
Onefootball Karma. Incarnation 1.
Robinhood Postknight
Viki Sky Force Reloaded
Zombie Age 3

Explore other great apps and games in the Editors’ Choice section on Google Play.

How useful did you find this blogpost?

Android Wear Beta

Posted by Hoi Lam, Lead Developer Advocate, Android Wear
LG Watch Sport

Today, we are launching the beta of the next Android Wear update. As we mentioned at Google I/O, this will mainly be a technical upgrade to API 26 with enhancements to background limits and notification channels. LG Watch Sport users can go to this webpage to sign up and the factory image will automatically be downloaded to the watch you enroll. As this is a beta, please be sure to review the known issues before enrolling. If you don't have a watch to test on, you can use the Android emulator. For developers working with Android Wear for China, an updated emulator image is also available.

Notification Channels

In this update, users can choose the types of notifications they receive via an app through notification channels. This gives users finer-grained control than muting all notifications from the app. For notifications generated locally by Android Wear apps, users will be able to customise the notifications channel they want to see, right on their watch. Please refer to the Wear notification sample for more details. For notifications bridged from the phone, the phone notifications channel settings will dictate what is shown on the watch.

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    mNotificationManager.createNotificationChannel(
        NotificationChannel("1001", "New Follower",
            NotificationManager.IMPORTANCE_DEFAULT))

    mNotificationManager.createNotificationChannel(
        NotificationChannel("1002", "Likes",
            NotificationManager.IMPORTANCE_LOW))
}

Background Limits

There are increased restrictions on background services. Developers should assume services can no longer run in the background without a visible notification. In addition, the background location update frequency will be reduced. Battery-saving best practices such as using JobScheduler should be adopted to ensure your app is battery-efficient and able to perform background tasks when possible.

Please give us your feedback

We expect this to be the only beta release before the final production release. Thank you for your feedback so far. Please submit any bugs you find via the Android Wear issue tracker. The earlier you submit them, the higher the likelihood that we can include the fixes in the final release.

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 padding1 and AES block chaining2 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 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 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 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. 

  2. Keystore supports GCM, CBC and ECB block chaining modes. 

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:

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 collection of games on Google Play.

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

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?

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?