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.