इस दस्तावेज़ में, Wear OS डिवाइस और हाथ में पकड़े जाने वाले डिवाइस के बीच डेटा सिंक करने का तरीका बताया गया है.
सीधे नेटवर्क से डेटा भेजना और सिंक करना
नेटवर्क से सीधे तौर पर इंटरैक्ट करने के लिए, Wear OS ऐप्लिकेशन बनाएं. मोबाइल डेवलपमेंट के लिए इस्तेमाल किए जाने वाले एपीआई का ही इस्तेमाल करें. हालांकि, Wear OS के हिसाब से कुछ अंतरों को ध्यान में रखें.
Wear OS Data Layer API का इस्तेमाल करके डेटा सिंक करना
DataClient
, कॉम्पोनेंट के लिए एपीआई को एक्सपोज़ करता है, ताकि वे DataItem
या
Asset
को पढ़ सकें या उसमें लिख सकें.
किसी भी डिवाइस से कनेक्ट किए बिना, डेटा आइटम और एसेट सेट की जा सकती हैं. डिवाइसों के नेटवर्क से कनेक्ट होने पर, ये सिंक हो जाते हैं. यह डेटा आपके ऐप्लिकेशन के लिए निजी होता है और सिर्फ़ दूसरे डिवाइसों पर आपके ऐप्लिकेशन के लिए ऐक्सेस किया जा सकता है.
DataItem
, Wear OS नेटवर्क में मौजूद सभी डिवाइसों पर सिंक हो जाता है. आम तौर पर, ये छोटे साइज़ के होते हैं.किसी बड़ी इमेज को ट्रांसफ़र करने के लिए,
Asset
का इस्तेमाल करें. सिस्टम यह ट्रैक करता है कि कौनसी ऐसेट पहले से ट्रांसफ़र की जा चुकी हैं और डुप्लीकेट कॉपी हटाने की प्रोसेस अपने-आप करता है.
सेवाओं में इवेंट सुनना
WearableListenerService
क्लास को बड़ा करें. सिस्टम, बेस WearableListenerService
के लाइफ़साइकल को मैनेज करता है. जब उसे डेटा आइटम या मैसेज भेजने की ज़रूरत होती है, तब वह सेवा से बाइंड हो जाता है और जब कोई काम नहीं होता, तब सेवा से अनबाइंड हो जाता है.
गतिविधियों में इवेंट सुनना
OnDataChangedListener
इंटरफ़ेस लागू करें. अगर आपको सिर्फ़ तब बदलावों को सुनना है, जब उपयोगकर्ता आपके ऐप्लिकेशन का इस्तेमाल कर रहा हो, तो WearableListenerService
के बजाय इस इंटरफ़ेस का इस्तेमाल करें.
डेटा ट्रांसफ़र करें
किसी दूसरे डिवाइस से, ब्लूटूथ ट्रांसपोर्ट की मदद से बड़े डेटा ऑब्जेक्ट भेजने के लिए, डेटा आइटम में
Asset
अटैच करें. इसके बाद, डेटा आइटम को डुप्लीकेट किए गए डेटास्टोर में डालें. जैसे, किसी ऑडियो रिकॉर्डिंग को भेजना.
एसेट, डेटा को अपने-आप कैश मेमोरी में सेव करती हैं, ताकि डेटा को फिर से भेजने से बचा जा सके और ब्लूटूथ बैंडविड्थ को बचाया जा सके. आम तौर पर, हैंडहेल्ड ऐप्लिकेशन किसी इमेज को डाउनलोड करता है और उसे स्मार्टवॉच पर दिखाने के लिए सही साइज़ में छोटा करता है. इसके बाद, उसे स्मार्टवॉच ऐप्लिकेशन पर ऐसेट के तौर पर भेजता है. नीचे दिए गए उदाहरणों में, इस पैटर्न के बारे में बताया गया है.
ध्यान दें: सैद्धांतिक तौर पर, डेटा आइटम का साइज़ 100 केबी तक सीमित है. हालांकि, असल में बड़े डेटा आइटम का इस्तेमाल किया जा सकता है. बड़े डेटा आइटम के लिए, डेटा को यूनीक पाथ के हिसाब से अलग करें. साथ ही, सभी डेटा के लिए एक ही पाथ का इस्तेमाल करने से बचें. बड़ी एसेट ट्रांसफ़र करने से, कई मामलों में उपयोगकर्ता अनुभव पर असर पड़ता है. इसलिए, अपने ऐप्लिकेशन की जांच करें, ताकि यह पक्का किया जा सके कि बड़ी एसेट ट्रांसफ़र करते समय वे अच्छी परफ़ॉर्म करें.
कोई ऐसेट ट्रांसफ़र करना
create...()
Asset
क्लास में दिए गए किसी एक तरीके का इस्तेमाल करके ऐसेट बनाएं.
बिटमैप को बाइट स्ट्रीम में बदलें. इसके बाद, ऐसेट बनाने के लिए
createFromBytes()
को कॉल करें, जैसा कि नीचे दिए गए सैंपल में दिखाया गया है.
private fun createAssetFromBitmap(bitmap: Bitmap): Asset = ByteArrayOutputStream().let { byteStream -> bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteStream) Asset.createFromBytes(byteStream.toByteArray()) }
private static Asset createAssetFromBitmap(Bitmap bitmap) { final ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteStream); return Asset.createFromBytes(byteStream.toByteArray()); }
इसके बाद, ऐसेट को किसी डेटा आइटम से अटैच करें. इसके लिए, putAsset()
का तरीका इस्तेमाल करें. इसके लिए,
DataMap
या
PutDataRequest
में जाएं. इसके बाद, डेटा आइटम को डेटास्टोर में डालें. इसके लिए, यहां दिए गए सैंपल में दिखाए गए तरीके का इस्तेमाल करें.
putDataItem()
यहां दिए गए सैंपल में PutDataRequest
का इस्तेमाल किया गया है:
val asset: Asset = BitmapFactory.decodeResource(resources, R.drawable.image).let { bitmap -> createAssetFromBitmap(bitmap) } val request: PutDataRequest = PutDataRequest.create("/image").apply { putAsset("profileImage", asset) } val putTask: Task<DataItem> = Wearable.getDataClient(context).putDataItem(request)
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.image); Asset asset = createAssetFromBitmap(bitmap); PutDataRequest request = PutDataRequest.create("/image"); request.putAsset("profileImage", asset); Task<DataItem> putTask = Wearable.getDataClient(context).putDataItem(request);
यहां दिए गए सैंपल में PutDataMapRequest
का इस्तेमाल किया गया है:
val asset: Asset = BitmapFactory.decodeResource(resources, R.drawable.image).let { bitmap -> createAssetFromBitmap(bitmap) } val request: PutDataRequest = PutDataMapRequest.create("/image").run { dataMap.putAsset("profileImage", asset) asPutDataRequest() } val putTask: Task<DataItem> = Wearable.getDataClient(context).putDataItem(request)
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.image); Asset asset = createAssetFromBitmap(bitmap); PutDataMapRequest dataMap = PutDataMapRequest.create("/image"); dataMap.getDataMap().putAsset("profileImage", asset); PutDataRequest request = dataMap.asPutDataRequest(); Task<DataItem> putTask = Wearable.getDataClient(context).putDataItem(request);
ऐसेट पाना
ऐसेट बनाने के बाद, हो सकता है कि आपको कनेक्शन के दूसरी तरफ़ जाकर उसे पढ़ना और निकालना हो. ऐसेट में हुए बदलाव का पता लगाने और ऐसेट को निकालने के लिए, कॉलबैक को लागू करने का उदाहरण यहां दिया गया है:
override fun onDataChanged(dataEvents: DataEventBuffer) { dataEvents .filter { it.type == DataEvent.TYPE_CHANGED && it.dataItem.uri.path == "/image" } .forEach { event -> val bitmap: Bitmap? = DataMapItem.fromDataItem(event.dataItem) .dataMap.getAsset("profileImage") .let { asset -> loadBitmapFromAsset(asset) } // Do something with the bitmap } } fun loadBitmapFromAsset(asset: Asset): Bitmap? { // Convert asset into a file descriptor and block until it's ready val assetInputStream: InputStream? = Tasks.await(Wearable.getDataClient(context).getFdForAsset(asset)) ?.inputStream return assetInputStream?.let { inputStream -> // Decode the stream into a bitmap BitmapFactory.decodeStream(inputStream) } ?: run { Log.w(TAG, "Requested an unknown Asset.") null } }
@Override public void onDataChanged(DataEventBuffer dataEvents) { for (DataEvent event : dataEvents) { if (event.getType() == DataEvent.TYPE_CHANGED && event.getDataItem().getUri().getPath().equals("/image")) { DataMapItem dataMapItem = DataMapItem.fromDataItem(event.getDataItem()); Asset profileAsset = dataMapItem.getDataMap().getAsset("profileImage"); Bitmap bitmap = loadBitmapFromAsset(profileAsset); // Do something with the bitmap } } } public Bitmap loadBitmapFromAsset(Asset asset) { if (asset == null) { throw new IllegalArgumentException("Asset must be non-null"); } // Convert asset into a file descriptor and block until it's ready InputStream assetInputStream = Tasks.await(Wearable.getDataClient(context).getFdForAsset(asset)) .getInputStream(); if (assetInputStream == null) { Log.w(TAG, "Requested an unknown Asset."); return null; } // Decode the stream into a bitmap return BitmapFactory.decodeStream(assetInputStream); }
ज़्यादा जानकारी के लिए, GitHub पर DataLayer का सैंपल प्रोजेक्ट देखें.