diff --git a/docs/html/wear/preview/features/app-distribution.jd b/docs/html/wear/preview/features/app-distribution.jd new file mode 100644 index 0000000000000..319efa6b65545 --- /dev/null +++ b/docs/html/wear/preview/features/app-distribution.jd @@ -0,0 +1,325 @@ +page.title=App Distribution +meta.keywords="wear-preview" +page.tags="wear-preview" +page.image=images/cards/card-n-sdk_2x.png +@jd:body + +
+
+ +

In this document

+ + + +
+
+ +

+ With Android Wear 2.0, a user can visit the Play Store on a watch and + download a Wear app directly to the watch. +

+ +

+ Generally, a Wear 2.0 app in the Play Store needs + a minimum and target API level of 24 or higher in + the Android manifest file. The minimum SDK level can be 23 + only if you are using the same APK + for Wear 1.0 and 2.0 (and thus have an embedded Wear 1.0 APK). +

+ +

+ Publish Your APKs +

+ +

+ To make your app appear in the on-watch Play Store, upload + the watch APK in the Play Developer Console just as you would any other + APK. If you only have a watch APK and no phone APK, no other steps + are required. +

+ +

+ If you have a phone APK in addition to a watch APK, you must use the + Multi-APK delivery method. +

+ +

+ Run-time + permissions are required. +

+ +

+ Also see + + Standalone Apps. +

+ +

+ Distribution to Wear 2.0 watches +

+ +

+ If you only want your app to be distributed to Wear 2.0 watches, + it is unnecessary to embed the watch APK inside the the phone APK. +

+ +

+ If you want your app to + be distributed to Wear 1.0 watches, you need to embed the + watch APK inside the phone APK, as described directly below. +

+ +

+ Distribution to Wear 1.0 and 2.0 watches +

+ +

+ If you are already distributing your app to Wear 1.0 watches, + follow these steps: +

+ +
    +
  1. Provide a Wear 2.0 (standalone) version of your watch APK that can be made + available in the Play Store on Wear. +
  2. + +
  3. Continue embedding a Wear 1.0 APK in your phone APK, + for use by watches that do not have Wear 2.0. +
  4. +
+ +

+ Specifying a version code +

+ +

+ To ensure that a standalone APK acts as an upgrade to an embedded Wear APK, the + standalone Wear APK's + version code generally should be higher than the embedded Wear APK's version code. + (A phone APK's version code scheme can be independent from that of a watch + APK, although they must be unique.) However, the version codes + of the standalone APK and the embedded Wear APK can be the same if + the APKs are equivalent. If the APKs are not equivalent, + but the version code is the same, then when a watch updates from Wear 1.0 + to 2.0, the watch may get the new APK only after waiting for a + longer-than-expected period of time. +

+ +

+ Note that it currently is not possible to create a single APK that works + on a phone and watch. +

+ +

+ Support in the Gradle file +

+ +

+ If you have a Wear app that is intended for both Wear 1.0 and Wear 2.0, + consider using + product flavors. For example, + if you want to target both SDK version 23 and version 24, + update your Wear module's build.gradle file to include + the following if an existing embedded app has a minimum SDK version of 23: +

+ +
+android {
+    ...
+    defaultConfig
+    {
+       // This is the minSdkVersion of the Wear 1.0 embedded app
+       minSdkVersion 23
+       ...
+    }
+    buildTypes {...}
+    productFlavors {
+        wear1 {
+          // Use the defaultConfig value
+        }
+        wear2 {
+            minSdkVersion 24
+        }
+    }
+
+ +

+ Then update your phone module’s build.gradle file, replacing + wearApp as follows: +

+ +
+dependencies {
+    ...
+    wearApp project(path: ':wearable', configuration: 'wear1Release')
+}
+
+ +

+ A + build variant is a combination of the product flavor and build type. + In Android Studio, select the appropriate build variant when + debugging or publishing your app. For example, if wear2 is a + product flavor, select wear2Release as the + release build variant. +

+ +

+ For purposes of code that is Wear 2.0-specific or Wear 1.0-specific, + consider + source sets for build variants. +

+ + +

+ Setting Up Targeting for a Watch +

+ +

+ In your Android Manifest file, you must specify the following feature + restriction: the uses-feature element is set to + android.hardware.type.watch. Do not set + the required attribute to false. + A single APK for Wear and non-Wear devices presently is not supported. +

+ +

+ Thus, if an APK has the following setting, Google Play provides the APK + to watches only: +

+ +
+<manifest package="com.example.standalone"
+    xmlns:android="http://schemas.android.com/apk/res/android">
+    <uses-feature
+        android:name="android.hardware.type.watch"
+    ...
+</manifest>
+
+ +

+ The android.hardware.type.watch setting above can be + combined with other criteria such as SDK version, screen resolution, and + CPU architecture. Thus, different Wear APKs can target different hardware + configurations. +

+ +

+ Using the Play Developer Console +

+ +

+ Below is an introduction to uploading + a standalone Wear APK to an application listing using the Play Developer + Console. +

+ +

+ If your app supports both Wear 1.0 and Wear 2.0, continue embedding the + Wear 1.0 APK (minimum SDK version of 20, 21, or 22, or 23) in the phone + APK and upload the phone APK. In addition, upload your standalone Wear + 2.0 APK (which has a minimum SDK version of 24). +

+ +

+ Also see + Multiple APK Support and + Manage Your App. + Before uploading an APK as described below, the APK + must be + signed. +

+ +

+ Uploading your APK +

+ +

+ Go to the Play Developer + Console, navigate to your application listing, and select + APK in the left-navigation panel. An APK screen similar to + the following is displayed: +

+ alt_text + +

+ You may need to use advanced mode for uploads, as follows: +

+ + + +

+ Therefore, on the above APK screen, to determine whether to click + the Switch to advanced mode + button, consider the following: +

+ + + +

+ See + Simple mode and advanced mode for more information about toggling + between modes. +

+ +

+ Select the appropriate tab (Production, Beta + Testing, or Alpha Testing) for your upload. + Then click + the Upload New APK button and select your standalone + Wear APK for upload. +

+ +

+ Reviewing and publishing +

+ +

+ After you upload your standalone Wear APK and scroll down the resulting + page, the APK is shown in the Current APK table, with a + version number, in a similar way to the following: +

+ alt_text + +

+ Finally, in the Current APK table above, click the line + with the Version to review the APK. The APK + Details panel is displayed. You can verify, for example, that + the number in the Supported Android Devices line is far + fewer than the number would be for a typical phone APK: +

+ alt_text + +

+ When you are ready, publish + your app. +

diff --git a/docs/html/wear/preview/features/standalone-apps.jd b/docs/html/wear/preview/features/standalone-apps.jd new file mode 100644 index 0000000000000..5c1930dedf866 --- /dev/null +++ b/docs/html/wear/preview/features/standalone-apps.jd @@ -0,0 +1,499 @@ +page.title=Standalone Apps +meta.keywords="wear-preview" +page.tags="wear-preview" +page.image=images/cards/card-n-sdk_2x.png + +@jd:body + +
+
+ +

In this document

+ + + +
+
+ +

+ In Android Wear 2.0, apps can work independently of a phone. Users can + complete more tasks on a watch, without access to an Android or iOS + phone. +

+ +

+ Planning Your Phone and Watch Apps +

+ +

+ A watch APK targeting Wear 2.0 should not be embedded in a phone APK. + For more information, see + + App Distribution. +

+ +

+ Generally, the minimum and target API level for a standalone app, and + for Wear 2.0, is level 24. The minimum SDK level can be 23 + only if you are using the same APK + for Wear 1.0 and 2.0 (and thus have an embedded Wear 1.0 APK). +

+ +

+ If you build a standalone Wear 2.0 APK and will continue to have a + Wear 1.0 APK, please do both of the following: +

+ + + +

+ Caution: For the Wear 2.0 Developer Preview, if you + publish an update to your production phone APK that has removed an embedded + Wear APK, production users who update the phone APK before installing + your standalone Wear APK will lose their existing Wear app and its data. + Therefore, it's important that you continue to embed + your watch APK into your phone APK. +

+ +

+ + Run-time permissions are required for standalone apps. +

+ +

+ Shared code and data storage +

+ +

+ Code can be shared between a Wear app and a phone app. Optionally, code + that is specific to a form factor can be in a separate module. +

+ +

+ For example, common code for networking can be in a shared library. +

+ +

+ You can use standard Android storage APIs to store data locally. + For example, you can use + the + SharedPreferences APIs, SQLite, or internal storage (as you would in + the case of a phone). +

+ +

+ Detecting your phone app or watch app +

+ +

+ If a user of your watch app needs your phone app, your watch app can + detect if the phone app is available. Using the + CapabilityApi, your phone app or watch app can advertise its presence + to a paired device. It can do so statically and dynamically. When an app + is on a node in a user's Wear network (i.e., on a phone, paired watch, or + in the cloud), the CapabilityApi enables another + app to detect if it is installed. For more information, see + Advertise capabilities. +

+ +

+ If your phone app is unavailable, your can check if the Play Store is + available on the phone, as described below, before directing the user to + go to the Play Store (to install your phone app). +

+ +

+ Checking for Play Store availability on a phone +

+ +

+ iPhones and some Android phones lack the Play Store. A standalone Wear + app can check if the paired phone has the Play Store, before directing a + user to go there to install your phone app. The + PlayStoreAvailability class contains a + getPlayStoreAvailabilityOnPhone() method that enables your + Wear app to check if a companion phone has the Play Store. +

+ +

+ More information about the PlayStoreAvailability class is + available when you + download the Android Wear 2.0 Preview Reference. Here is a snippet + that uses the getPlayStoreAvailabilityOnPhone() method to + determine if the paired phone has the Play Store: +

+ +
+int playStoreAvailabilityOnPhone =
+PlayStoreAvailability.getPlayStoreAvailabilityOnPhone(context);
+
+ +

+ The value returned by the getPlayStoreAvailabilityOnPhone() + method is one of the following: +

+ + + + + + + + + + + + + + + + + + + + + +
+ Return value + + Description +
+ PLAY_STORE_ON_PHONE_AVAILABLE + + The Play Store is available on the companion phone. +
+ PLAY_STORE_ON_PHONE_UNAVAILABLE + + The Play Store is not available on the companion phone. +
+ PLAY_STORE_ON_PHONE_ERROR_UNKNOWN + + An error occurred in the check for the Play Store; another check + should be made later. +
+ +

+ Network Access and Cloud Messaging +

+ +

+ Android Wear apps can make their own network requests. When a watch has a + Bluetooth connection to a phone, the watch's network traffic is proxied + through the phone. When a phone is unavailable, Wi-Fi and cellular + networks are used, depending on the hardware. The Wear platform handles + transitions between networks. A watch's network access thus does not + require the + Wearable Data Layer API. +

+ +

+ For sending notifications, apps can directly use Firebase Cloud Messaging + (FCM), which replaces Google Cloud Messaging, or continue to use GCM. +

+ +

+ No APIs for network access or FCM are specific to Android Wear. + Refer to the existing documentation about + connecting to a network and cloud messaging. +

+ +

+ You can use protocols such as HTTP, TCP, and UDP. However, + the + android.webkit APIs are not available. Therefore, + use of cookies is available by reading and writing headers on + requests and responses, but the + CookieManager class is not available. +

+ +

+ FCM works well with + + Doze. +

+ +

+ Additionally, we recommend using the following: +

+ + + +

+ For foreground use cases, we currently recommend that you make a + request for an unmetered network. Here is an example of using + the multi-networking APIs to request an unmetered network: +

+ +
+ConnectivityManager.NetworkCallback networkCallback =
+  new ConnectivityManager.NetworkCallback() {
+    @Override
+    public void onAvailable(Network network) {
+      // access network
+      }
+    };
+ConnectivityManager connectivityManager =
+  (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+
+connectivityManager.requestNetwork(new NetworkRequest.Builder()
+  .addCapability(NET_CAPABILITY_NOT_METERED)
+  .build(), networkCallback);
+
+ +

+ We also recommend setting a timer for frontend scenarios + to prevent a user from potentially waiting for a long time. + When the network is no longer needed, or if the timer fires, + the network callback needs to be unregistered: +

+ +
+connectivityManager.unregisterNetworkCallback(networkCallback):
+
+ +

+ A Wear app can communicate with a phone app using the Wearable + Data Layer API, but connecting to a network using that API is + discouraged. +

+ +

+ Obtaining only the necessary data +

+ +

+ When obtaining data from the cloud, get only the necessary data. + Otherwise, you may introduce unnecessary latency, memory use, and battery + use. +

+ +

+ When a watch is connected over a Bluetooth LE connection, your app may + have access to a bandwidth of only 10 kilobytes per second. Therefore, + the following steps are recommended: +

+ + + +

+ Using Background Services +

+ +

+ To ensure that background tasks are correctly executed, they must account + for + Doze. In Android 6.0, Doze and App Standby resulted in significant + improvements to battery life by allowing devices to enter deep sleep when + idle and stationary. +

+ +

+ Doze is enhanced + in Android Nougat and Android Wear 2.0. When a screen turns off or enters + ambient mode for a long enough time, a subset of Doze can occur and + background tasks may be deferred for certain periods. Later, when a + device is stationary for an extended time, regular Doze occurs. +

+ +

+ You should schedule jobs with the + JobScheduler API, which enables your app to register for Doze-safe + code execution. When scheduling jobs, you can select constraints such as + periodic execution and the need for connectivity or device charging. + It is important to configure jobs in a way that does not adversely + impact battery life. Jobs should use a + + JobInfo.Builder object to provide constraints and metadata, e.g. with + one or more of the following methods for a task: +

+ + + +

+ Note that some low-bandwidth networks, such as Bluetooth LE, are + considered metered. +

+ +

+ Scheduling with constraints +

+ +

+ You can schedule a task that requires constraints. In the example below, + a JobScheduler object activates MyJobService + when the following constraints are met: +

+ + + +

+ You can use the builder method setExtras to attach a bundle + of app-specific metadata to the job request. When your job executes, this + bundle is provided to your job service. Note the MY_JOB_ID + value passed to the JobInfo.Builder constructor. This + MY_JOB_ID value is an app-provided identifier. Subsequent + calls to cancel, and subsequent jobs created with that same value, will + update the existing job: +

+ +
+JobInfo jobInfo = new JobInfo.Builder(MY_JOB_ID,
+        new ComponentName(this, MyJobService.class))
+        .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
+        .setRequiresCharging(true)
+        .setExtras(extras)
+        .build();
+((JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE))
+        .schedule(jobInfo);
+
+ +

+ Below is an implementation of + JobService to handle the job above. When the job executes, a + JobParameters object is passed into the + onStartJob method. The JobParameters object + enables you to get the job ID value along with any extras bundle provided + when scheduling the job. The onStartJob method is called on + the main application thread, and therefore any expensive logic should be + run from a separate thread. In the example, an AsyncTask is + used to run code in the background. When work is complete, you would call + the jobFinished method to notify JobScheduler + that the task is done: +

+ +
+public class MyJobService extends JobService {
+    @Override public boolean onStartJob(JobParameters params) {
+        new JobAsyncTask().execute(params);
+        return true;
+    }
+
+    private class JobAsyncTask extends AsyncTask
+
+ +

+ Cloud Notifications Using FCM +

+ +

+ FCM is the recommended way to send notifications to a watch. +

+ +

+ Provide for messages from FCM by collecting a registration token for a + device when your Wear app runs. Then include the token as part of the + destination when your server sends messages to the FCM REST endpoint. FCM + sends messages to the device identified by the token. +

+ +

+ An FCM message is in JSON format and can include one or both of the + following payloads: +

+ + + +

+ For more information and examples of payloads, see About + FCM Messages. +

+ +

+ Notifications from a Companion Phone +

+ +

+ By default, notifications are bridged (shared) from a phone app to a + watch. If you have a standalone Wear app and a corresponding phone app, + duplicate notifications can occur. For example, the same notification + from FCM, received by both a phone and a watch, could be + displayed by both devices independently. +

+ +

+ For information about preventing duplicate notifications, see Bridging + Mode for Notifications. +

diff --git a/docs/html/wear/preview/images/apk-details.png b/docs/html/wear/preview/images/apk-details.png new file mode 100644 index 0000000000000..eb3b8591f53fa Binary files /dev/null and b/docs/html/wear/preview/images/apk-details.png differ diff --git a/docs/html/wear/preview/images/apk-tabs.png b/docs/html/wear/preview/images/apk-tabs.png new file mode 100644 index 0000000000000..949b98f75b7d3 Binary files /dev/null and b/docs/html/wear/preview/images/apk-tabs.png differ diff --git a/docs/html/wear/preview/images/current-apk.png b/docs/html/wear/preview/images/current-apk.png new file mode 100644 index 0000000000000..2545f925f6081 Binary files /dev/null and b/docs/html/wear/preview/images/current-apk.png differ