콘텐츠로 건너뛰기

자주 방문한 페이지

최근 방문한 페이지

navigation

Migrating Wear Apps to GoogleApi

Starting with version 11.8.0 of Google Play services, Wear OS apps should migrate away from the GoogleApiClient class and instead use client objects that are based on the GoogleApi class.

Use of GoogleApi makes it easier to set up asynchronous operations. For example, as described in the introduction to the Tasks API, you can obtain a Task object instead of a PendingResult object.

This page includes:

Note: This update does not apply to Wear OS apps for China, which generally use version 10.2.0 of Google Play services.

Replacements for Deprecated Components

When you use classes that extend the GoogleApi class, such as DataClient and MessageClient, the Google Play services SDK manages connections to Google Play services for you.

Apps that use the replacement classes below do not need to create and manage GoogleApiClient objects. Also see Accessing Google APIs and the reference page for the Wearable class.

The following table contains deprecated components and their replacements:

Deprecated component Replacement component
CapabilityApi CapabilityClient
Channel ChannelClient.Channel
ChannelApi ChannelClient
DataApi DataClient
MessageApi MessageClient
NodeApi NodeClient

Also note the following:

Migration Example for a Wear app

As a migration example, the code snippets below illustrate how the Wear Data Layer sample, which uses the Data Layer API, was updated for version 11.8.0 of Google Play services. If your app has a phone module, its updates may be similar to those for the Wear module.

Update the dependency on Google Play services

Since your app may depend on an earlier version of Google Play services, update the following dependency in the build.gradle file of your Wear module:

dependencies {
...
compile 'com.google.android.gms:play-services-wearable:11.8.0'
}

Update the Import statements of your app

Import the necessary classes, including classes in the Tasks API.

For example, formerly the Wear Data Layer sample included the following import statement in the MainActivity.java file. This import statement should be removed:

...
import com.google.android.gms.common.api.GoogleApiClient;
...

In the Wear Data Layer sample, import statements such as the above were replaced with, for example, the following (the second one is for handling task exceptions):

...
import com.google.android.gms.tasks.Tasks;
import java.util.concurrent.ExecutionException;
...

Implement the new client interfaces

Remove any usage of the GoogleApiClient class and associated interfaces (ConnectionCallbacks, OnConnectionFailedListener, etc.) and replace the other Listener implementations with their new versions. The actual methods to override generally have the same names as before, so the main change is similar to the example below.

The main activity of the Wear Data Layer sample (as indicated in a diff on GitHub) had implemented, for example, the CapabilityApi.CapabilityListener interface. But now, the main activity implements CapabilityClient.OnCapabilityChangedListener.

Below is a comparison of the class definitions.

Here is a snippet before the use of version 11.8.0 of Google Play services:

public class MainActivity extends Activity implements
  ConnectionCallbacks,
  OnConnectionFailedListener,
  DataApi.DataListener,
  MessageApi.MessageListener,
  CapabilityApi.CapabilityListener

Here is a snippet after the use of version 11.8.0 of Google Play services:

public class MainActivity extends Activity implements
  DataClient.OnDataChangedListener,
  MessageClient.OnMessageReceivedListener,
  CapabilityClient.OnCapabilityChangedListener

Remove and add listeners

The new client objects are cached and shared between GoogleApi instances, so it is unnecessary to keep member variables; clients are inexpensive to create and won't lose their listeners.

Below is a snippet from the revised Wear Data Layer sample:

@Override
protected void onResume() {
  super.onResume();
  Wearable.getDataClient(this).addListener(this);
  Wearable.getMessageClient(this).addListener(this);
  Wearable.getCapabilityClient(this)
  .addListener(
    this, Uri.parse("wear://"), CapabilityClient.FILTER_REACHABLE);
}

@Override
protected void onPause() {
  super.onPause();
  Wearable.getDataClient(this).removeListener(this);
  Wearable.getMessageClient(this).removeListener(this);
  Wearable.getCapabilityClient(this).removeListener(this);
}

Requesting information with the Tasks API

You may want to request information outside of the listeners that update your app when there is a data change. In such cases, make a request using a client such as DataClient, in conjunction with the Tasks API and a result class (that is, as Task<ResultType>).

For example, as shown in the Wear Data Layer sample, you can use the Tasks API to find connected nodes with any given capabilities:

private void showNodes(final String... capabilityNames) {
  Task<Map<String, CapabilityInfo>> capabilitiesTask =
    Wearable.getCapabilityClient(this)
            .getAllCapabilities(CapabilityClient.FILTER_REACHABLE);
  capabilitiesTask.addOnSuccessListener(new
    OnSuccessListener<Map<String, CapabilityInfo>>() {
      @Override
      public void onSuccess(Map<String, CapabilityInfo>
        capabilityInfoMap) {
          Set<Node> nodes = new HashSet<>();
          if (capabilityInfoMap.isEmpty()) {
            showDiscoveredNodes(nodes);
            return;
          }
          for (String capabilityName : capabilityNames) {
            CapabilityInfo capabilityInfo = capabilityInfoMap.get(capabilityName);
            if (capabilityInfo != null) {
              nodes.addAll(capabilityInfo.getNodes());
            }
          }
          showDiscoveredNodes(nodes);
      }
  });
}

private void showDiscoveredNodes(Set<Node> nodes) {
  List<String> nodesList = new ArrayList<>();
  for (Node node : nodes) {
    nodesList.add(node.getDisplayName());
  }
  LOGD(TAG, "Connected Nodes: " + (nodesList.isEmpty()
    ? "No connected device was found for the given capabilities"
    : TextUtils.join(",", nodesList)));
  String msg;
  if (!nodesList.isEmpty()) {
    msg = getString(R.string.connected_nodes, TextUtils.join(", ", nodesList));
  } else {
    msg = getString(R.string.no_device);
  }
  Toast.makeText(MainActivity.this, msg, Toast.LENGTH_LONG).show();
}

For additional code that utilizes the Wearable and Tasks APIs, see the Wear Data Layer sample. And as an example of using heavy tasks off of the UI thread or in a service, there is another option available. Here is an example of how to block on a task and get the result synchronously:

@Override
protected Bitmap doInBackground(Asset... params) {
  if (params.length > 0) {
    Asset asset = params[0];
    Task<DataClient.GetFdForAssetResponse> getFdForAssetResponseTask =
      Wearable.getDataClient(getApplicationContext()).getFdForAsset(asset);
    try {
      // Block on a task and get the result synchronously. This is generally done
      // when executing a task inside a separately managed background thread. Doing
      // this on the main (UI) thread can cause your application to become
      // unresponsive.
      DataClient.GetFdForAssetResponse getFdForAssetResponse =
        Tasks.await(getFdForAssetResponseTask);
      InputStream assetInputStream = getFdForAssetResponse.getInputStream();
      if (assetInputStream != null) {
        return BitmapFactory.decodeStream(assetInputStream);
      } else {
        Log.w(TAG, "Requested an unknown Asset.");
        return null;
      }

    } catch (ExecutionException exception) {
      Log.e(TAG, "Failed retrieving asset, Task failed: " + exception);
      return null;
    } catch (InterruptedException exception) {
      Log.e(TAG, "Failed retrieving asset, interrupt occurred: " + exception);
      return null;
    }
  } else {
    Log.e(TAG, "Asset must be non-null");
    return null;
  }
}

@Override
protected void onPostExecute(Bitmap bitmap) {
  if (bitmap != null) {
    LOGD(TAG, "Setting background image on second page..");
    moveToPage(1);
    mAssetFragment.setBackgroundImage(bitmap);
  }
}
이 사이트는 쿠키를 사용하여 사이트별 언어 및 표시 옵션에 대한 환경설정을 저장합니다.

Google Play에서 성공을 거두는 데 도움이 되는 최신 Android 개발자 뉴스 및 도움말을 받아 보세요.

* 필수 입력란

완료되었습니다.

WeChat에서 Google Developers 팔로우하기

이 사이트를 (으)로 탐색할까요?

페이지를 요청했지만 이 사이트의 언어 환경설정은 입니다.

언어 환경설정을 변경하고 이 사이트를 (으)로 탐색할까요? 언어 환경설정을 나중에 변경하려면 각 페이지 하단의 언어 메뉴를 사용하세요.

이 클래스를 사용하려면 API 수준 이상이 필요합니다.

문서에 대해 선택한 API 수준이 이므로 이 문서가 표시되지 않습니다. 왼쪽 탐색 메뉴의 선택기로 문서 API 수준을 변경할 수 있습니다.

앱에 필요한 API 수준 지정에 관한 자세한 내용은 다양한 플랫폼 버전 지원을 참조하세요.

Take a short survey?
Help us improve the Android developer experience. (April 2018 — Developer Survey)