Tuesday, February 7, 2017
API Updates for Sign In with Google
API Updates for Sign In with Google
Posted by Laurence Moroney
With the release of Google Play services 8.3, weve made a lot of improvements to Sign-In with Google. In the first blog post of this ongoing series, we discussed the user interface improvements. Today, we will look further into the changes to the API to make building apps that Sign-In with Google easier than ever before.
Changes to basic sign in flow
When building apps that sign in with Google, youll notice that there are a lot of changes to make your code easier to understand and maintain.
Prior to this release, if you built an app that used Sign-In with Google, you would build one that attempted to connect to a GoogleApiClient. At this point the user was presented with an account picker and/or a permissions dialog, both of which would trigger a connection failure. You would have to handle these connection failures in order to sign in. Once the GoogleApiClient connected, then the user was considered to be signed in and the permissions could be granted. The process is documented in a CodeLab here.
Now, your code can be greatly simplified.
The process of signing in and connecting the GoogleApiClient are handled separately. Signing in is achieved with a GoogleSignInOptions object, on which you specify the parameters of the sign in, such as scopes that you desire. Heres a code example:
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestEmail() .build();
Once you have a GoogleSignInOptions object, you can use it to configure the GoogleApiClient:
Heres where your code will diverge greatly in the new API. Now, if you want to connect with a Google Account, instead of handling errors on the GoogleApiClient, youll instead use an intent that is initialized using the client.
Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient); startActivityForResult(signInIntent, RC_SIGN_IN);
Starting the intent will give you the account picker, and the scopes permission dialog if your GoogleSignInOptions requested anything other than basic scope. Once the user has finished interacting with the dialogs, an OnActivityResult callback will fire, and it will contain the requisite sign-in information.
@Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...); if (requestCode == RC_SIGN_IN) { GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data); handleSignInResult(result); } }
You can learn more about this code in the Integrating Google Sign-In quickstart, or by looking at the sample code.
Silent Sign-In
To further reduce friction for users in a multi-device world, the API supports silent sign in. In this case, if your user has given authorization to the app on a different device, the details will follow their account, and they dont need to re-give them on future devices that they sign into, unless they deauthorize. An existing sign-in is also cached and available synchronously on the current device is available.
Using it is as simple as calling the silentSignIn method on the API.
OptionalPendingResultopr = Auth.GoogleSignInApi.silentSignIn(mGoogleApiClient);
Then, you can check the isDone() method on the pending result -- and if it returns true, the user is signed in, and you can get their status from the PendingResult. If it isnt then you have to wait for a callback with the SignInResult
if (pendingResult.isDone()) { doStuffWith(pendingResult.get()); } else { // Theres no immediate result ready, displays some progress indicator and waits for the // async callback. showProgressIndicator(); pendingResult.setResultCallback(new ResultCallback<GoogleSignInResult>() { @Override public void onResult(@NonNull GoogleSignInResult result) { updateButtonsAndStatusFromSignInResult(result); hideProgressIndicator(); } }); }
Customizing the Sign-In Button
When building apps that Sign-In with Google, we provide a SignInButton object that has the Google branding, and which looks like this:

You can customize this button with a number of properties and constants that are documented in the API here.
The branding guidelines are available here, and they include versions of the buttons in PNG, SVG, EPS and other formats in many resolutions, including all the different states of the button. These files may be used for localization of the button, and if you need to match the style of the button to your app, guidelines are provided.
This only deals with the Android side of your app. Youll likely have a server back end, and you may want to use the credentials on that securely.
In the next blog post, well discuss how to use Sign-In with Google in server-side scenarios, including how to securely pass your credentials to your own server, and how to use Google back-end services, such as Google Drive, with the permission and credentials from users.
Available link for download
Sunday, October 23, 2016
API 23 SDK now available for Android Wear
API 23 SDK now available for Android Wear
Posted by Wayne Piekarski, Developer Advocate
The new LG Watch Urbane 2nd Edition LTE is the first watch to run Android 6.0 Marshmallow (API 23) for Android Wear. Currently, all other Android Wear watches implement API 22, and in the coming months, these will receive an OTA update for API 23 as well.
So what does this mean for you as an Android Wear developer? You will need to ensure that your apps are compatible with both API 23 and API 22 watches. While you can start implementing the new features in this post, you still need to maintain backwards compatibility until all watches are upgraded.
New permissions model and samples
API 23 introduces a new runtime permissions model for both phones and watches. The new permissions model allows users to pick and choose which permissions to grant apps at the time of use. In addition, new permissions settings allow users to turn on and off app permissions at any time.
To use the new permissions model on Wear, read Permissions on Android Wear. This training guide provides an in-depth discussion of Wear-specific scenarios, such as when your Wear app relies on a phone-side permission. In addition, all of the Android Wear samples have been updated to use the new permissions model, and a new RuntimePermissionsWear sample shows how to handle permission requests across devices.
When you are ready, you can update your application on both the phone and watch side to use compileSdkVersion 23 and targetSdkVersion 23. Make sure that you check and request the permissions needed by your app at runtime, on both the phone and the watch. It is important that you do not change targetSdkVersion to 23 until you have implemented the permission checks properly, since it changes how the system installs and runs the app. For example, an API call that might have previously returned a result could now fail, causing the app to behave in unexpected ways.

-round and -notround resource qualifiers
API 23 makes it easier to build apps for both round and square Android Wear watches. We listened to your feedback and added new resource qualifiers for -round and -notround, so you can use the resource system to load the appropriate images, layouts, and strings based on the type of watch you are working with. You can also combine this with existing resource qualifiers -hdpi, -tvdpi, -280dpi, and -360dpi for the various Android Wear watches that are currently available. All of the existing classes in the wearable UI library, such as WatchViewStub, BoxInsetLayout, and WearableFrameLayout will continue to work as well, so you do not need to change your code. The -round and -notround resource qualifiers will not work on API 22 devices, so you cannot assume they will be available until all devices are on API 23.
Watches with speakers
The LG Watch Urbane 2nd Edition LTE is the first watch to include speaker support, so you can now add sounds to your Wear app. You can play audio files using the same APIs that are available on Android phones, such as AudioTrack, MediaPlayer, and ExoPlayer. Check out the sample and documentation to learn how to detect when the speaker is available on a Wear device and play sounds through it.
Intel x86 support
The new TAG Heuer Connected, along with other upcoming Android Wear watches, is based on Intel x86 processors. If you are working only with Java code, your apps will automatically work on any architecture. However, if youre using the NDK, youll need to provide both armeabi-v7a and x86 shared libraries in your wearable APK. Since only one wearable app can be bundled in a phone app, it is not possible to deliver different APKs to different watches based on architecture. If your wearable APK is missing an x86 library, it will fail to install on x86 watches with INSTALL_FAILED_NO_MATCHING_ABIS and code -113.
If you are using Android Studio, you will need to adjust your build.gradle file to include:
ndk { abiFilters = [armeabi-v7a,x86] }
If you are using the NDK directly, you will need to modify your Application.mk file to use:
APP_ABI := armeabi-v7a x86
These changes should only be made for the wearable APK, and you can continue to support other ABIs on the phone side. You can test your application by checking if it works on the x86 emulator provided by the SDK Manager.
Updated emulator
New Android Wear emulator images for API 23 and x86 watches are available to download from the SDK Manager in Android Studio. We have also added profiles that represent every available Android Wear watch, so you can easily test on any device you want. It is also important that you understand and test all the combinations of phones (API <= 22, API = 23) and wearables (API 22, API 23), so that your app works for all users.
Updates to existing watches
The new emulator images allow you to get started immediately with testing and deploying updated apps for users with API 23 watches. The schedule for updating existing Android Wear watches via OTA updates has not been announced yet. We will announce the update schedule on the Android Wear Developers Google+ community. Well also let you know when the rollout is complete, and API 22 support for Android Wear is no longer needed.

Available link for download
Monday, September 26, 2016
Android Mobile Vision restores operation and adds Text API
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.
Were also pleased to announce the Text API, a new component for Android Mobile Vision.
The Text APIs 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.
Available link for download
Tuesday, September 20, 2016
Build beautifully for Android Wear’s Round Screen using API 23’s round identifier
Build beautifully for Android Wear’s Round Screen using API 23’s round identifier
Posted by Hoi Lam, Android Wear Developer Advocate
Android Wear is about choice. From the beginning, users could choose the style they wanted, including watches with circular screens. With Android Wear API 23, we have enabled even better developer support so that you can code delightful experiences backed by beautiful code. The key component of this is the new round resource identifier which helps you separate resource files such as layouts, dimens between round and square devices. In this blog post, I will lay out the options that developers have and why you should consider dimens.xml! In addition, I will outline how best to deal with devices which have a chin.
Getting started? Consider BoxInsetLayout!
If all your content can fit into a single square screen, use the BoxInsetLayout. This class has been included in the Wearable Support Library from the start and helps you put all the content into the middle square area of the circular screen and is ignored by square screens. For details on how to use the BoxInsetLayout, refer to the Use a Shape-Aware Layout section in our developer guide.
![]() | ![]() |
Goodbye WatchViewStub, Hello layout-round!
Developers have been able to specify different layouts for square and round watches using WatchViewStub from the beginning. With Android Wear API 23, this has become even easier. Developers can put different layouts into layout-round and layout folders. Previously with WatchViewStub, developers needed to wait until the layout was inflated before attaching view elements, this added significant complexity to the code. This is eliminated using the -round identifier:
Pre Android Wear API 23 - WatchViewStub (4 files) |
1. layout/activity_main.xml 2. layout/rect_activity_main.xml - layout for square watches 3. layout/round_activity_main.xml - layout for round watches 4. MainAcitivity.java |
After Android Wear API 23 - layout-round (3 files) |
1. layout-notround/activity_main.xml - layout for square watches 2. layout-round/activity_main.xml - layout for round watches 3. MainAcitivity.java |
That said, since WatchViewStub is part of the Android Wear Support Library, if your current code uses it, it is not a breaking change and you can refactor your code at your convenience. In addition to the -round identifier, developers also use the -notround idenifier to separate resources. So why would you want to use it in place of the default layout? Its a matter of style. If you have a mixture of layouts, you might consider organising layouts in this way:
- layout/ - Layouts which works for both circular and square watches
- layout-round/ and layout-notround/ - Screen shape specific layouts
An even better way to develop for round - values-round/dimens.xml
Maintaining multiple layout files is potentially painful. Each time you add a screen element, you need to go to all the layout files and add this. With mobile devices, you will usually only do this to specify different layouts for phones and tablets and rarely for different phone resolutions. For watches, unless your screen layout is significantly different between round and square (which is rare based on the applications I have seen thus far), you should consider using different dimens.xml instead.
As I experimented with the -round identifier, I found that the easiest way to build for round and square watches is actually by specifying values/dimens.xml and values-round/dimens.xml. By specifying different padding settings, I am able to create the following layout with the same layout.xml file and two dimens files - one for square and one for round. The values used suits this layout, you should experiment with different values to see what works best:
values-round/dimens.xml | values/dimens.xml |
|
|
![]() | ![]() |
Before API 23, to do the same would have involved a significant amount of boilerplate code manually specifying the different dimensions for all elements on the screen. With the -round identifier, this is now easy to do in API 23 and is my favourite way to build round / square layouts.
Dont forget the chin!
Some watches have an inset (also know as a chin) in an otherwise circular screen. So how should you can you build a beautiful layout while keeping your code elegant? Consider this design:
![]() | activity_main.xml
|
If we are to do nothing, the heart shape button will disappear into the chin. Luckily, theres an easy way to fix this with fitsSystemWindows:
<ImageButton
android:id="@+id/lovebtn"
android:src="@drawable/ic_favourite"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:fitsSystemWindows="true"
.../>
For the eagle-eyed (middle image of the screen shown below under fitsSystemWindows=true), you might noticed that the top and bottom padding that we have put in is lost. This is one of the main side effect of using fitsSystemWindows. This is because fitsSystemWindows works by overriding the padding to make it fits the system window. So how do we fix this? We can replace padding with InsetDrawables:
inset_favourite.xml
<inset
>="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/ic_favourite"
android:insetTop="5dp"
android:insetBottom="5dp" />
activity_main.xml
<ImageButton
android:id="@+id/lovebtn"
android:src="@drawable/inset_favourite"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:fitsSystemWindows="true"
.../>
Although the padding setting in the layout will be ignored, the code is tidier if we remove this redundant code.
and use InsetDrawable | ||
![]() | ![]() | ![]() |
If you require more control than what is possible declaratively using xml, you can also programmatically adjust your layout. To obtain the size of the chin you should attach a View.OnApplyWindowInsetsListener to the outermost view of your layout. Also dont forget to call v.onApplyWindowInsets(insets). Otherwise, the new listener will consume the inset and inner elements which react to insets may not react.
How to obtain the screen chin size programmatically
MainActivity.java
private int mChinSize;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// find the outermost element
final View container = findViewById(R.id.outer_container);
// attach a View.OnApplyWindowInsetsListener
container.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() {
@Override
public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {
mChinSize = insets.getSystemWindowInsetBottom();
// The following line is important for inner elements which react to insets
v.onApplyWindowInsets(insets);
return insets;
}
});
}
Last but not least, remember to test your code! Since last year, we have included several device images for Android Wear devices with a chin to make testing easier and faster:

Square peg in a round hole no more!
Android Wear has always been about empowering users to wear what they want. A major part in enabling this is the round screen. With API 23 and the -round resource identifier, it is easier than ever to build for both round and square watches - delightful experiences backed by beautiful code!
Additional Resources
Why would I want to fitsSystemWindows? by Ian Lake - Best practice for using this powerful tool including its limitations. ScreenInfo Utility by Wayne Piekarski - Get useful information for your display including DPI, chin size, etc.
Available link for download
Friday, August 26, 2016
Always on Android Wear apps with the Google Maps API
Always on Android Wear apps with the Google Maps API
Originally posted on the Geo Developers Blog
Posted by Ankur Kotwal, Developer Advocate
Some Android Wear apps are most useful when they are always available to the user, even at a glance. Now, with Google Play Services 8.1, the Google Maps Android API supports ambient mode, the API that provides always-on capabilities. In ambient mode, the map adjusts its style to provide a simplified, low-color rendering of the map. All markers, objects, and UI controls disappear, keeping the map on the screen while letting the user know that it is not currently ready to accept user input. An important advantage is the camera position and zoom level are retained, thus keeping the users context within the map.
The screenshot below show how maps appear in interactive mode and in ambient mode.

To implement ambient mode in your maps, follow these steps:
- Set your your targetSDKVersion to 22 or higher
- Add the following dependencies to build.gradle for your app to add the wearable support library.
dependencies { compile com.google.android.support:wearable:1.2.0 provided com.google.android.wearable:wearable:1.0.0 }
- Add the wearable shared library entry into the wearable app manifest:
<application> <uses-library android_name="com.google.android.wearable" android_required="false" /> ... </application>
- Add the WAKE_LOCK permission to the handheld and wearable app manifest:
<uses-permission android_name="android.permission.WAKE_LOCK" />
- Have your Activity extend WearableActivity. This will provide the overrides that notify your app when the wearable enters, exits and provides screen updates in ambient mode.
- In the onCreate() method of your activity, call the
setAmbientEnabled()
method. This tells the framework that the app should enter ambient mode rather than returning to the watch face. - Set your map to support ambient mode. You can do this by setting the attribute
map:ambientEnabled="true" in the activitys XML layout file, or programmatically by setting GoogleMapOptions.ambientEnabled(true)
. This informs the API to pre-load necessary map tiles for ambient mode. - When the activity switches to ambient mode, the system calls the
onEnterAmbient()
method in your wearable activity. OverrideonEnterAmbient()
and callMapFragment.onEnterAmbient()
orMapView.onEnterAmbient()
. The map changes to a non-interactive, low-color rendering of the map. - When in ambient mode, your app can update the display every minute by overriding
onUpdateAmbient()
. If you need more frequent updates, check out this guide. - When the activity leaves ambient mode, the system calls the
onExitAmbient()
method in your wearable activity. OverrideonExitAmbient()
and callMapFragment.onExitAmbient()
orMapView.onExitAmbient()
. The map returns to the normal rendering and is now ready to accept user input.
With always-on maps on Android Wear, you can now show maps at a glance. For more information on these APIs check out the documentation and the sample code.
Available link for download