Wear uygulamalarını GoogleApi'ye taşıma

sürümü ile başlıyor Google Play Hizmetleri'nin 11.8.0 sürümü (Wear OS uygulamaları taşınmayacaktır) GoogleApiClient sınıfını kullanır ve bunun yerine GoogleApi sınıfına dayalı istemci nesnelerini kullanır.

GoogleApi kullanımı, eşzamansız işlemlerin ayarlanmasını kolaylaştırır. Örneğin, Tasks API yerine Task nesnesini alabilirsiniz PendingResult nesne.

Bu sayfa şunları içerir:

  • Yedek bileşenler tablosu
  • Görevler API'sini kullanmak için mevcut bir uygulamayı güncelleme örneği

Not: Bu güncelleme Çin.

Not: Bu API şu anda yalnızca Android telefonlarda kullanılabilir. ve Android telefonlarla eşlenen Wear OS kol saatleri. iOS ile eşlenen Wear OS kol saatleri için İnternet bağlantısı varsa uygulamalar, diğer bulut tabanlı API'leri sorgulayabilir.

Kullanımdan kaldırılan bileşenler için değişimler

DataClient ve MessageClient gibi GoogleApi sınıfını genişleten sınıflar kullandığınızda Google Play Hizmetleri SDK'sı şunları yönetir: sizin için Google Play Hizmetleri bağlantısı.

Aşağıdaki yedek sınıfları kullanan uygulamaların GoogleApiClient adlı işletmeyi yönetin nesneler'i tıklayın. Ayrıca bkz. Erişim Google API'leri ve referans sayfasını ziyaret edin.

Aşağıdaki tabloda desteği sonlandırılmış bileşenler ve bunların değiştirme:

Kullanımdan kaldırılan bileşen İkame bileşen
CapabilityApi CapabilityClient
Channel ChannelClient.Channel
ChannelApi ChannelClient
DataApi DataClient
MessageApi MessageClient
NodeApi NodeClient

Ayrıca aşağıdakilere de dikkat edin:

Wear uygulaması için taşıma örneği

Taşıma örneği olarak aşağıdaki kod snippet'leri Wear Verileri Veri Katmanı API'sını kullanan katman örneği sürümü için güncellendi Google Play Hizmetleri'nin 11.8.0 hükümleri. Uygulamanızda telefon modülü varsa Wear modülündekilere benzer.

Google Play Hizmetleri'ndeki bağımlılığı güncelleyin

Uygulamanız Google Play Hizmetleri'nin önceki bir sürümünü kullanıyor olabileceğinden, build.gradle dosyasında aşağıdaki bağımlılığı güncelleyin: Wear modülünüz:

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

Uygulamanızın içe aktarma ifadelerini güncelleme

Tasks API'deki sınıflar da dahil olmak üzere gerekli sınıfları içe aktarın.

Örneğin, önceki adıyla Wear Veri Katmanı sample aşağıdaki içe aktarma deyimini MainActivity.java dosyası. Bu import ekstresi kaldırılmalıdır:

Kotlin

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

Java

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

Wear Veri Katmanı örneği, yukarıdakilere benzer import ifadeleri örneğin, aşağıdaki URL'lerle değiştirildi (ikincisi görev istisnalarını ele alma):

Kotlin

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

Java

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

Yeni istemci arayüzlerini uygulama

Tüm GoogleApiClient kullanımlarını kaldırın sınıf ve ilişkili arayüzler (ConnectionCallbacks, OnConnectionFailedListener vb.) kaldırın ve diğer Yeni sürümlerindeki dinleyici uygulamaları. Projenin başarısı için geçersiz kılma genelde öncekiyle aynı ada sahiptir. Bu nedenle, temel değişiklik aşağıdaki örneğe benzer.

Wear Veri Katmanı örneğinin ana faaliyeti (farklarda belirtildiği gibi tarihinde Örneğin GitHub) CapabilityApi.CapabilityListener arayüzü. Ama şimdi, ana faaliyetin uyguladığı CapabilityClient.OnCapabilityChangedListener

Aşağıda sınıf tanımlarının bir karşılaştırması verilmiştir.

Google Play'in 11.8.0 sürümünü kullanmadan önceki snippet'i burada bulabilirsiniz hizmetler:

Kotlin

class MainActivity :
        Activity(),
        GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener,
        DataApi.DataListener,
        MessageApi.MessageListener,
        CapabilityApi.CapabilityListener

Java

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

Google Play'in 11.8.0 sürümünü kullandıktan sonraki bir snippet'i burada bulabilirsiniz hizmetler:

Kotlin

class MainActivity :
        Activity(),
        DataClient.OnDataChangedListener,
        MessageClient.OnMessageReceivedListener,
        CapabilityClient.OnCapabilityChangedListener

Java

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

İşleyicileri kaldırma ve ekleme

Yeni istemci nesneleri önbelleğe alındığından ve GoogleApi örnekleri arasında paylaşıldığından üyenin tutulmasına gerek yoktur değişkenler; oluşturmaları çok düşük maliyetlidir ve bu sayede, yardımcı olur.

Aşağıda, düzeltilmiş Wear Veri Katmanı'ndan bir snippet bulunmaktadır. örnek:

Kotlin

override fun 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 fun onPause() {
    super.onPause()
    Wearable.getDataClient(this).removeListener(this)
    Wearable.getMessageClient(this).removeListener(this)
    Wearable.getCapabilityClient(this).removeListener(this)
}

Java

@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);
}

Tasks API ile bilgi isteme

Güncellenen dinleyicilerin dışında da bilgi isteyebilirsiniz. uygulamanızla ilgili güncel bilgileri paylaşın. Bu gibi durumlarda Tasks API ile birlikte DataClient gibi bir istemci ve bir sonuç sınıfı (Task<ResultType> gibi).

Örneğin, Wear Veri Katmanı'nda gösterildiği gibi sample kullanıyorsanız Tasks API'yi kullanarak belirtilen tüm özelliklere sahip bağlı düğümleri bulun:

Kotlin

private fun showNodes(vararg capabilityNames: String) {
    Wearable.getCapabilityClient(this)
            .getAllCapabilities(CapabilityClient.FILTER_REACHABLE).apply {
                addOnSuccessListener { capabilityInfoMap ->
                    val nodes: Set<Node> = capabilityInfoMap
                            .filter { capabilityNames.contains(it.key) }
                            .flatMap { it.value.nodes }
                            .toSet()
                    showDiscoveredNodes(nodes)
                }
            }
}

private fun showDiscoveredNodes(nodes: Set<Node>) {
    val nodesList: Set<String> = nodes.map { it.displayName }.toSet()
    val msg: String = if (nodesList.isEmpty()) {
        Log.d(TAG, "Connected Nodes: No connected device was found for the given capabilities")
        getString(R.string.no_device)
    } else {
        Log.d(TAG, "Connected Nodes: ${nodesList.joinToString(separator = ", ")}")
        getString(R.string.connected_nodes, nodesList)
    }
    Toast.makeText(this@MainActivity, msg, Toast.LENGTH_LONG).show()
}

Java

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();
}

Giyilebilir Cihaz ve Görevler API'lerini kullanan ek kodlar için şuraya bakın: Wear Veri Katmanı örnek bölümüne bakın. Kullanıcı arayüzü iş parçacığı dışındaki ağır görevleri kullanmaya bir hizmette sunulan başka bir seçenek vardır. Elektronik tablo kullanarak yapılmış Bir görevde engelleme ve sonucu eşzamanlı olarak alma:

Kotlin

override fun doInBackground(vararg params: Asset): Bitmap? {
    if (params.isNotEmpty()) {
        val asset = params[0]
        val getFdForAssetResponseTask: Task<DataClient.GetFdForAssetResponse> =
                Wearable.getDataClient(applicationContext).getFdForAsset(asset)
        return 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.
            val getFdForAssetResponse: DataClient.GetFdForAssetResponse =
                    Tasks.await(getFdForAssetResponseTask)
            getFdForAssetResponse.inputStream?.let { assetInputStream ->
                BitmapFactory.decodeStream(assetInputStream)
            } ?: run {
                Log.w(TAG, "Requested an unknown Asset.")
                null
            }

        } catch (exception: ExecutionException) {
            Log.e(TAG, "Failed retrieving asset, Task failed: $exception")
            return null
        } catch (exception: InterruptedException) {
            Log.e(TAG, "Failed retrieving asset, interrupt occurred: $exception")
            return null
        }

    } else {
        Log.e(TAG, "Asset must be non-null")
        return null
    }
}

override fun onPostExecute(bitmap: Bitmap?) {
    bitmap?.also {
        Log.d(TAG, "Setting background image on second page..")
        moveToPage(1)
        assetFragment.setBackgroundImage(it)
    }
}

Java

@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);
    assetFragment.setBackgroundImage(bitmap);
  }
}