Tag Archives: Android Developer

New video tips to help news publishers find success on Google Play

Posted by Tamzin Taylor - Strategic Partner Lead, Google Play

Today we have released a three-part video series ‘Tips for your news app on Google Play’, where you can find actionable tips and learn best practices for developing, launching and monetising a high quality news app. The video series accompanies the recently published News Publisher Playbook.

Watch the video series to learn:

  • 10 tips on how to design and develop your News app
  • 10 tips to help you launch your News app and start gaining readers
  • 10 tips to engage your readers and monetize your News app

You can also get the News Publisher Playbook on the Play Store to help you develop a successful news mobile strategy on Android. It includes tips on mobile website optimization, how to create a Google Play Newsstand edition, how to improve your native app, and more.

Give us your feedback

Once you’ve checked out the video series, we’d love to hear your feedback so we can continue to help you find success with and achieve your business objectives. Leave a comment or a thumbs up, and subscribe to the Android Developers YouTube channel!

Also, check out our other videos in in the Tips for Success on Google Play series, including the recent video on 10 tips to build an app for billions of users.

For more best practices to find success on Google Play, get the new Playbook for Developers app.

Android changes for NDK developers

Posted by Dmitry Malykhanov, Developer Advocate

Related to other improvements to the Android platform, the dynamic linker in Android M and N has stricter requirements for writing clean, cross-platform compatible native code in order to load. It is necessary that an application’s native code follows the rules and recommendations in order to ensure a smooth transition to recent Android releases.

Below we outline in detail each individual change related to native code loading, the consequences and steps you can take to avoid issues.

Required tools: there is an <arch>-linux-android-readelf binary (e.g. arm-linux-androideabi-readelf or i686-linux-android-readelf) for each architecture in the NDK (under toolchains/), but you can use readelf for any architecture, as we will be doing basic inspection only. On Linux you need to have the “binutils” package installed for readelf, and “pax-utils” for scanelf.

Private API (Enforced since API 24)

Native libraries must use only public API, and must not link against non-NDK platform libraries. Starting with API 24 this rule is enforced and applications are no longer able to load non-NDK platform libraries. The rule is enforced by the dynamic linker, so non-public libraries are not accessible regardless of the way code tries to load them: System.loadLibrary(...), DT_NEEDED entries, and direct calls to dlopen(...) will fail in exactly the same way.

Users should have a consistent app experience across updates, and developers shouldn’t have to make emergency app updates to handle platform changes. For that reason, we recommend against using private C/C++ symbols. Private symbols aren’t tested as part of the Compatibility Test Suite (CTS) that all Android devices must pass. They may not exist, or they may behave differently. This makes apps that use them more likely to fail on specific devices, or on future releases --- as many developers found when Android 6.0 Marshmallow switched from OpenSSL to BoringSSL.

In order to reduce the user impact of this transition, we’ve identified a set of libraries that see significant use from Google Play’s most-installed apps, and that are feasible for us to support in the short term (including libandroid_runtime.so, libcutils.so, libcrypto.so, and libssl.so). In order to give you more time to transition, we will temporarily support these libraries; so if you see a warning that means your code will not work in a future release -- please fix it now!

$ readelf --dynamic libBroken.so | grep NEEDED
 0x00000001 (NEEDED)                     Shared library: [libnativehelper.so]
 0x00000001 (NEEDED)                     Shared library: [libutils.so]
 0x00000001 (NEEDED)                     Shared library: [libstagefright_foundation.so]
 0x00000001 (NEEDED)                     Shared library: [libmedia_jni.so]
 0x00000001 (NEEDED)                     Shared library: [liblog.so]
 0x00000001 (NEEDED)                     Shared library: [libdl.so]
 0x00000001 (NEEDED)                     Shared library: [libz.so]
 0x00000001 (NEEDED)                     Shared library: [libstdc++.so]
 0x00000001 (NEEDED)                     Shared library: [libm.so]
 0x00000001 (NEEDED)                     Shared library: [libc.so]

Potential problems: starting from API 24 the dynamic linker will not load private libraries, preventing the application from loading.

Resolution: rewrite your native code to rely only on public API. As a short term workaround, platform libraries without complex dependencies (libcutils.so) can be copied to the project. As a long term solution the relevant code must be copied to the project tree. SSL/Media/JNI internal/binder APIs should not be accessed from the native code. When necessary, native code should call appropriate public Java API methods.

A complete list of public libraries is available within the NDK, under platforms/android-API/usr/lib.

Note: SSL/crypto is a special case, applications must NOT use platform libcrypto and libssl libraries directly, even on older platforms. All applications should use GMS Security Provider to ensure they are protected from known vulnerabilities.

Missing Section Headers (Enforced since API 24)

Each ELF file has additional information contained in the section headers. These headers must be present now, because the dynamic linker uses them for sanity checking. Some developers try to strip them in an attempt to obfuscate the binary and prevent reverse engineering. (This doesn’t really help because it is possible to reconstruct the stripped information using widely-available tools.)

$ readelf --header libBroken.so | grep 'section headers'
  Start of section headers:          0 (bytes into file)
  Size of section headers:           0 (bytes)
  Number of section headers:         0
$

Resolution: remove the extra steps from your build that strip section headers.

Text Relocations (Enforced since API 23)

Starting with API 23, shared objects must not contain text relocations. That is, the code must be loaded as is and must not be modified. Such an approach reduces load time and improves security.

The usual reason for text relocations is non-position independent hand-written assembler. This is not common. Use the scanelf tool as described in our documentation for further diagnostics:

$ scanelf -qT libTextRel.so
  libTextRel.so: (memory/data?) [0x15E0E2] in (optimized out: previous simd_broken_op1) [0x15E0E0]
  libTextRel.so: (memory/data?) [0x15E3B2] in (optimized out: previous simd_broken_op2) [0x15E3B0]
[skipped the rest]

If you have no scanelf tool available, it is possible to do a basic check with readelf instead, look for either a TEXTREL entry or the TEXTREL flag. Either alone is sufficient. (The value corresponding to the TEXTREL entry is irrelevant and typically 0 --- simply the presence of the TEXTREL entry declares that the .so contains text relocations). This example has both indicators present:

$ readelf --dynamic libTextRel.so | grep TEXTREL
 0x00000016 (TEXTREL)                    0x0
 0x0000001e (FLAGS)                      SYMBOLIC TEXTREL BIND_NOW
$

Note: it is technically possible to have a shared object with the TEXTREL entry/flag but without any actual text relocations. This doesn’t happen with the NDK, but if you’re generating ELF files yourself make sure you’re not generating ELF files that claim to have text relocations, because the Android dynamic linker trusts the entry/flag.

Potential problems: Relocations enforce code pages being writable, and wastefully increase the number of dirty pages in memory. The dynamic linker has issued warnings about text relocations since Android K (API 19), but on API 23 and above it refuses to load code with text relocations.

Resolution: rewrite assembler to be position independent to ensure no text relocations are necessary. Check the Gentoo documentation for cookbook recipes.

Invalid DT_NEEDED Entries (Enforced since API 23)

While library dependencies (DT_NEEDED entries in the ELF headers) can be absolute paths, that doesn’t make sense on Android because you have no control over where your library will be installed by the system. A DT_NEEDED entry should be the same as the needed library’s SONAME, leaving the business of finding the library at runtime to the dynamic linker.

Before API 23, Android’s dynamic linker ignored the full path, and used only the basename (the part after the last ‘/’) when looking up the required libraries. Since API 23 the runtime linker will honor the DT_NEEDED exactly and so it won’t be able to load the library if it is not present in that exact location on the device.

Even worse, some build systems have bugs that cause them to insert DT_NEEDED entries that point to a file on the build host, something that cannot be found on the device.

$ readelf --dynamic libSample.so | grep NEEDED
 0x00000001 (NEEDED)                     Shared library: [libm.so]
 0x00000001 (NEEDED)                     Shared library: [libc.so]
 0x00000001 (NEEDED)                     Shared library: [libdl.so]
 0x00000001 (NEEDED)                     Shared library:
[C:\Users\build\Android\ci\jni\libBroken.so]
$

Potential problems: before API 23 the DT_NEEDED entry’s basename was used, but starting from API 23 the Android runtime will try to load the library using the path specified, and that path won’t exist on the device. There are broken third-party toolchains/build systems that use a path on a build host instead of the SONAME.

Resolution: make sure all required libraries are referenced by SONAME only. It is better to let the runtime linker to find and load those libraries as the location may change from device to device.

Missing SONAME (Used since API 23)

Each ELF shared object (“native library”) must have a SONAME (Shared Object Name) attribute. The NDK toolchain adds this attribute by default, so its absence indicates either a misconfigured alternative toolchain or a misconfiguration in your build system. A missing SONAME may lead to runtime issues such as the wrong library being loaded: the filename is used instead when this attribute is missing.

$ readelf --dynamic libWithSoName.so | grep SONAME
 0x0000000e (SONAME)                     Library soname: [libWithSoName.so]
$

Potential problems: namespace conflicts may lead to the wrong library being loaded at runtime, which leads to crashes when required symbols are not found, or you try to use an ABI-incompatible library that isn’t the library you were expecting.

Resolution: the current NDK generates the correct SONAME by default. Ensure you’re using the current NDK and that you haven’t configured your build system to generate incorrect SONAME entries (using the -soname linker option).

Please remember, clean, cross-platform code built with a current NDK should have no issues on Android N. We encourage you to revise your native code build so that it produces correct binaries.

Android Mobile Vision restores operation and adds Text API

Posted by Michael Sipe, Product Manager

As an important framework for finding objects in photos and video, Mobile Vision operation for Android devices is restored in Google Play Services v9.2.

This new version of Google Play Services fixes a download issue in Google Play Services v.9.0 that caused a service outage. See release notes for details.

We’re also pleased to announce the Text API, a new component for Android Mobile Vision.

The Text API’s optical character recognition technology reads Latin character text (e.g. English, Spanish, German, French, etc.) in photos and returns the text as well as the organizational structure (paragraphs, lines, words). Mobile apps can now:

  • Organize photos that contain text
  • Automate tedious data entry for credit cards, receipts, and business cards
  • Translate documents (along with the Cloud Translate API)
  • Keep track of real objects, such as reading the numbers on subway trains
  • Provide accessibility features

If you want to get started quickly, you can try our codelab which will get Android developers reading text with their apps in under an hour.

Like the Mobile Vision Face and Barcode components, the Text API runs on-device and is suitable for real-time applications. For more information, check out the Mobile Vision Developer site.

Create Intelligent, Context-Aware Apps with the Google Awareness APIs

Posted by Bhavik Singh, Product Manager

Last month at Google I/O 2016 we announced the new Google Awareness APIs, enabling your apps to intelligently react to user context using snapshots and fences with minimal impact on system resources.

Today we’re proud to announce that the Google Awareness API is available to all developers through Google Play services.

Using 7 different types of context—including location, weather, user activity, and nearby beacons—your app can better understand your users’ current situations, and use this information to provide optimized and customized experiences.

The Awareness API offers two ways to take advantage of context signals within your app:

  • The Snapshot API lets your app easily request information about the user's current context. For example, "give me the user's current location and the current weather conditions".
  • The Fence API lets your app react to changes in user’s context - and when it matches a certain set of conditions. For example, "tell me whenever the user is walking and their headphones are plugged in". Similar to the Geofencing API, once an awareness fence is registered, it can send callbacks to your app even when it's not running.

As a single, simplified surface, the Awareness APIs combine optimally processed context signals in new ways that were not previously possible, providing more accurate and insightful context cues, while also managing system resources to save battery and minimize bandwidth.

We’ve worked closely with some of our partners, who have already found amazing ways to integrate context awareness into their apps:

Trulia, an online residential real estate site, uses our Fence API to suggest open houses. When the weather is perfect and the user is walking around near a house they are interested in, Trulia sends a notification reminding them to stop by. This sort of tailored notification can help users engage with open houses at the perfect time for them.

SuperPlayer Music, on the other hand, uses our Snapshot API and Fence API to suggest the perfect music to match your mood. Whether you’re just finishing up a run and beginning to stretch, setting off on a long car ride, or just getting to the gym, their assistant can understand your context and suggest the right playlist for you.

With our initial set of signals and our awesome partners, we’re just getting started with the Awareness APIs. Join us on a journey to build tailored experiences within your apps, by getting started with the Google Awareness API developer documentation, and learn more by watching our Google I/O session


Improving Stability with Private C/C++ Symbol Restrictions in Android N

Posted by Dimitry Ivanov & Elliott Hughes, Software Engineers

As documented in the Android N behavioral changes, to protect Android users and apps from unforeseen crashes, Android N will restrict which libraries your C/C++ code can link against at runtime. As a result, if your app uses any private symbols from platform libraries, you will need to update it to either use the public NDK APIs or to include its own copy of those libraries. Some libraries are public: the Native Development Kit (NDK) exposes libandroid, libc, libcamera2ndk, libdl, libGLES, libjnigraphics, liblog, libm, libmediandk, libOpenMAXAL, libOpenSLES, libstdc++, libvulkan, and libz as part of the NDK API. Other libraries are private, and Android N only allows access to them for platform HALs, system daemons, and the like. If you aren’t sure whether your app uses private libraries, you can immediately check it for warnings on the N Developer Preview.

We’re making this change because it’s painful for users when their apps stop working after a platform update. Whether they blame the app developer or the platform, everybody loses. Users should have a consistent app experience across updates, and developers shouldn’t have to make emergency app updates to handle platform changes. For that reason, we recommend against using private C/C++ symbols. Private symbols aren’t tested as part of the Compatibility Test Suite (CTS) that all Android devices must pass. They may not exist, or they may behave differently. This makes apps that use them more likely to fail on specific devices, or on future releases --- as many developers found when Android 6.0 Marshmallow switched from OpenSSL to BoringSSL.

You may be surprised that there’s no STL in the list of NDK libraries. The three STL implementations included in the NDK -- the LLVM libc++, the GNU STL, and libstlport -- are intended to be bundled with your app, either by statically linking into your library, or by inclusion as a separate shared library. In the past, some developers have assumed that they didn’t need to package the library because the OS itself had a copy. This assumption is incorrect: a particular STL implementation may disappear (as was the case with stlport, which was removed in Marshmallow), may never have been available (as is the case with the GNU STL), or it may change in ABI incompatible ways (as is the case with the LLVM libc++).

In order to reduce the user impact of this transition, we’ve identified a set of libraries that see significant use from Google Play’s most-installed apps, and that are feasible for us to support in the short term (including libandroid_runtime.so, libcutils.so, libcrypto.so, and libssl.so). For legacy code in N, we will temporarily support these libraries in order to give you more time to transition. Note that we don't intend to continue this support in any future Android platform release, so if you see a warning that means your code will not work in a future release -- please fix it now!


Table 1. What to expect if your app is linking against private native libraries.

Libraries App's targetSdkVersion Runtime access via dynamic linker Impact, N Developer Preview Impact, Final N Release Impact, future platform version
NDK Public Any Accessible
Private (graylist) <=23 Temporarily accessible Warning / Toast Warning Error
>=24 Restricted Error Error Error
Private (all other)> Any Restricted Error Error Error

What behavior will I see?

Please test your app during the N Previews.

  • N Preview behavior
    • All public NDK libraries ( libandroid, libc, libcamera2ndk, libdl, libGLES, libjnigraphics, liblog, libm, libmediandk, libOpenMAXAL, libOpenSLES, libstdc++, libvulkan, and libz), plus libraries that are part of your app are accessible.
    • For all other libraries you’ll see a warning in logcat and a toast on the display. This will happen only if your app’s targetSdkVersion is less than N. If you change your manifest to target N, loading will fail: Java’s System.loadLibrary will throw, and C/C++’s dlopen(3) will return NULL.

  • N Final Release behavior
    • All NDK libraries ( libandroid, libc, libcamera2ndk, libdl, libGLES, libjnigraphics, liblog, libm, libmediandk, libOpenMAXAL, libOpenSLES, libstdc++, libvulkan, and libz), plus libraries that are part of your app are accessible.
    • For the temporarily accessible libraries (such as libandroid_runtime.so, libcutils.so, libcrypto.so, and libssl.so), you’ll see a warning in logcat for all API levels before N, but loading will fail if you update your app so that its targetSdkVersion is N or later.
    • Attempts to load any other libraries will fail in the final release of Android N, even if your app is targeting a pre-N platform version.
    • Future platform behavior
      • In O, all access to the temporarily accessible libraries will be removed. As a result, you should plan to update your app regardless of your targetSdkVersion prior to O. If you believe there is missing functionality from the NDK API that will make it impossible for you to transition off a temporarily accessible library, please file a bug here.

What do the errors look like?

Here’s some example logcat output from an app that hasn’t bumped its target SDK version (and so the restriction isn’t fully enforced because this is only the developer preview):

03-21 17:07:51.502 31234 31234 W linker : library "libandroid_runtime.so" ("/system/lib/libandroid_runtime.so") needed or dlopened by "/data/app/com.popular-app.android-2/lib/arm/libapplib.so" is not accessible for the namespace "classloader-namespace" - the access is temporarily granted as a workaround for http://b/26394120

This is telling you that your library “libapplib.so” refers to the library “libandroid_runtime.so”, which is a private library.

When Android N ships, or if you set your target SDK version to N now, you’ll see something like this if you try to use System.loadLibrary from Java:

java.lang.UnsatisfiedLinkError: dlopen failed: library "libcutils.so" ("/system/lib/libcutils.so") needed or dlopened by "/system/lib/libnativeloader.so" is not accessible for the namespace "classloader-namespace" at java.lang.Runtime.loadLibrary0(Runtime.java:977) at java.lang.System.loadLibrary(System.java:1602)

If you’re using dlopen(3) from C/C++ you’ll get a NULL return and dlerror(3) will return the same “dlopen failed...” string as shown above.

For more information about how to check if your app is using private symbols, see the FAQ on developer.android.com.

Android Developer Story: Sendy uses Google Play features to build for the next billion users

Posted by Lily Sheringham, Google Play team

Sendy is a door to door on-demand couriering platform founded in Nairobi, Kenya. It connects customers and logistics providers, providing two unique apps, one for the driver and one for the customer. Watch CEO & Co-founder, Meshack Alloys, and Android Developer, Jason Rogena, explain how they use Developer Console features, such as alpha and beta testing, as well as other tips and best practices, to build for the next billion users.

Learn more about building for billions and get more tips to grow your games business by opting-in to the Playbook app beta and download the Playbook app in the Google Play Store.

Notifications in Android N

Posted by Ian Lake, Developer Advocate

Android notifications are often a make-or-break interaction between your Android app and users. To provide a better user experience, notifications on Android N have received a visual refresh, improved support for custom views, and expanded functionality in the forms of Direct Reply, a new MessagingStyle, and bundled notifications.

Same notification, new look

The first and most obvious change is that the default look and feel of notifications has significantly changed. Many of the fields that were spread around the notifications have been collapsed into a new header row with your app’s icon and name anchoring the notification. This change ensured that the title, text, and large icon are given the most amount of space possible and, as a result, notifications are generally slightly larger now and easier to read.


Given the single header row, it is more important than ever that the information there is useful. When you target Android N, by default the time will be hidden - if you have a time critical notification such as a messaging app, you can re-enable it with setShowWhen(true). In addition, the subtext will take precedence over any content info you set: only if you target a previous version of Android will both appear. In all cases, ensure that the subtext is relevant and useful - don’t add an account email address as your subtext if the user only has one account, for example.

Notification actions have also received a redesign and are now in a visually separate bar below the notification.


You’ll note that the icons are not present in the new notifications; instead more room is provided for the labels themselves in the constrained space of the notification shade. However, the notification action icons are still required and continue to be used on older versions of Android and on devices such as Android Wear.

If you’ve been building your notification with NotificationCompat.Builder and the standard styles available to you there, you’ll get the new look and feel by default with no code changes required.

Better Support for Custom Views

If you’re instead building your notification from custom RemoteViews, adapting to any new style has been challenging. With the new header, expanding behavior, actions, and large icon positioning as separate elements from the main text+title of the notification, we’ve introduced a new DecoratedCustomViewStyle and DecoratedMediaCustomViewStyle to provide all of these elements, allowing you to focus only on the content portion with the new setCustomContentView() method.


This also ensures that future look and feel changes should be significantly easier to adapt to as these styles will be updated alongside the platform with no code changes needed on the app side.

Direct Reply

While notification actions have already been able to launch an Activity or do background work with a Service or BroadcastReceiver, Direct Reply allows you to build an action that directly receives text input inline with the notification actions.


Direct Reply uses the same RemoteInput API - originally introduced for Android Wear - to mark an Action as being able to directly receive input from the user.

The RemoteInput itself contains information like the key which will be used to later retrieve the input and the hint text which is displayed before the user starts typing.

// Where should direct replies be put in the intent bundle (can be any string)
private static final String KEY_TEXT_REPLY = "key_text_reply";

// Create the RemoteInput specifying this key
String replyLabel = getString(R.string.reply_label);
RemoteInput remoteInput = new RemoteInput.Builder(KEY_TEXT_REPLY)
        .setLabel(replyLabel)
        .build();


Once you’ve constructed the RemoteInput, it can be attached to your Action via the aptly named addRemoteInput() method. You might consider also calling setAllowGeneratedReplies(true) to enable Android Wear 2.0 to generate Smart Reply choices when available and make it easier for users to quickly respond.

// Add to your action, enabling Direct Reply for it
NotificationCompat.Action action =
    new NotificationCompat.Action.Builder(R.drawable.reply, replyLabel, pendingIntent)
        .addRemoteInput(remoteInput)
        .setAllowGeneratedReplies(true)
        .build();


Keep in mind that the pendingIntent being passed into your Action should be an Activity on Marshmallow and lower devices that don’t support Direct Reply (as you’ll want to dismiss the lock screen, start an Activity, and focus the input field to have the user type their reply) and should be a Service (if you need to do work on a separate thread) or BroadcastReceiver (which runs on the UI thread) on Android N devices so as the process the text input in the background even from the lock screen. (There is a separate user control to enable/disable Direct Reply from a locked device in the system settings.)

Extracting the text input in your Service/BroadcastReceiver is then possible with the help of the RemoteInput.getResultsFromIntent() method:

private CharSequence getMessageText(Intent intent) {
    Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
    if (remoteInput != null) {
        return remoteInput.getCharSequence(KEY_TEXT_REPLY);
    }
    return null;
 }


After you’ve processed the text, you must update the notification. This is the trigger which hides the Direct Reply UI and should be used as a technique to confirm to the user that their reply was received and processed correctly.

For most templates, this should involve using the new setRemoteInputHistory() method which appends the reply to the bottom of the notification. Additional replies should be appended to the history until the main content is updated (such as the other person replying).


However, if you’re building a messaging app and expect back and forth conversations, you should use MessagingStyle and append the additional message to it.

MessagingStyle

We’ve optimized the experience for displaying an ongoing conversation and using Direct Reply with the new MessagingStyle.


This style provides built-in formatting for multiple messages added via the addMessage() method. Each message supports passing in the text itself, a timestamp, and the sender of the message (making it easy to support group conversations).

builder.setStyle(new NotificationCompat.MessagingStyle("Me")
    .setConversationTitle("Team lunch")
    .addMessage("Hi", timestampMillis1, null) // Pass in null for user.
    .addMessage("What's up?", timestampMillis2, "Coworker")
    .addMessage("Not much", timestampMillis3, null)
    .addMessage("How about lunch?", timestampMillis4, "Coworker"));


You’ll note that this style has first-class support for specifically denoting messages from the user and filling in their name (in this case with “Me”) and setting an optional conversation title. While this can be done manually with a BigTextStyle, by using this style Android Wear 2.0 users will get immediate inline responses without kicking them out of the expanded notification view, making for a seamless experience without needing to build a full Wear app.

Bundled Notifications

Once you’ve built a great notification by using the new visual designs, Direct Reply, MessagingStyle, and all of our previous best practices, it is important to think about the overall notification experience, particularly if you post multiple notifications (say, one per ongoing conversation or per new email thread).


Bundled notifications offer the best of both worlds: a single summary notification for when users are looking at other notifications or want to act on all notifications simultaneously and the ability to expand the group to act on individual notifications (including using actions and Direct Reply).

If you’ve built stacking notifications for Android Wear, the API used here is exactly the same. Simply add setGroup() to each individual notification to bundle those notifications together. You’re not limited to one group, so bundle notifications appropriately. For an email app, you might consider one bundle per account for instance.

It is important to also create a summary notification. This summary notification, denoted by setGroupSummary(true), is the only notification that appears on Marshmallow and lower devices and should (you guessed it) summarize all of the individual notifications. This is an opportune time to use the InboxStyle, although using it is not a requirement. On Android N and higher devices, some information (such as the subtext, content intent, and delete intent) is extracted from the summary notification to produce the collapsed notification for the bundled notifications so you should continue to generate a summary notification on all API levels.

To improve the overall user experience on Android N devices, posting 4 or more notifications without a group will cause those notifications to be automatically bundled.

N is for Notifications

Notifications on Android have been a constant area of progressive enhancement. From the single tap targets of the Gingerbread era to expandable notifications, actions, MediaStyle, and now features such as Direct Reply and bundled notifications, notifications play an important part of the overall user experience on Android.

With many new tools to use (and NotificationCompat to help with backward compatibility), I’m excited to see how you use them to #BuildBetterApps

Follow the Android Development Patterns Collection for more!

Bring Your Android App to Chromebooks

Posted by Dylan Reid and Elijah Taylor, Software Engineers, Chrome OS

Users love Chromebooks for their speed, security and simplicity. According to IDC1, in Q1 of this year Chromebook shipments overtook Macs in the U.S. That means, thanks to your support, in the U.S. Chrome OS is now the second most popular PC operating system.  As we continue to increase our focus on mobility, we want to make sure your apps are easily available on this new form factor, reaching the many Chrome devices while maintaining a great experience.

Today we announced that we’re adding Android apps to Chromebooks, which means users will be able to install the apps they know and love. Later this year you can expand your app’s reach to a new hardware platform and wider audience while maximizing the Google Play ecosystem. With expanded app availability, new use cases and improved workflows can be achieved for all Chromebook users, whether for personal use, for work or for education.  As a developer we encourage you to test your app as described here.



Developers can start to optimize their app for the Chromebook form factor in advance of launch later in 2016. Here are some of the benefits:
  • Android Apps can be shown in 3 different window sizes to allow the best experience
  • Users can multi-task with multiple Android apps in moveable windows along with a full desktop browser, all within the familiar Chrome OS interface.
  • Keyboard, mouse, and touch input will seamlessly work together
  • Users will get Android notifications on their Chromebooks
  • Android apps benefit from the Wifi or Bluetooth connectivity setup by the user or the administrator
  • File sharing is seamless between Chrome and Android apps through the Files app
  • Performance of demanding apps such as games or design apps is excellent
In addition to being a great personal device, one of the reasons Chromebooks are popular in schools and businesses is that you can centrally manage and configure them with 200+ policies. Administrators can manage Android apps on Chromebooks using the same Admin Console. In addition to whitelisting or push installing specific apps to users, admins can selectively enable them for parts of their organization while disabling in others.

Please come to our Google I/O session on May 19th at 4 pm. You will hear directly  from our friendly engineers on how to optimize your Android app for Chromebooks. We are making the feature available in early June on Asus Chromebook Flip, Chromebook Pixel (2015) and Acer Chromebook R11 specifically for developers to have sufficient time to test their apps. For the actual launch and thereafter we will keep adding support for the following list of devices. Please see detailed instructions on how to get started with testing your apps.

1 - IDC’s Worldwide Quarterly PC Tracker, May 2016

Enhancing Android Pay APIs

Posted by Pali Bhat, Senior Director, Product Management

Today, we’re enhancing our APIs, making it easier than ever for the developer community to integrate with Android Pay. With just a few lines of code, you can enable quick and seamless checkout to help increase purchase conversions and ongoing engagement.

Improve conversions within apps

We’ve been working with popular apps such as Airbnb, Yelp Eat24, Kickstarter, TicketMaster, Uber and many others to bring the ease of speedy checkouts to apps. We also want to make the same great in-app experience available to all developers, big or small. So we’re taking a few steps:

  • Earlier today, we announced Android Instant Apps, which gives users the ability to pay using Android Pay with a single tap, without the friction of getting a user to install the app to complete their transaction. 

Example of Android Pay in Android Instant Apps

  • We’re opening the Android Pay API to all developers selling physical goods and services in markets where Android Pay is available—just sign up at developers.google.com/android-pay/
  • We’ve teamed up with payment processors globally so developers can integrate Android Pay with their Android apps in just a few hours.

Enhance mobile web payments

Many users continue to make purchases on mobile sites. But buying something from a website on your phone can be clumsy and cumbersome, which results in much lower conversion rates on mobile sites than on desktop sites.

To make painful web checkout forms a thing of the past, we will be launching PaymentRequest, a brand new web API that we are developing together with Chrome and standardizing across browsers through W3C. Android Pay will be part of this API to allow users to pay on mobile websites as they do in-store and in-app.

Example of Android Pay in PaymentRequest
Drive deeper engagement

Thanks for all the great feedback on our Save to Android Pay API since launch. You spoke and we’ve listened: We think you’ll be thrilled with the latest improvements to the Save to Android Pay API. The following enhancements help developers build stronger loyalty and engagement with new and existing customers:

  • Enable users to add offers, loyalty cards and gift cards in the Android Pay app with the tap of a button. Simply add a deep link to an email, SMS message, push notification or within an app and you’re all set.
  • Enroll new customers into a loyalty program in a variety of ways with the new simplified sign-up feature. Customers can sign-up either in store via a NFC tap or through a sign-up page linked from an Android Pay transaction notification.

Example sign-up feature for Walgreens Balance Reward®  
via Save to Android Pay from transaction notification
We believe that mobile payments can make for a better, more secure shopping experience - so we're in this together for the long haul. We’re building a robust Android Pay ecosystem, one that’s open and scalable, to enable developers to drive mobile payments - and their businesses - forward. We're very excited for the road ahead and we hope you are too.

To learn more about Android Pay and share your feedback, visit our developer pages.

What’s new in Google Play at I/O 2016: better betas, the pre-launch report, benchmarks, a new Play Console app, and more

Posted by Purnima Kochikar, Director, Google Play Apps & Games

Google Play reaches over 1 billion monthly active users giving developers the world’s largest app distribution platform. Last year, Play users installed apps 65 billion times. To keep that great momentum going, we’re continuing to listen to your feedback and invest in more ways to help you grow your app or game business. Today, we’re sharing new features that benefit developers of all sizes.

 

Improvements to beta tests and app discovery on Google Play

Beta testing is a crucial tool that many developers use in the Google Play Developer Console to test their apps with real users, gather feedback, and make improvements before launching widely. Open beta tests are helpful to get feedback from a large group of users and allow any user to join a beta test. We're making open beta tests easier to find and participate in: apps that are available only as open betas and aren’t in production yet will soon appear in Play search results, users will be able to opt-in from Play store listings directly, and users will be able to send you private feedback through your Play store listing too.

We'll also be adding a new featured section to the store, called Google Play Early Access, showcasing a hand-picked group of promising open betas that haven’t gone to production yet.

There are more than a million apps available on Google Play and we continue to work on making it easy for people to discover the apps they’ll love. To that end, you’ll start seeing new collections on the store for tasks that might require a combination of apps. For example, when you're buying a house, you’ll see the best apps for finding real estate, keeping notes, getting a mortgage, and travelling in the area in one handy collection. Developers don’t need to take any action to take advantage of this benefit, apps will automatically be chosen. These contextual collections make it easier for users to discover complimentary apps as well as new types of apps.
Users can now opt-in to beta tests from the Play Store
An example of a new collection for apps relating to buying a house
Improve your app with the Play pre-launch report

Your app business relies on having high quality apps. To achieve quality, your apps need to be tested on a range of real devices before you ship them to your users. Play’s new pre-launch report summarizes issues found when testing your app on Firebase Test Lab for Android on a wide range of devices.

The pre-launch report in the Developer Console
Along with diagnostics to help you fix any crashes we detected in your app, your reports will also include screenshots from devices that use different Android versions, languages, and screen resolutions. These can help you find layout issues. We’ve also included early warnings of known security vulnerabilities that may have sneaked into your app -- even via third party libraries you rely on. You can enable the pre-launch report in the Developer Console.

Gain deeper insights from user reviews at a glance and reply to user reviews more easily

Your app reviews offer a wealth of information on what your users like and dislike about your app. We’re expanding on the improvements we made to ratings and reviews earlier this year, to offer you more ways to take advantage of reviews and better engage your audience.

Review benchmarks let you see your app’s rating distribution compared to similar apps in your category for a list of common topics which are relevant for all apps – like design, stability, and speed. You are also able to see how each area impacts your app’s rating. Review topics will let you see your app’s rating distribution for a list of topics which are specific to your app. With this analysis functionality, you can more easily identify what users think of your app and where to focus your improvement efforts.

Review benchmarks in the Developer Console
Developers frequently tell us they find replying to reviews valuable as a channel to directly engage their audience and gather feedback. In fact, we have found that users who update their star rating after a developer has responded to their review increase it by an average of 0.7 stars. For developers who have their own customer support solutions, we’re making replying easier with a new Reply to Reviews API. In the last few months, we’ve tested the API with Zendesk and Conversocial, so you can now start replying to reviews directly from those popular platforms or build your own custom integration.



Developers can now reply to reviews on Google Play from platorms such as Zendesk and Conversocial
Understand more about user acquisition and conversion, and see how you’re doing compared to others

The User Acquisition performance report in the Developer Console gives you a snapshot of how many users visit your store listing, how many install your app, and how many go on to make purchases. We’ve now added the ability to see user acquisition data by country and you’ll soon be able to see user acquisition benchmarks and compare your app’s conversion rates to similar apps on the Play store. With this data, you can find opportunities to focus your marketing efforts and increase your installs with tools like Store Listing Experiments.


User acquisition country data in the Developer Console

Building apps and games for billions of users

Hundreds of millions of users, many of them in emerging markets, are coming online and, for many of them, their first experience is on an Android device.
 
To help you get your app ready for this opportunity, we’ve created Building for Billions guidelines with a development checklist to help you optimize your app. You can also get more in-depth tips and best practices for expanding to new markets in the accompanying Building for Billions Playbook

To help you meet local expectations when you set your prices and make purchases more attractive to your users, the Developer Console will now automatically round prices to local conventions in each market. For example, for a US app priced at $1.99, a user in Japan would see ¥200 rather than a non-rounded price from a straight FX conversion. You can also set up pricing templates to change pricing for products in bulk. You can make this change in the Developer Console.

While you're working on getting your app ready for billions of users, we've been enhancing the Google Play experience for them too. With improved compression, we've made app updates more data efficient, and we're focusing on making the Play Store itself faster than ever on all connection types.

We’ve also revamped how we select visible apps in key markets like India and Brazil to better showcase apps that are more relevant locally and apps made by local developers. And we continue to add more payment methods in new countries, including carrier billing and gift cards in India and Indonesia.

Two new apps: Get your app data and important notifications on the go, and stay up to date with best practices

To give you access to your data when you need it, and to keep you informed of crucial business updates with notifications, we’re launching the Play Console app. You can access your app’s data including installs, uninstalls, crashes, ratings, and reviews. You can also receive push notifications for important news like when your app update is live on Google Play. And you can even reply to reviews directly in the app, making it easier and quicker to engage your audience when you want to. Get the Play Console app on Google Play today.

Staying on top of all the features and best practices and strategies you should consider when growing your business can be a challenge. We’ve built another app, the Playbook by Google Play. The Playbook is a tailored list, based on your objectives, of the latest articles and videos from Google experts and across the web to help you grow a successful business on Google Play. Join the Playbook beta today and let us know your feedback.
The Play Console app
Playbook by Google Play

Finally, we will be soon making some updates to the Developer Distribution Agreement (DDA), which includes the ability for family members to share purchased apps on Google Play. Here you can see the updated DDA.



To learn more about all of these features, tune-in live to ‘What’s new in Google Play for developers’ at 11am PDT / 2pm EDT / 7:00pm GMT+1 on May 19 on the Google Developers YouTube channel.

If you’re attending I/O, come and visit the Google Play sandbox to get your app reviewed by experts.

Whether you’re attending I/O in person, at one of the many I/O Extended events around the world, or just watching from home, you can find more Google Play sessions in the I/O 2016 schedule.