Wear ऐप्लिकेशन को GoogleApi में माइग्रेट करें

version से शुरू हो रहा है 11.8.0 Google Play services से, Wear OS ऐप्लिकेशन माइग्रेट हो जाएंगे GoogleApiClient से क्लास का इस्तेमाल करें और उसके बजाय GoogleApi क्लास पर आधारित क्लाइंट ऑब्जेक्ट का इस्तेमाल करें.

GoogleApi का इस्तेमाल करने से, एसिंक्रोनस कार्रवाइयां सेट अप करना आसान हो जाता है. उदाहरण के लिए, जैसा कि Tasks API का इस्तेमाल कर रहे हैं, तो आप इसके बजाय Task ऑब्जेक्ट पा सकते हैं PendingResult ऑब्जेक्ट.

इस पेज में ये चीज़ें शामिल हैं:

  • रिप्लेसमेंट कॉम्पोनेंट की टेबल
  • Tasks API का इस्तेमाल करने के लिए, किसी मौजूदा ऐप्लिकेशन को अपडेट करने का उदाहरण

ध्यान दें: यह अपडेट, इनके लिए Wear OS ऐप्लिकेशन पर लागू नहीं होता चीन, जो आम तौर पर Google Play services के 10.2.0 वर्शन का इस्तेमाल करता है.

ध्यान दें: फ़िलहाल, यह एपीआई सिर्फ़ Android फ़ोन पर उपलब्ध है और Wear OS स्मार्टवॉच, जिन्हें Android फ़ोन से जोड़ा गया हो. iOS के साथ जोड़ी गई Wear OS स्मार्टवॉच के लिए अगर इंटरनेट कनेक्टिविटी उपलब्ध है, तो ऐप्लिकेशन अन्य क्लाउड-आधारित API से क्वेरी कर सकते हैं.

काम न करने वाले कॉम्पोनेंट को बदलना

जब GoogleApi क्लास (जैसे, DataClient और MessageClient) को बढ़ाने वाली क्लास का इस्तेमाल किया जाता है, तो Google Play services का SDK टूल इन्हें मैनेज करता है आपके लिए Google Play services से कनेक्ट करता है.

नीचे दी गई रीप्लेसमेंट क्लास का इस्तेमाल करने वाले ऐप्लिकेशन को GoogleApiClient को मैनेज करें ऑब्जेक्ट हैं. ऐक्सेस करना Google API और पहने जाने वाले डिवाइस की क्लास का रेफ़रंस पेज.

नीचे दी गई टेबल में ऐसे कॉम्पोनेंट और उनके कॉम्पोनेंट शामिल हैं जो अब काम नहीं करते रीप्लेसमेंट:

अब काम नहीं करने वाला कॉम्पोनेंट कॉम्पोनेंट का कॉम्पोनेंट
CapabilityApi CapabilityClient
Channel ChannelClient.Channel
ChannelApi ChannelClient
DataApi DataClient
MessageApi MessageClient
NodeApi NodeClient

इन बातों पर भी ध्यान दें:

Wear ऐप्लिकेशन के लिए माइग्रेशन का उदाहरण

माइग्रेशन के उदाहरण के तौर पर, नीचे दिए गए कोड स्निपेट दिखाते हैं कि Wear का डेटा डेटा लेयर एपीआई का इस्तेमाल करने वाला लेयर सैंपल वर्शन के लिए अपडेट किया गया Google Play services का 11.8.0. अगर आपके ऐप्लिकेशन में फ़ोन का मॉड्यूल है, तो ये अपडेट, Wear मॉड्यूल के अपडेट जैसे हो सकते हैं.

Google Play services पर डिपेंडेंसी अपडेट करना

आपका ऐप्लिकेशन, Google Play services के पुराने वर्शन पर निर्भर हो सकता है. इसकी build.gradle फ़ाइल में इस डिपेंडेंसी को अपडेट करें आपका Wear मॉड्यूल:

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

अपने ऐप्लिकेशन के इंपोर्ट स्टेटमेंट अपडेट करें

ज़रूरी क्लास इंपोर्ट करें. इनमें Tasks API में मौजूद क्लास भी शामिल हैं.

उदाहरण के लिए, पहले Wear डेटा लेयर था सैंपल में ये इंपोर्ट स्टेटमेंट शामिल किए गए हैं MainActivity.java फ़ाइल. यह import स्टेटमेंट हटाया जाना चाहिए:

Kotlin

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

Java

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

Wear में डेटा लेयर सैंपल, import स्टेटमेंट (जैसा कि ऊपर बताया गया है) उदाहरण के लिए, निम्न से बदला गया (दूसरा वाला हैंडलिंग टास्क के अपवाद):

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;
...

नए क्लाइंट इंटरफ़ेस लागू करना

GoogleApiClient को इस्तेमाल करना हटाएं क्लास और उससे जुड़े इंटरफ़ेस (ConnectionCallbacks, OnConnectionFailedListener वगैरह) और अन्य लिसनर को उनके नए वर्शन के साथ लागू करना. इसके सही तरीके ओवरराइड आम तौर पर पहले जैसे नाम वाले होते हैं, इसलिए मुख्य परिवर्तन यह है जैसा कि नीचे दिए गए उदाहरण में बताया गया है.

Wear डेटा लेयर सैंपल की मुख्य गतिविधि (जैसा कि अंतर में दिखाया गया है को GitHub) पर लागू किया था, उदाहरण के लिए, CapabilityApi.CapabilityListener इंटरफ़ेस. हालांकि, अब मुख्य गतिविधि लागू करती है CapabilityClient.OnCapabilityChangedListener.

नीचे क्लास की परिभाषाओं की तुलना की गई है.

यहां Google Play के 11.8.0 वर्शन के इस्तेमाल से पहले का एक स्निपेट दिया गया है सेवाएं:

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 के 11.8.0 वर्शन के इस्तेमाल के बाद का स्निपेट दिया गया है सेवाएं:

Kotlin

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

Java

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

लिसनर हटाएं और जोड़ें

नए क्लाइंट ऑब्जेक्ट, कैश मेमोरी में सेव किए जाते हैं और GoogleApi इंस्टेंस के बीच शेयर किए जाते हैं. इसलिए, सदस्य को बनाए रखना ज़रूरी नहीं है वैरिएबल; क्लाइंट बनाने में पैसा खर्च होता है और वे हमेशा सुरक्षित रहते हैं श्रोताओं के लिए.

नीचे, अपडेट किए गए Wear डेटा लेयर का एक स्निपेट दिया गया है सैंपल:

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 की मदद से जानकारी पाने का अनुरोध करना

हो सकता है कि आप अपडेट करने वाले लिसनर से बाहर, जानकारी पाने का अनुरोध करना चाहें डेटा में बदलाव होने पर आपके ऐप्लिकेशन पर. ऐसे मामलों में, इसका इस्तेमाल करके अनुरोध करें DataClient जैसा कोई क्लाइंट, जो Tasks API के साथ जुड़ा हो और एक रिज़ल्ट क्लास (यानी, Task<ResultType> के रूप में).

उदाहरण के लिए, जैसा कि Wear डेटा लेयर में दिखाया गया है सैंपल है, तो आप Tasks API का इस्तेमाल करके, किसी खास सुविधा के साथ कनेक्ट किए गए नोड ढूंढे जा सकते हैं:

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

Wearable और Tasks API का इस्तेमाल करने वाले अन्य कोड के लिए, Wear की डेटा लेयर नमूना. यूज़र इंटरफ़ेस (यूआई) थ्रेड से बाहर जाकर, बहुत ज़्यादा टास्क इस्तेमाल करने के उदाहरण के तौर पर या किसी सेवा में, कोई दूसरा विकल्प उपलब्ध है. यहां इसका एक उदाहरण दिया गया है किसी टास्क को कैसे ब्लॉक करें और उसका नतीजा कैसे पाएं:

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