Maps API ב-Wear OS

מפה במכשיר לביש

באמצעות ה-SDK של מפות Google ל-Android, ניתן ליצור אפליקציה לבישה מבוססת מפה שפועלת ישירות במכשירי Wear OS by Google. משתמשי האפליקציה יכולים לראות את המיקום שלהם במפה פשוט על ידי מבט אל פרקי כף היד שלהם. הן יכולות להציג את המיקום שלהם במסלול, לדוגמה, ואז להגדיל את התצוגה כדי לראות פרטים או להקיש על כדי לראות חלון מידע שסופק על ידי האפליקציה.

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

תחילת העבודה עם Wear OS

פיתוח אפליקציה לבישה באמצעות ה-SDK של מפות Google ל-Android היא כמו לבנות אפליקציה של מפות Google לכל מכשיר Android אחר. ההבדל נמצא בעיצוב שלך לגורם הצורה הקטן יותר של המכשיר הלביש, לבצע אופטימיזציה של השימושיות והביצועים של האפליקציה.

Android Studio הוא הכלי המומלץ לפיתוח Wear OS, כי הוא מספק הגדרת פרויקט, הכללה בספרייה ונוחות אריזה.

לקבלת עזרה כללית בעיצוב אפליקציה לבישה, כדאי לעיין ב הנחיות לעיצוב Wear OS. לקבלת עזרה ביצירה לאפליקציה הלבישה הראשונה, כדאי לעיין במדריך ליצירת אפליקציות לבישות.

פיתוח אפליקציית המפות הראשונה שלך ב-Wear OS

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

הוספת יחסי תלות למודול Wear

צריך לוודא שיחסי התלות הבאים כלולים בקובץ build.gradle של מודול Wear OS של האפליקציה:

dependencies {
    // ...
    compileOnly 'com.google.android.wearable:wearable:2.9.0'
    implementation 'com.google.android.support:wearable:2.9.0'
    implementation 'com.google.android.gms:play-services-maps:19.0.0'

    // This dependency is necessary for ambient mode
    implementation 'androidx.wear:wear:1.3.0'
}

למידע נוסף על יחסי התלות, אפשר לעיין במדריך הוספת מודול Wear OS בפרויקט הקיים.

להטמיע תנועת החלקה לסגירה ולהגדיר את צבע הרקע הראשוני

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

כדי להגדיר צבע רקע ראשוני בהתאמה אישית, יש להשתמש ב-XML של map:backgroundColor כדי להגדיר את הצבע שיוצג עד שמשבצות המפה בפועל ייטענו.

הוספת הרכיבים SwipeDismissFrameLayout ו-backgroundColor לפריסה את ההגדרה שלו כמאגר התגים של SupportMapFragment:

  <androidx.wear.widget.SwipeDismissFrameLayout
      android:id="@+id/map_container"
      android:layout_width="match_parent"
      android:layout_height="match_parent">
    <fragment
        android:id="@+id/map"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        map:backgroundColor="#fff0b2dd" />
  </androidx.wear.widget.SwipeDismissFrameLayout>

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

Kotlin



class MainActivity : AppCompatActivity(), OnMapReadyCallback,
                     AmbientModeSupport.AmbientCallbackProvider {


    public override fun onCreate(savedState: Bundle?) {
        super.onCreate(savedState)

        // Set the layout. It only contains a SupportMapFragment and a DismissOverlay.
        setContentView(R.layout.activity_main)

        // Enable ambient support, so the map remains visible in simplified, low-color display
        // when the user is no longer actively using the app but the app is still visible on the
        // watch face.
        val controller = AmbientModeSupport.attach(this)
        Log.d(MainActivity::class.java.simpleName, "Is ambient enabled: " + controller.isAmbient)

        // Retrieve the containers for the root of the layout and the map. Margins will need to be
        // set on them to account for the system window insets.
        val mapFrameLayout = findViewById<SwipeDismissFrameLayout>(R.id.map_container)
        mapFrameLayout.addCallback(object : SwipeDismissFrameLayout.Callback() {
            override fun onDismissed(layout: SwipeDismissFrameLayout) {
                onBackPressed()
            }
        })

        // Obtain the MapFragment and set the async listener to be notified when the map is ready.
        mapFragment = supportFragmentManager
            .findFragmentById(R.id.map) as SupportMapFragment
        mapFragment.getMapAsync(this)
    }

    // ...
}

      

Java


public class MainActivity extends AppCompatActivity implements OnMapReadyCallback,
    AmbientModeSupport.AmbientCallbackProvider {


    public void onCreate(Bundle savedState) {
        super.onCreate(savedState);

        // Set the layout. It only contains a SupportMapFragment and a DismissOverlay.
        setContentView(R.layout.activity_main);

        // Enable ambient support, so the map remains visible in simplified, low-color display
        // when the user is no longer actively using the app but the app is still visible on the
        // watch face.
        AmbientModeSupport.AmbientController controller = AmbientModeSupport.attach(this);
        Log.d(MainActivity.class.getSimpleName(), "Is ambient enabled: " + controller.isAmbient());

        // Retrieve the containers for the root of the layout and the map. Margins will need to be
        // set on them to account for the system window insets.
        final SwipeDismissFrameLayout mapFrameLayout = (SwipeDismissFrameLayout) findViewById(
            R.id.map_container);
        mapFrameLayout.addCallback(new SwipeDismissFrameLayout.Callback() {
            @Override
            public void onDismissed(SwipeDismissFrameLayout layout) {
                onBackPressed();
            }
        });

        // Obtain the MapFragment and set the async listener to be notified when the map is ready.
        mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
    }

    // ...
}

      

הוספת מפה

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

Kotlin



private val sydney = LatLng(-33.85704, 151.21522)

override fun onMapReady(googleMap: GoogleMap) {
    // Add a marker with a title that is shown in its info window.
    googleMap.addMarker(
        MarkerOptions().position(sydney)
            .title("Sydney Opera House")
    )

    // Move the camera to show the marker.
    googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(sydney, 10f))
}

      

Java


private static final LatLng SYDNEY = new LatLng(-33.85704, 151.21522);

@Override
public void onMapReady(@NonNull GoogleMap googleMap) {
    // Add a marker with a title that is shown in its info window.
    googleMap.addMarker(new MarkerOptions().position(SYDNEY)
        .title("Sydney Opera House"));

    // Move the camera to show the marker.
    googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(SYDNEY, 10));
}

      

הפעלת תאורת אווירה

ה-SDK של מפות Google ל-Android תומך במצב רגישות לגאדג'טים לבישים תרגום מכונה. לפעמים, אפליקציות שתומכות במצב רגישות לסביבה נקראות אפליקציות מופעלות תמיד. תאורת האווירה מופעלת כשהמשתמש לא משתמש יותר באפליקציה באופן פעיל. ומאפשרת לאפליקציה להמשיך להיות גלויה במכשיר הלביש.

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

כדי לוודא שהאפליקציה משתמשת במצב האווירה של המפה, יש לבצע את השלבים הבאים:

  1. צריך לעדכן את Android SDK כך שיכלול את Android 6.0 (API 23) ואילך שמספקת את ממשקי ה-API שמאפשרים לפעילויות לעבור במצב תצוגה. מידע על עדכון ה-SDK זמין במסמכי התיעוד של Android על הוספה של חבילות SDK.
  2. כדי לוודא שהפרויקט מטרגט את Android 6.0 ואילך, צריך להגדיר targetSdkVersion עד 23 ואילך במניפסט האפליקציה.
  3. צריך להוסיף את יחסי התלות הלבישים לקובץ build.gradle של האפליקציה. לצפייה דוגמה בדף הזה.
  4. הוספת הרשומה של הספרייה המשותפת הלבישה לקובץ המניפסט של האפליקציה הלבישת, בתור שתוארו בשיעור ההדרכה על Android איך מוודאים שהאפליקציה גלויה.
  5. מוסיפים את ההרשאה WAKE_LOCK למניפסטים של אפליקציות לבישים ולמכשירים ניידים, כמו שמתואר בשיעור ההדרכה על Android הקפידו שהאפליקציה שלכם תהיה גלויה.
  6. בשיטה onCreate() של הפעילות, קוראים לפונקציה AmbientModeSupport.attach(). זה אומר ל- למערכת ההפעלה שהאפליקציה פועלת תמיד, כך שכאשר המכשיר בכיבוי המכשיר צריך לעבור למצב רגישות לסביבה במקום לחזור לשעון פרצוף.
  7. מטמיעים את הממשק של AmbientModeSupport.AmbientCallbackProvider פעילות שמאפשרת לקבל שינויים במצב האווירה.
  8. יש להגדיר את המפה כך שתתמוך במצב רגישות לסביבה. אפשר לעשות זאת על ידי הגדרה של במאפיין map:ambientEnabled="true" בקובץ פריסת ה-XML של הפעילות, או אותו באופן פרוגרמטי על ידי הגדרה של GoogleMapOptions.ambientEnabled(true). ההגדרה הזו מודיעה ל-API שעליו לטעון מראש את קטעי המפה הנחוצים להשתמש בו במצב רגישות לסביבה.
  9. כשהפעילות עוברת למצב רגישות לסביבה, המערכת מפעילה את השיטה onEnterAmbient() בAmbientCallback לספק. ביטול onEnterAmbient() והתקשרות SupportMapFragment.onEnterAmbient(ambientDetails) או MapView.onEnterAmbient(ambientDetails) ה-API מחליף לא אינטראקטיבי ובצבע נמוך של המפה.
  10. באופן דומה, הפונקציה onExitAmbient() SupportMapFragment.onExitAmbient() או MapView.onExitAmbient(). ממשק API מחליף לעיבוד הרגיל של המפה.

דוגמת הקוד הבאה מפעילה את מצב האווירה בפעילות:

Kotlin



class AmbientActivity : AppCompatActivity(), AmbientModeSupport.AmbientCallbackProvider {

    private lateinit var mapFragment: SupportMapFragment

    public override fun onCreate(savedState: Bundle?) {
        super.onCreate(savedState)

        // Set the layout. It only contains a SupportMapFragment and a DismissOverlay.
        setContentView(R.layout.activity_main)

        // Enable ambient support, so the map remains visible in simplified, low-color display
        // when the user is no longer actively using the app but the app is still visible on the
        // watch face.
        val controller = AmbientModeSupport.attach(this)
        Log.d(AmbientActivity::class.java.simpleName, "Is ambient enabled: " + controller.isAmbient)

        // Obtain the MapFragment and set the async listener to be notified when the map is ready.
        mapFragment = supportFragmentManager
            .findFragmentById(R.id.map) as SupportMapFragment
    }

    override fun getAmbientCallback(): AmbientModeSupport.AmbientCallback {
        return object : AmbientModeSupport.AmbientCallback() {
            /**
             * Starts ambient mode on the map.
             * The API swaps to a non-interactive and low-color rendering of the map when the user is no
             * longer actively using the app.
             */
            override fun onEnterAmbient(ambientDetails: Bundle) {
                super.onEnterAmbient(ambientDetails)
                mapFragment.onEnterAmbient(ambientDetails)
            }

            /**
             * Exits ambient mode on the map.
             * The API swaps to the normal rendering of the map when the user starts actively using the app.
             */
            override fun onExitAmbient() {
                super.onExitAmbient()
                mapFragment.onExitAmbient()
            }
        }
    }
}

      

Java


public class AmbientActivity extends AppCompatActivity implements
    AmbientModeSupport.AmbientCallbackProvider {

    private SupportMapFragment mapFragment;

    public void onCreate(Bundle savedState) {
        super.onCreate(savedState);

        // Set the layout. It only contains a SupportMapFragment and a DismissOverlay.
        setContentView(R.layout.activity_main);

        // Enable ambient support, so the map remains visible in simplified, low-color display
        // when the user is no longer actively using the app but the app is still visible on the
        // watch face.
        AmbientModeSupport.AmbientController controller = AmbientModeSupport.attach(this);
        Log.d(AmbientActivity.class.getSimpleName(), "Is ambient enabled: " + controller.isAmbient());

        // Obtain the MapFragment and set the async listener to be notified when the map is ready.
        mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);
    }

    @Override
    public AmbientCallback getAmbientCallback() {
        return new AmbientCallback() {
            /**
             * Starts ambient mode on the map.
             * The API swaps to a non-interactive and low-color rendering of the map when the user is no
             * longer actively using the app.
             */
            @Override
            public void onEnterAmbient(Bundle ambientDetails) {
                super.onEnterAmbient(ambientDetails);
                mapFragment.onEnterAmbient(ambientDetails);
            }

            /**
             * Exits ambient mode on the map.
             * The API swaps to the normal rendering of the map when the user starts actively using the app.
             */
            @Override
            public void onExitAmbient() {
                super.onExitAmbient();
                mapFragment.onExitAmbient();
            }
        };
    }
}

      

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

שימוש ב-Street View ב-Wear OS

יש תמיכה מלאה ב-Street View במכשירים לבישים.

כדי לאפשר למשתמשים לצאת מהאפליקציה כשהם צופים בפנורמה של Street View, צריך להשתמש ב- StreetViewPanorama.OnStreetViewPanoramaLongClickListener ממשק להאזנה לתנועה של לחיצה ארוכה. כשמשתמש לוחץ לחיצה ארוכה במקום כלשהו בתמונת Street View, תקבלו אירוע מסוג onStreetViewPanoramaLongClick(StreetViewPanoramaOrientation). שיחת טלפון DismissOverlayView.show() כדי להציג לחצן יציאה.

קוד לדוגמה

ב-GitHub יש אפליקציה לדוגמה, ואפשר להשתמש בה בתור נקודת ההתחלה של האפליקציה. בדוגמה אפשר לראות איך מגדירים מפת Google בסיסית ב-Wear OS.

פונקציונליות נתמכת ב-API של מפות Google ב-Wear OS

בסעיף זה מתוארים ההבדלים בפונקציונליות הנתמכת של מפות ב: מכשירים לבישים בהשוואה למכשירים ניידים (טלפונים וטאבלטים). כל תכונות ה-API שלא צוינו למטה אמורות לפעול לפי התיעוד המלא של ה-API.

פונקציונליות
מצב אינטראקטיבי מלא ומצב Lite

ניתן להשתמש ב-SDK של מפות ל-Android במצב אינטראקטיבי מלא או במצב Lite. כדאי להשתמש במצב Lite אם רוצים לשפר את הביצועים במכשיר הלביש והאפליקציה לא צריכה תמיכה אינטראקציה כגון תנועות או הזזה ושינוי מרחק התצוגה של המפה.

במצב Lite, כוונה להפעיל את האפליקציה לנייד של מפות Google כאשר משתמש מקיש על המפה מושבת ולא ניתן להפעיל אותו ב- מכשיר לביש.

לרשימה מלאה של ההבדלים בין מצב Lite לבין מצב אינטראקטיבי מלא במצב בסיסימצב Lite התיעוד.

סרגל הכלים של המפה המפה סרגל הכלים מושבת ולא ניתן להפעיל אותו מכשיר לביש.
פקדים בממשק המשתמש ממשק המשתמש אמצעי הבקרה מושבתים כברירת מחדל במכשירים לבישים. המידע הזה כולל מרחק התצוגה, המצפן ופקדי המיקום. אפשר להפעיל אותן באמצעות UiSettings כרגיל.
תנועות נגיעה יחידה תנועות פועלות כמצופה. לדוגמה: נגיעה וגרירה כדי להזיז את המפה, הקשה כפולה כדי להתקרב, והקש שתי אצבעות כדי להתרחק. התמיכה בתנועות מרובות מגע משתנה בהתאם למכשיר של המשתמש. דוגמאות לתנועות עם כמה נקודות מגע כוללות דחיפה באמצעות שתי אצבעות להטיית המפה, עושים תנועת צביטה כדי לשנות את מרחק התצוגה וסיבוב עם שתי אצבעות.
מפות פנים ובניינים מפות פנים הן מושבת כברירת מחדל במכשיר לביש. אפשר להפעיל אותם באמצעות שיחת טלפון GoogleMap.setIndoorEnabled(true) אם מפות הפנים מופעלת, המפה תציג את רמת הקומה המוגדרת כברירת מחדל. הרמה בוחר ברכיב בממשק המשתמש לא נתמך במכשירים לבישים.
שכבות-על של משבצות שכבות-על של משבצות הן לא נתמך במכשירים לבישים.

שיטות מומלצות לפיתוח עם ה-API של מפות Google ב-Wear OS

איך לספק את חוויית המשתמש הטובה ביותר באפליקציה:

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