Posted by Ian Lake, Developer Advocate
With the release of the 25.1.0 Support Library, there's a new entry in the family: the ExifInterface Support Library. With significant improvements introduced in Android 7.1 to the framework's ExifInterface, it only made sense to make those available to all API 9+ devices via the Support Library's ExifInterface.
ExifInterface
The basics are still the same: the ability to read and write Exif tags embedded within image files: now with 140 different attributes (almost 100 of them new to Android 7.1/this Support Library!) including information about the camera itself, the camera settings, orientation, and GPS coordinates.
For Camera apps, the writing is probably the most important - writing attributes is still limited to JPEG image files. Now, normally you wouldn't need to use this during the actual camera capturing itself - you'd instead be calling the Camera2 API CaptureRequest.Builder.set() with JPEG_ORIENTATION, JPEG_GPS_LOCATION or the equivalents in the Camera1 Camera.Parameters. However, using ExifInterface allows you to make changes to the file after the fact (say, removing the location information on the user's request).
CaptureRequest.Builder.set()
JPEG_ORIENTATION
JPEG_GPS_LOCATION
Camera.Parameters
For the rest of us though, reading those attributes is going to be our bread-and-butter; this is where we see the biggest improvements.
Firstly, you can read Exif data from JPEG and raw images (specifically, DNG, CR2, NEF, NRW, ARW, RW2, ORF, PEF, SRW and RAF files). Under the hood, this was a major restructuring, removing all native dependencies and building an extensive test suite to ensure that everything actually works.
For apps that receive images from other apps with a content:// URI (such as those sent by apps that target API 24 or higher), ExifInterface now works directly off of an InputStream; this allows you to easily extract Exif information directly out of content:// URIs you receive without having to create a temporary file.
content://
InputStream
Uri uri; // the URI you've received from the other app InputStream in; try { in = getContentResolver().openInputStream(uri); ExifInterface exifInterface = new ExifInterface(in); // Now you can extract any Exif tag you want // Assuming the image is a JPEG or supported raw format } catch (IOException e) { // Handle any errors } finally { if (in != null) { try { in.close(); } catch (IOException ignored) {} } }
Note: ExifInterface will not work with remote InputStreams, such as those returned from a HttpURLConnection. It is strongly recommended to only use them with content:// or file:// URIs.
HttpURLConnection
file://
For most attributes, you'd simply use the getAttributeInt(), getAttributeDouble(), or getAttribute() (for Strings) methods as appropriate.
getAttributeInt()
getAttributeDouble()
getAttribute()
One of the most important attributes when it comes to displaying images is the image orientation, stored in the aptly-named TAG_ORIENTATION, which returns one of the ORIENTATION_ constants. To convert this to a rotation angle, you can post-process the value.
TAG_ORIENTATION
ORIENTATION_
int rotation = 0; int orientation = exifInterface.getAttributeInt( ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); switch (orientation) { case ExifInterface.ORIENTATION_ROTATE_90: rotation = 90; break; case ExifInterface.ORIENTATION_ROTATE_180: rotation = 180; break; case ExifInterface.ORIENTATION_ROTATE_270: rotation = 270; break; }
There are some helper methods to extract values from specific Exif tags. For location data, the getLatLong() method gives you the latitude and longitude as floats and getAltitude() will give you the altitude in meters. Some images also embed a small thumbnail. You can check for its existence with hasThumbnail() and then extract the byte[] representation of the thumbnail with getThumbnail() - perfect to pass to BitmapFactory.decodeByteArray().
getLatLong()
getAltitude()
hasThumbnail()
byte[]
getThumbnail()
BitmapFactory.decodeByteArray()
One thing that is important to understand with Exif data is that there are no required tags: each and every tag is optional - some services even specifically strip Exif data. Therefore throughout your code, you should always handle cases where there is no Exif data, either due to no data for a specific attribute or an image format that doesn't support Exif data at all (say, the ubiquitous PNGs or WebP images).
Add the ExifInterface Support Library to your project with the following dependency:
compile "com.android.support:exifinterface:25.1.0"
But when an Exif attribute is exactly what you need to prevent a mis-rotated image in your app, the ExifInterface Support Library is just what you need to #BuildBetterApps
Posted by Jason Douglas, PM Director for Actions on Google
The Google Assistant brings together all of the technology and smarts we've been building for years, from the Knowledge Graph to Natural Language Processing. To be a truly successful Assistant, it should be able to connect users across the apps and services in their lives. This makes enabling an ecosystem where developers can bring diverse and unique services to users through the Google Assistant really important.
In October, we previewed Actions on Google, the developer platform for the Google Assistant. Actions on Google further enhances the Assistant user experience by enabling you to bring your services to the Assistant. Starting today, you can build Conversation Actions for Google Home and request to become an early access partner for upcoming platform features.
Conversation Actions for Google Home
Conversation Actions let you engage your users to deliver information, services, and assistance. And the best part? It really is a conversation -- users won't need to enable a skill or install an app, they can just ask to talk to your action. For now, we've provided two developer samples of what's possible, just say "Ok Google, talk to Number Genie " or try "Ok Google, talk to Eliza' for the classic 1960s AI exercise.
You can get started today by visiting the Actions on Google website for developers. To help create a smooth, straightforward development experience, we worked with a number of development partners, including conversational interaction development tools API.AI and Gupshup, analytics tools DashBot and VoiceLabs and consulting companies such as Assist, Notify.IO, Witlingo and Spoken Layer. We also created a collection of samples and voice user interface (VUI) resources or you can check out the integrations from our early access partners as they roll out over the coming weeks.
Coming soon: Actions for Pixel and Allo + Support for Purchases and Bookings
Today is just the start, and we're excited to see what you build for the Google Assistant. We'll continue to add more platform capabilities over time, including the ability to make your integrations available across the various Assistant surfaces like Pixel phones and Google Allo. We'll also enable support for purchases and bookings as well as deeper Assistant integrations across verticals. Developers who are interested in creating actions using these upcoming features should register for our early access partner program and help shape the future of the platform.
Posted by Clayton Wilkinson, Developer Platform Engineer
Some changes are coming to Play Game Services in early 2017:
In November, we announced an update to Google Sign-In API. Play Game Services is being updated to use Google Sign-In API for authentication. The advantages are:
This change unifies the Google Sign-in and the Games API Sign-in, so there are updates to how to build the Google API Client:
// Defaults to Games Lite scope, no server component GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN).build(); // OR for apps with a server component GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN) .requestServerAuthCode(SERVER_CLIENT_ID) .build(); // OR for developers who need real user Identity GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN) .requestEmail() .build(); // Build the api client. mApiClient = new GoogleApiClient.Builder(this) .addApi(Games.API) .addApi(Auth.GOOGLE_SIGN_IN_API, gso) .addConnectionCallbacks(this) .build(); } @Override public void onConnected(Bundle connectionHint) { if (mApiClient.hasConnectedApi(Games.API)) { Auth.GoogleSignInApi.silentSignIn(mApiClient).setResultCallback( new ResultCallback() { @Override public void onResult(GoogleSignInResult googleSignInResult) { // In this case, we are sure the result is a success. GoogleSignInAccount acct = googleSignInResult.getGoogleSignInAccount()); // For Games with a server, send the auth code to your server. String serverAuthCode = signInAccount.getServerAuthCode(); // Use the API client as normal. Player player = Games.API.getCurrentPlayer(mApiClient); } } ); } else { onSignedOut(); } }
List of APIs that are deprecated by removing Google+ integration (and their C++ equivalents):
We realize this is a large change, but moving forward Play Game Services are much better aligned with the rest of the Mobile platform from Google and will lead to better developer experience for Android game developers.
Today at Google Developer Day China, we are happy to announce a developer preview of Android Wear 2.0 for developers creating apps for China. Android Wear 2.0 is the biggest update since our partners launched their first devices in China last year.
We're making a Developer Preview available today and plan to release additional updates in the coming months. Please send us your feedback by filing bugs or posting in our Android Wear Developers community.
With Android Wear 2.0, apps can access the internet directly on Android Wear devices. As a result, for the majority of apps, having a companion phone application is no longer necessary. This means that most developers creating apps for Android Wear 2.0 may no longer need to import the Google Play services library.
There are two situations where developers will need to import Google Play services for China:
You can find more details about how to import the China compatible version of Google Play services library here.
The Android Wear 2.0 Developer Preview includes an updated SDK with tools, and system images for testing using the Huawei Watch.
To get started, follow these steps:
We will update this developer preview over the next few months based on your feedback. The sooner we hear from you, the more we can include in the final release, so don't be shy!
编辑: 林海泉, Android Wear 开发平台负责人
今天在上海举办的Google 开发者大会上,我们正式宣布了一款专门针对中国市场的Android Wear 2.0 开发者预览版。Android Wear 2.0系统,将是自我们的合作伙伴首次发布手表产品以来最重大的更新。
开发者预览版已于今日正式上线。与此同时,我们也计划在未来的几个月内持续进行更新。请您将您遇到的问题在此提交反馈,或者在我们的Android Wear开发者论坛发表意见。
在Android Wear 2.0系统中,应用可以由Android Wear手表直接连接至互联网。因此,对于大多数应用来说,手机端的伴侣应用也就变得不再必要。这也意味着,多数为Android Wear 2.0开发应用的开发者将不再需要引用Google Play services客户端库。
目前,在两个情况下开发者仍然需要引入Google Play Services客户端库来为中国市场开发应用:
您可以在这里找到关于如何引入与中国版兼容的Google Play service的更多信息。
Android Wear 2.0 开发者预览版包括最新的SDK套件,手表测试系统镜像(基于华为手表)。
情按照以下步骤进行测试:
我们会根据您的反馈在未来的几个月中更新开发者预览版。您给我们的反馈越早,我们将会在最终的发布版本中包含更多针对您的反馈的解决方案。敬请期待!
A key part of Android Wear 2.0 is letting watch apps work as standalone apps, so users can respond to messages, track their fitness, and use their favorite apps, even when their phone isn't around. Developer Preview 4 includes a number of new APIs that will help you build more powerful standalone apps.
To make authentication a seamless experience for both Android phone and iPhone users, we have created new APIs for OAuth and added support for one-click Google Sign-in. With the OAuth API for Android Wear, users can tap a button on the watch that opens an authentication screen on the phone. Your watch app can then authenticate with your server side APIs directly. With Google Sign-In, it's even easier. All the user needs to do is select which account they want to authenticate with and they are done.
In addition to paid apps, we have added in-app billing support, to give you another way to monetize your Android Wear app or watch face. Users can authorize purchases quickly and easily on the watch through a 4-digit Google Account PIN. Whether it's new levels in a game or new styles on a watch face, if you can build it, users can buy it.
What if your watch app doesn't work standalone? Or what if it offers a better user experience when both the watch and phone apps are installed? We've been listening carefully to your feedback, and we've added two new APIs (PlayStoreAvailability and RemoteIntent) to help you navigate users to the Play Store on a paired device so they can more easily install your app. Developers can also open custom URLs on the phone from the watch via the new RemoteIntent API; no phone app or data layer is required.
PlayStoreAvailability
RemoteIntent
// Check Play Store is available int playStoreAvailabilityOnPhone = PlayStoreAvailability.getPlayStoreAvailabilityOnPhone(getApplicationContext()); if (playStoreAvailabilityOnPhone == PlayStoreAvailability.PLAY_STORE_ON_PHONE_AVAILABLE) { // To launch a web URL, setData to Uri.parse("https://g.co/wearpreview") Intent intent = new Intent(Intent.ACTION_VIEW) .addCategory(Intent.CATEGORY_BROWSABLE) .setData(Uri.parse("market://details?id=com.google.android.wearable.app")); // mResultReceiver is optional; it can be null. RemoteIntent.startRemoteActivity(this, intent, mResultReceiver); }
Many of you have given us the feedback that the swipe-to-dismiss gesture from Android Wear 1.0 is an intuitive time-saver. We agree, and have reverted back to the previous behavior with this developer preview release. To support swipe-to-dismiss in this release, we've made the following platform and API changes:
SwipeDismissFrameLayout
Additional details are available under the behavior changes section of the Android Wear Preview site.
Android Wear apps packaged using the legacy embedded app mechanism can now be delivered to Android Wear 2.0 watches. When a user installs a phone app that also contains an embedded Android Wear app, the user will be prompted to install the embedded app via a notification. If they choose not to install the embedded app at that moment, they can find it in the Play Store on Android Wear under a special section called "Apps you've used".
Despite support for the existing mechanism, there are significant benefits for apps that transition to the multi-APK delivery mechanism. Multi-APK allows the app to be searchable in the Play Store on Android Wear, to be eligible for merchandising on the homepage, and to be remotely installed from the web to the watch. As a result, we strongly recommend that developers move to multi-APK.
setShouldPeekOnScrollDown
Thanks for all your terrific feedback on Android Wear 2.0. Check out g.co/wearpreview for the latest builds and documentation, keep the feedback coming by filing bugs or posting in our Android Wear Developers community, and stay tuned for Android Wear Developer Preview 5!
Posted by Wayne Piekarski, Developer Advocate for IoT
The Internet of Things (IoT) will bring computing to a whole new range of devices. Today we're announcing two important updates to our IoT developer platform to make it faster and easier for you to create these smart, connected products.
We're releasing a Developer Preview of Android Things, a comprehensive way to build IoT products with the power of Android, one of the world's most supported operating systems. Now any Android developer can quickly build a smart device using Android APIs and Google services, while staying highly secure with updates direct from Google. We incorporated the feedback from Project Brillo to include familiar tools such as Android Studio, the Android Software Development Kit (SDK), Google Play Services, and Google Cloud Platform. And in the coming months, we will provide Developer Preview updates to bring you the infrastructure for securely pushing regular OS patches, security fixes, and your own updates, as well as built-in Weave connectivity and more.
There are several turnkey hardware solutions available for you to get started building real products with Android Things today, including Intel Edison, NXP Pico, and Raspberry Pi 3. You can easily scale to large production runs with custom designs of these solutions, while continuing to use the same Board Support Package (BSP) from Google.
We are also updating the Weave platform to make it easier for all types of devices to connect to the cloud and interact with services like the Google Assistant. Device makers like Philips Hue and Samsung SmartThings already use Weave, and several others like Belkin WeMo, LiFX, Honeywell, Wink, TP-Link, and First Alert are implementing it. Weave provides all the cloud infrastructure, so that developers can focus on building their products without investing in cloud services. Weave also includes a Device SDK for supported microcontrollers and a management console. The Weave Device SDK currently supports schemas for light bulbs, smart plugs and switches, and thermostats. In the coming months we will be adding support for additional device types, custom schemas/traits, and a mobile application API for Android and iOS. Finally, we're also working towards merging Weave and Nest Weave to enable all classes of devices to connect with each other in a secure and reliable way. So whether you started with Google Weave or Nest Weave, there is a path forward in the ecosystem. This is just the beginning of the IoT ecosystem we want to build with you. To get started, check out Google's IoT developer site, or go directly to the Android Things, Weave, and Google Cloud Platform sites for documentation and code samples. You can also join Google's IoT Developers Community on Google+ to get the latest updates and share and discuss ideas with other developers.