Android Pay has been a hot topic in the last weeks after a series of memos and promotional materials turned up with the supposed August 26th launch date. As it turns out, Google hadn't yet distributed the necessary software to enable Android Pay for use on phones. That changes with version 8.1 of the Play services apk, which began rolling out Friday afternoon. A look around inside of the app also suggests there has been a bit more progress on the long-anticipated Kid Accounts. As of this release, there is also an important change to the convention Google uses for identifying Play services apk variants for different devices.
Changes To The Naming Scheme For Variants
If you're into sideloading Google's apps ahead of their natural rollout to your devices, this is going to be important to you. Each version of the Play Services apk is distributed in many different variants, each intended for devices with a specific set of characteristics.
Starting with v8.1, variants beginning with a '4' are now intended to run exclusively on Android 6.0 Marshmallow. If you want the Lollipop variant, look for a '2' in the X position.
The naming convention for these versions is formatted as -XYZ, where X represents the version of Android it is supposed to run on, Y denotes the CPU architecture, and Z is for the different screen densities. As many people know, if there is a '0' in the X position, that variant is meant for devices running KitKat or below; and if there was a '4' or '7,' it tells us the apk belongs on devices running Lollipop. Forget that.
It seems that starting with v8.1, variants beginning with a '4' are now intended to run exclusively on Android 6.0 Marshmallow. If you're looking for the Lollipop variant, you should now look for a '2' in the X position.
The first few variants to roll out have been -238, -236, and -438. Both of the apks marked with '2' require SDK 21 or above (Android 5.0 and 5.1) to install while the -438 apk requires SDK 23 (Android 6.0). Attempts to install the -438 apk will fail on any version of Android below Android M Developer Preview 3. If anybody installs -238 on Android 6.0, it may lead to inefficient or unpredictable behavior, but since the version number is higher, it can be easily upgraded to -438.
If you're ever uncertain of which version to download, always check APK Mirror for an explanation of which versions are right for your devices.
Teardown
Disclaimer: Teardowns are necessarily speculative and usually based on incomplete evidence. It's possible that the guesses made here are totally and completely wrong. There is always a chance that details may change or plans may be cancelled prior to the launch of a new feature discovered in a teardown. Much like rumors, nothing is certain until it's officially announced.
Android Pay
We've known it was coming, and now it's finally here... sorta. Android Pay functionality is now baked into Google Play services, but the server-side service hasn't actually been activated for regular consumers yet, so it's not really usable. However, it's actually possible to launch many of the activities and experience bits and pieces of the interface today.
We can begin with the animation Google uses for the "warm welcome" that occurs when users would first enter the Android Pay setup.
The process guides users to install the Google Wallet app from the Play Store, assuming it's not already installed. Once installed, the process continues with setting up credit cards, security settings, and a couple of other details. Since users can't actually use Android Pay yet, the setup process will fail before a card can be set up as the default payment method on an account.
Since security is also a major concern, Android Pay will also force users to enable their lockscreen using one of the more secure methods, like a pattern, password, or PIN code. Android Pay also runs as a Device Administrator so it can keep tabs on when the lockscreen has become active.
And naturally, Android Pay appears in the Tap & Pay screen and in the Device Administrator list.
If anybody would like to check out these screens on their own device, I'm including commands to run the two most interesting activities. There are others that can be run, but they don't result in any particularly interesting screens. To use them, simply connect your phone to a computer with ADB and any necessary device drivers, then run these commands:
adb shell am start -n com.google.android.gms/com.google.android.gms.tapandpay.settings.TapAndPaySettingsActivity
adb shell am start -n com.google.android.gms/com.google.android.gms.tapandpay.ui.WarmWelcomeActivity
As far as teardown materials go, most of the strings were added shortly after Android Pay was announced at Google I/O 2015. Actually, most of them were added long before that with the integration of Google Wallet, but after the announcement somebody at Google did a quick search-and-replace to get them renamed. If you're looking for something to poke around in, there are a bunch of new activities and services to check out.
Evidence
<permission android:name="com.google.android.gms.permission.SHOW_TRANSACTION_RECEIPT" android:protectionLevel="signature"/>
<uses-permission android:name="com.google.android.gms.permission.SHOW_TRANSACTION_RECEIPT"/>
<permission android:name="com.google.android.gms.permission.READ_VALUABLES_IMAGES" android:protectionLevel="signature"/>
<uses-permission android:name="com.google.android.gms.permission.READ_VALUABLES_IMAGES"/>
<permission android:name="com.google.android.gms.permission.SHOW_WARM_WELCOME_TAPANDPAY_APP" android:protectionLevel="signature"/>
<uses-permission android:name="com.google.android.gms.permission.SHOW_WARM_WELCOME_TAPANDPAY_APP"/>
<string name="android_pay">Android Pay</string>
<string name="wallet_fab_first_time_toast">"Faster checkout available!
Tap for details"</string>
<service android:exported="false" android:name="com.google.android.gms.wallet.service.orchestration.BuyFlowInitializationService">
<action android:name="com.google.android.gms.wallet.buyflow.ACTION_INITIALIZE_BUYFLOW"/>
<activity android:configChanges="keyboardHidden|orientation|screenSize" android:excludeFromRecents="true" android:exported="false" android:label="@string/auth_authzen_workflow_title" android:name="com.google.android.gms.auth.authzen.transaction.workflows.SimpleNotificationWorkflow" android:process="com.google.android.gms.ui" android:theme="@style/Theme.AppCompat.Light"/>
<service android:exported="true" android:name="com.google.android.gms.tapandpay.service.TapAndPayService" android:process="com.google.process.gapps">
<action android:name="com.google.android.gms.tapandpay.service.BIND"/>
<service android:exported="false" android:name="com.google.android.gms.tapandpay.service.TapAndPayIntentService" android:process="com.google.process.gapps"/>
<activity android:exported="false" android:icon="@drawable/tp_logo_android_pay_color_48dp" android:label="@string/tp_payments_application_name" android:name="com.google.android.gms.tapandpay.transaction.WalletTransactionDetailsActivity" android:process="com.google.android.gms.ui" android:theme="@android:style/Theme.Translucent">
<action android:name="com.google.android.gms.tapandpay.transaction.WALLET_TRANSACTION_DETAILS_ACTIVITY"/>
<category android:name="android.intent.category.DEFAULT"/>
<service android:exported="false" android:name="com.google.android.gms.tapandpay.notifications.TapAndPayNotificationService" android:process="com.google.process.gapps"/>
<receiver android:exported="false" android:name="com.google.android.gms.tapandpay.notifications.GcmBroadcastReceiver" android:process="com.google.process.gapps"/>
<activity android:exported="true" android:icon="@drawable/tp_logo_android_pay_color_48dp" android:label="@string/tp_payments_application_name" android:launchMode="singleTask" android:name="com.google.android.gms.tapandpay.settings.TapAndPaySettingsActivity" android:parentActivityName="com.google.android.gms.app.settings.GoogleSettingsLink" android:process="com.google.android.gms.ui" android:taskAffinity="com.google.android.gms.common.settings" android:theme="@style/common.Theme.GoogleSettings">
<action android:name="com.google.android.gms.wallet.settings.GOOGLE_WALLET_SETTINGS"/>
<category android:name="android.intent.category.DEFAULT"/>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:host="tapandpay" android:pathPattern="/settings" android:scheme="comgoogleandroidgms"/>
<activity android:exported="false" android:icon="@drawable/tp_logo_android_pay_color_48dp" android:label="@string/tp_payments_application_name" android:name="com.google.android.gms.tapandpay.settings.SelectUntokenizedCardActivity" android:parentActivityName="com.google.android.gms.tapandpay.tokenization.TokenizePanActivity" android:process="com.google.android.gms.ui" android:theme="@style/common.Theme.GoogleSettings"/>
<activity android:exported="false" android:icon="@drawable/tp_logo_android_pay_color_48dp" android:label="@string/tp_payments_application_name" android:name="com.google.android.gms.tapandpay.settings.NotificationSettingsActivity" android:process="com.google.android.gms.ui" android:theme="@style/common.Theme.GoogleSettings"/>
<activity android:exported="false" android:icon="@drawable/tp_logo_android_pay_color_48dp" android:label="@string/tp_payments_application_name" android:name="com.google.android.gms.tapandpay.pin.ChangeOrSetPinActivity" android:process="com.google.android.gms.ui" android:theme="@style/TpPinTheme">
<action android:name="com.google.android.gms.tapandpay.CREATE_PIN"/>
<action android:name="com.google.android.gms.tapandpay.EDIT_PIN"/>
<category android:name="android.intent.category.DEFAULT"/>
<activity android:exported="false" android:icon="@drawable/tp_logo_android_pay_color_48dp" android:label="@string/tp_payments_application_name" android:name="com.google.android.gms.tapandpay.tokenization.TokenizePanActivity" android:process="com.google.android.gms.ui" android:theme="@style/Theme.AppCompat.Light.NoActionBar">
<action android:name="com.google.android.gms.tapandpay.ACTION_TOKENIZE_PAN"/>
<category android:name="android.intent.category.DEFAULT"/>
<activity android:icon="@drawable/tp_logo_android_pay_color_48dp" android:label="@string/tp_payments_application_name" android:name="com.google.android.gms.tapandpay.tokenization.AddNewCardForTokenizationActivity" android:process="com.google.android.gms.ui" android:theme="@android:style/Theme.Translucent.NoTitleBar"/>
<activity android:exported="false" android:icon="@drawable/tp_logo_android_pay_color_48dp" android:label="@string/tp_payments_application_name" android:name="com.google.android.gms.tapandpay.tokenization.UnsupportedCardActivity" android:parentActivityName="com.google.android.gms.tapandpay.tokenization.TokenizePanActivity" android:process="com.google.android.gms.ui" android:theme="@style/common.Theme.GoogleSettings"/>
<activity android:configChanges="orientation" android:exported="false" android:icon="@drawable/tp_logo_android_pay_color_48dp" android:label="@string/tp_payments_application_name" android:name="com.google.android.gms.tapandpay.tokenization.SelectVerificationMethodActivity" android:process="com.google.android.gms.ui" android:theme="@style/common.Theme.GoogleSettings"/>
<activity android:configChanges="orientation" android:exported="false" android:icon="@drawable/tp_logo_android_pay_color_48dp" android:label="@string/tp_payments_application_name" android:name="com.google.android.gms.tapandpay.tokenization.EnterVerificationCodeActivity" android:process="com.google.android.gms.ui" android:theme="@style/common.Theme.GoogleSettings" android:windowSoftInputMode="adjustResize"/>
<activity android:exported="false" android:icon="@drawable/tp_logo_android_pay_color_48dp" android:label="@string/tp_payments_application_name" android:name="com.google.android.gms.tapandpay.admin.DeviceAdminPromptActivity" android:process="com.google.android.gms.ui" android:theme="@style/common.Theme.GoogleSettings"/>
<activity android:exported="false" android:icon="@drawable/tp_logo_android_pay_color_48dp" android:label="@string/tp_payments_application_name" android:name="com.google.android.gms.tapandpay.ui.ShowSecurityPromptActivity" android:process="com.google.android.gms.ui" android:theme="@style/Theme.AppCompat.Light.Dialog">
<action android:name="com.google.android.gms.tapandpay.ACTION_SHOW_SECURITY_PROMPT"/>
<category android:name="android.intent.category.DEFAULT"/>
<receiver android:exported="false" android:name="com.google.android.gms.tapandpay.receiver.SelfDestructReceiver" android:process="com.google.process.gapps">
<action android:name="com.google.android.gms.tapandpay.SELF_DESTRUCT"/>
<activity android:exported="false" android:icon="@drawable/tp_logo_android_pay_color_48dp" android:label="@string/tp_payments_application_name" android:name="com.google.android.gms.tapandpay.ui.WarmWelcomeActivity" android:process="com.google.android.gms.ui" android:theme="@style/Theme.AppCompat.NoActionBar">
<action android:name="com.google.android.gms.tapandpay.ACTION_WARM_WELCOME"/>
<category android:name="android.intent.category.DEFAULT"/>
<activity android:exported="false" android:icon="@drawable/tp_logo_android_pay_color_48dp" android:label="@string/tp_payments_application_name" android:name="com.google.android.gms.tapandpay.ui.EnableSecureKeyguardActivity" android:process="com.google.android.gms.ui" android:theme="@android:style/Theme.Translucent.NoTitleBar">
<action android:name="com.google.android.gms.tapandpay.ACTION_ENABLE_SECURE_KEYGUARD"/>
<category android:name="android.intent.category.DEFAULT"/>
<activity android:exported="false" android:icon="@drawable/tp_logo_android_pay_color_48dp" android:label="@string/tp_payments_application_name" android:name="com.google.android.gms.tapandpay.ui.SecureDeviceActivity" android:process="com.google.android.gms.ui" android:theme="@style/Theme.AppCompat.NoActionBar"/>
<activity android:excludeFromRecents="true" android:exported="false" android:icon="@drawable/tp_logo_android_pay_color_48dp" android:label="@string/tp_payments_application_name" android:name="com.google.android.gms.tapandpay.tap.TapActivity" android:process="com.google.android.gms.ui" android:theme="@android:style/Theme.Translucent.NoTitleBar"/>
<activity android:excludeFromRecents="true" android:exported="false" android:name="com.google.android.gms.tapandpay.tap.TapKeyguardActivity" android:process="com.google.android.gms.ui"/>
<activity android:exported="false" android:icon="@drawable/tp_logo_android_pay_color_48dp" android:label="@string/tp_payments_application_name" android:name="com.google.android.gms.tapandpay.tokenization.AcceptTosActivity" android:process="com.google.android.gms.ui" android:theme="@style/common.Theme.GoogleSettings"/>
<activity android:excludeFromRecents="true" android:exported="false" android:icon="@drawable/tp_logo_android_pay_color_48dp" android:label="@string/tp_payments_application_name" android:launchMode="singleTask" android:name="com.google.android.gms.tapandpay.ui.PromptSetupActivity" android:process="com.google.android.gms.ui" android:theme="@style/TpPromptSetup"/>
<receiver android:description="@string/tp_device_admin_desc" android:enabled="false" android:icon="@drawable/tp_deviceadmin_android_pay_color_40dp" android:label="@string/tp_payments_application_name" android:name="com.google.android.gms.tapandpay.admin.TpDeviceAdminReceiver" android:permission="android.permission.BIND_DEVICE_ADMIN" android:process="com.google.process.gapps">
<meta-data android:name="android.app.device_admin" android:resource="@xml/tp_device_admin"/>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED"/>
<action android:name="android.app.action.DEVICE_ADMIN_DISABLED"/>
<action android:name="android.app.action.ACTION_PASSWORD_CHANGED"/>
<receiver android:name="com.google.android.gms.tapandpay.keyguard.KeyguardDismissedReceiver" android:process="com.google.process.gapps">
<action android:name="android.intent.action.USER_PRESENT"/>
<service android:exported="false" android:name="com.google.android.gms.tapandpay.tokenization.TokenizePanService" android:process="com.google.process.gapps"/>
<service android:exported="false" android:name="com.google.android.gms.tapandpay.selfdestruct.SelfDestructService" android:process="com.google.process.gapps"/>
<service android:exported="false" android:name="com.google.android.gms.tapandpay.notifications.TapAndPayGcmRegistrationService" android:process="com.google.process.gapps">
<action android:name="com.google.android.gms.gcm.ACTION_TASK_READY"/>
<service android:exported="false" android:name="com.google.android.gms.tapandpay.paymentbundle.PaymentBundleService" android:process="com.google.process.gapps"/>
<service android:exported="false" android:name="com.google.android.gms.tapandpay.paymentbundle.PaymentBundleRefreshService" android:process="com.google.process.gapps">
<action android:name="com.google.android.gms.gcm.ACTION_TASK_READY"/>
<service android:exported="true" android:label="@string/tp_payments_application_name" android:name="com.google.android.gms.tapandpay.hce.service.TpHceService" android:permission="android.permission.BIND_NFC_SERVICE" android:process="com.google.process.gapps">
<action android:name="android.nfc.cardemulation.action.HOST_APDU_SERVICE"/>
<category android:name="android.intent.category.DEFAULT"/>
<meta-data android:name="android.nfc.cardemulation.host_apdu_service" android:resource="@xml/hce_aids"/>
<service android:exported="false" android:name="com.google.android.gms.tapandpay.security.CheckInService" android:process="com.google.process.gapps">
<action android:name="com.google.android.gms.gcm.ACTION_TASK_READY"/>
<service android:exported="false" android:name="com.google.android.gms.tapandpay.security.FetchStorageKeyTaskService" android:process="com.google.process.gapps">
<action android:name="com.google.android.gms.gcm.ACTION_TASK_READY"/>
<service android:exported="false" android:name="com.google.android.gms.tapandpay.keyguard.KeyguardDismissedService" android:process="com.google.process.gapps"/>
<service android:exported="false" android:name="com.google.android.gms.tapandpay.security.StorageKeyCacheService" android:process="com.google.process.gapps"/>
<service android:exported="false" android:name="com.google.android.gms.tapandpay.security.FetchStorageKeyService" android:process="com.google.process.gapps"/>
<service android:exported="false" android:name="com.google.android.gms.tapandpay.tap.TapEventService" android:process="com.google.process.gapps"/>
<service android:exported="false" android:name="com.google.android.gms.tapandpay.tap.TapLocationReportingService" android:process="com.google.process.gapps"/>
<service android:exported="false" android:name="com.google.android.gms.tapandpay.serverlog.LogMessageService" android:process="com.google.process.gapps"/>
<service android:exported="false" android:name="com.google.android.gms.tapandpay.serverlog.LogMessageUploadService" android:process="com.google.process.gapps">
<action android:name="com.google.android.gms.gcm.ACTION_TASK_READY"/>
<receiver android:name="com.google.android.gms.tapandpay.paymentbundle.GmsInitializationCompletedReceiver" android:process="com.google.process.gapps">
<action android:name="com.google.android.gms.INITIALIZE"/>
<receiver android:name="com.google.android.gms.tapandpay.paymentbundle.ChargerConnectedReceiver" android:process="com.google.process.gapps">
<action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
<service android:exported="false" android:name="com.google.android.gms.tapandpay.cardart.CardArtService" android:process="com.google.process.gapps"/>
<receiver android:name="com.google.android.gms.tapandpay.account.AccountsChangedReceiver" android:process="com.google.process.gapps">
<action android:name="android.accounts.LOGIN_ACCOUNTS_CHANGED"/>
<service android:exported="false" android:name="com.google.android.gms.tapandpay.account.AccountsChangedService" android:process="com.google.process.gapps"/>
<receiver android:enabled="false" android:exported="false" android:name="com.google.android.gms.tapandpay.config.UpgradeNfcWalletReceiver" android:process="com.google.process.gapps">
<action android:name="com.google.android.gms.tapandpay.UPGRADE_NFC_WALLET"/>
It's a safe bet that Android Pay won't actually launch to the public until Play services v8.1 goes into a wide rollout to every user. If history is any indicator, that means it probably won't happen for at least another week, but it will probably take a bit longer.
Kid Accounts
Kid Accounts are starting to feel a little like Android@Home. After appearing in five teardowns (1, 2, 3, 4, 5) in the last 9 months, Google hasn't said a single word about Kid Accounts, even at a playground-themed Google I/O where developers were clubbed over the head with promotion for educational and family-oriented content.
The latest update brings a bit more in the way of some fairly verbose strings. They mostly repeat information we already knew, that parents can get the physical location of the device through location services. There's also a long-ish explanation about the data Google would receive if usage reporting is enabled. Some strings have also been added for the interface where parents can "create" a family.
strings
<string name="kids_family_creation">Family Creation</string>
<string name="kids_ga_action_create_account">CreateAccount</string>
<string name="kids_ga_category_creation">Creation</string>
<string name="kids_ga_screen_account_creation_view">Account Creation View Screen</string>
<string name="auth_kids_setup_wizard_services_usage_reporting_dialog_text">
"When you turn on usage and diagnostics, it sends information to Google about whats working and whats not working on your child's device. For example:
• How often apps are used
• Quality and duration of network connections (like cell, Wi‑Fi, and Bluetooth)
None of this information is used to identify your child. It's used to improve Google's products and services for everyone.
You can turn usage and diagnostics off at any time in your childs Google Settings app. It won't affect this devices ability to receive essential services, like system updates and security."</string>
<string name="auth_kids_setup_wizard_services_location_sharing"><b>Let Google’s location service help apps</b>" find your child's location quickly and accurately, which can reduce battery consumption. Anonymous location data will be sent to Google, even when no apps are running. "<annotation id="location_details">Learn more</annotation></string>
<string name="auth_kids_setup_wizard_services_location_sharing_dialog_text">"When Google's location services are turned on, this device uses Wi‑Fi and cellular networks to provide location information. This helps Google's location service estimate location faster and more accurately.
If you don't want to use Wi-Fi or cellular data, you can choose a mode that uses GPS only, sometimes called Device only mode."</string>
<string name="auth_kids_setup_wizard_services_backup_dialog_text">"When you turn on automatic backup, this device's data is periodically saved to your child's Google Account. Backups may include information in your child's app data folders, like preferences, settings, messages, photos, and other files."</string>
P.S. Somebody, please correct every instance of "whats" in the strings above to include apostrophes. My OCD is going crazy over this.
There's nothing exceptional about the new strings, but they do show that the interface elements for Kid Accounts have to be getting close to finished. There's no way to be sure about how much is left, but everything certainly looks close to finished.
Download
The APK is signed by Google and upgrades your existing app. The cryptographic signature guarantees that the file is safe to install and was not tampered with in any way. Rather than wait for Google to push this download to your devices, which can take days, download and install it just like any other APK.
File Name: com.google.android.gms-8.1.02_(2204618-238)-8102238-minAPI21.apk
Version: 8.1.02 (2204618-238) (8102238)