סנכרון נתונים

במאמר הזה מוסבר איך לסנכרן נתונים בין מכשיר Wear OS לבין טלפון. בסקירה הכללית מוסבר מתי כדאי להשתמש ב-Data Layer API ומתי כדאי להשתמש בתשתית שלכם.

שליחה וסנכרון של נתונים ישירות מהרשת

מפתחים אפליקציות ל-Wear OS כדי לתקשר ישירות עם הרשת. אתם יכולים להשתמש באותם ממשקי API שאתם משתמשים בהם לפיתוח לנייד, אבל חשוב לזכור כמה הבדלים שספציפיים ל-Wear OS.

סנכרון נתונים באמצעות Wear OS Data Layer API

DataClient חושף API לרכיבים כדי לקרוא או לכתוב ב-DataItem או ב-Asset.

אפשר להגדיר פריטי נתונים ונכסים גם בלי להתחבר למכשירים. הם מסתנכרנים כשהמכשירים מתחברים לרשת. הנתונים האלה פרטיים לאפליקציה שלכם, ורק לאפליקציה שלכם יש גישה אליהם במכשירים אחרים.

  • DataItem מסונכרן בכל המכשירים ברשת Wear OS. בדרך כלל הם קטנים.

  • משתמשים ב-Asset כדי להעביר אובייקט גדול יותר, כמו תמונה. המערכת עוקבת אחרי הנכסים שכבר הועברו ומבצעת ביטול כפילויות באופן אוטומטי.

האזנה לאירועים בשירותים

מרחיבים את המחלקה WearableListenerService. המערכת מנהלת את מחזור החיים של WearableListenerService הבסיסי, מקשרת לשירות כשהיא צריכה לשלוח פריטי נתונים או הודעות, ומבטלת את הקישור לשירות כשלא נדרשת עבודה.

האזנה לאירועים בפעילויות

מטמיעים את הממשק OnDataChangedListener. השתמשו בממשק הזה במקום ב-WearableListenerService כשאתם רוצים להאזין לשינויים רק כשהמשתמש משתמש באפליקציה באופן פעיל.

description: העברת אובייקטים בינאריים גדולים, כמו תמונות, בין טלפונים עם Android לשעוני Wear OS באמצעות נכסים ב-Data Layer API. keywords_public: Wear OS, Data Layer API, נכסים, העברת נתונים ב-Bluetooth, סנכרון נתונים, DataMap, PutDataRequest

סנכרון נתונים

כדי לשתף אובייקטים בינאריים גדולים באמצעות Bluetooth, כמו הקלטה קולית ממכשיר אחר, אתם יכולים לצרף Asset לפריט נתונים ואז להכניס את פריט הנתונים למאגר הנתונים המשוכפל.

הערה: Data Layer API יכול לשלוח הודעות ולסנכרן נתונים רק עם טלפונים עם Android או שעוני Wear OS. אם מכשיר Wear OS מותאם למכשיר iOS, ממשק ה-API של שכבת הנתונים לא יפעל.

לכן, אל תשתמשו ב-Data Layer API כדרך העיקרית לתקשר עם רשת. במקום זאת, צריך לפעול לפי אותה תבנית באפליקציה ל-Wear OS כמו באפליקציה לטלפון – עם כמה הבדלים קלים, כפי שמתואר במאמר גישה לרשת וסנכרון ב-Wear OS.

הנכסים מטפלים באופן אוטומטי בשמירת נתונים במטמון כדי למנוע שידור חוזר ולחסוך ברוחב הפס של Bluetooth. דפוס נפוץ הוא שאפליקציה לטלפון מורידה תמונה, מכווצת אותה לגודל שמתאים לתצוגה בשעון ומשתפת אותה עם אפליקציית שעון חכם כנכס. הדוגמאות הבאות ממחישות את התבנית הזו.

העברת נכס

יוצרים את הנכס באמצעות אחת מהשיטות של create...() במחלקה Asset. ממירים מפת סיביות (bitmap) למערך בייטים ואז קוראים ל-createFromBytes() כדי ליצור את הנכס, כמו בדוגמה הבאה.

private fun createAssetFromBitmap(bitmap: Bitmap): Asset =
    ByteArrayOutputStream().let { byteStream ->
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteStream)
        Asset.createFromBytes(byteStream.toByteArray())
    }

אחר כך מצרפים את הנכס לפריט נתונים באמצעות השיטה putAsset() ב-DataMap או ב-PutDataRequest. לאחר מכן, מכניסים את פריט הנתונים למאגר הנתונים באמצעות השיטה putDataItem(), כמו שמוצג בדוגמאות הבאות.

בדוגמה הבאה נעשה שימוש ב-PutDataRequest:

private fun Context.sendImagePutDataRequest(): Task<DataItem> {

    val asset: Asset = createAssetFromBitmap(BitmapFactory.decodeResource(resources, R.drawable.ic_walk))
    val request: PutDataRequest = PutDataRequest.create("/image").apply {
        putAsset("profileImage", asset)
    }
    val putTask: Task<DataItem> = Wearable.getDataClient(this).putDataItem(request)

    return putTask
}

בדוגמה הבאה נעשה שימוש ב-PutDataMapRequest:

private fun Context.sendImagePutDataMapRequest(): Task<DataItem> {

    val asset: Asset = createAssetFromBitmap(BitmapFactory.decodeResource(resources, R.drawable.ic_walk))
    val request: PutDataRequest = PutDataMapRequest.create("/image").run {
        dataMap.putAsset("profileImage", asset)
        asPutDataRequest()
    }
    val putTask: Task<DataItem> = Wearable.getDataClient(this).putDataItem(request)

    return putTask
}

קבלת נכסים

אחרי שיוצרים נכס, בדרך כלל קוראים ומחלצים אותו בצד השני של החיבור. בדוגמה הבאה אפשר לראות איך מטמיעים את הקריאה החוזרת (callback) כדי לזהות שינוי בנכס ולחלץ את הנכס:

override fun onDataChanged(dataEvents: DataEventBuffer) {
    dataEvents
        .filter { it.type == DataEvent.TYPE_CHANGED && it.dataItem.uri.path == "/image" }
        .forEach { event ->
            val asset = DataMapItem.fromDataItem(event.dataItem)
                .dataMap.getAsset("profileImage")

            asset?.let { safeAsset ->
                lifecycleScope.launch {
                    val bitmap = loadBitmapFromAsset(safeAsset)
                    // Do something with the bitmap
                }
            }
        }
}

private suspend fun loadBitmapFromAsset(asset: Asset): Bitmap? = withContext(Dispatchers.IO) {
    try {
        val assetResult = Wearable.getDataClient(this@DataLayerActivity2)
            .getFdForAsset(asset)
            .await()

        assetResult?.inputStream?.use { inputStream ->
            BitmapFactory.decodeStream(inputStream)
        }
    } catch (e: Exception) {
        e.printStackTrace()
        null
    }
}

מידע נוסף זמין בפרויקט לדוגמה של DataLayer ב-GitHub.