Maps API على Wear OS

خريطة على جهاز قابل للارتداء

باستخدام حزمة تطوير البرامج بالاستناد إلى بيانات خرائط Google للتطبيقات المتوافقة مع Android، يمكنك إنشاء تطبيق مخصّص لجهاز قابل للارتداء يستند إلى الخرائط يعمل مباشرةً على أجهزة Wear OS من Google. يمكن لمستخدمي تطبيقك الاطّلاع على موقعهم الجغرافي على الخريطة بمجرّد النظر إلى معصمهم. يمكنهم تحديد موقعهم الجغرافي على مسار، على سبيل المثال، ثم تكبير الخريطة للاطّلاع على التفاصيل، أو النقر على علامة للاطّلاع على نافذة معلومات يوفّرها تطبيقك.

تصف هذه الصفحة وظائف واجهة برمجة التطبيقات المتوفّرة على جهاز قابل للارتداء وتساعدك في البدء في إنشاء تطبيقك.

البدء على Wear OS

إنشاء تطبيق مخصّص لجهاز قابل للارتداء باستخدام حزمة تطوير البرامج بالاستناد إلى بيانات خرائط Google للتطبيقات المتوافقة مع Android هو نفسه بشكل أساسي إنشاء تطبيق "خرائط Google" لأي جهاز Android آخر. ويكمن الاختلاف في تصميمك لعامل الشكل الأصغر للجهاز القابل للارتداء، وذلك لتحسين سهولة استخدام التطبيق وأدائه.

يُنصح باستخدام "استوديو Android" لتطوير تطبيقات Wear OS، لأنّه يوفّر سهولة إعداد المشاريع وتضمين المكتبات وتجميع الحِزم.

للحصول على مساعدة عامة في تصميم تطبيق مخصّص لجهاز قابل للارتداء، يُرجى الرجوع إلى الـ إرشادات تصميم Wear OS. للحصول على مساعدة في إنشاء أول تطبيق قابل للارتداء، يُرجى الاطّلاع على دليل إنشاء تطبيقات قابلة للارتداء.

إنشاء أول تطبيق خرائط على Wear OS

يفترض هذا الدليل السريع أنّك على دراية بحزمة تطوير البرامج بالاستناد إلى بيانات خرائط Google للتطبيقات المتوافقة مع Android، وأنّك اتّبعت أدلة Wear OS لإنشاء وحدة قابلة للارتداء في تطبيقك، وأنّك تريد الآن إضافة خريطة إلى الوحدة القابلة للارتداء.

إضافة التبعيات لوحدة Wear

تأكَّد من تضمين التبعيات التالية في ملف build.gradle.kts لوحدة Wear OS في تطبيقك:

dependencies {
    // ...
    // Modern Android projects use version catalogs to manage dependencies.  To include the necessary dependencies,
    // first add the following to your libs.versions.toml file:
    //
    // [versions]
    // playServicesMaps = "20.0.0"
    // wear = "1.3.0"
    // wearable = "2.9.0"
    //
    // [libraries]
    // play-services-maps = { group = "com.google.android.gms", name = "play-services-maps", version.ref = "playServicesMaps" }
    // wear = { group = "androidx.wear", name = "wear", version.ref = "wear" }
    // wearable-compile = { group = "com.google.android.wearable", name = "wearable", version.ref = "wearable" }
    // wearable-support = { group = "com.google.android.support", name = "wearable", version.ref = "wearable" }

    compileOnly(libs.wearable.compile)
    implementation(libs.wearable.support)
    implementation(libs.play.services.maps)

    // This dependency is necessary for ambient mode
    implementation(libs.wear)

    // Android Test Dependencies
    androidTestImplementation(libs.ext.junit)
    androidTestImplementation(libs.espresso.core)
    androidTestImplementation(libs.uiautomator)
    androidTestImplementation(libs.truth)
    androidTestImplementation(libs.junit)
    
    // If your project does not use a version catalog, you can use the following dependencies instead:
    //
    //    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:20.0.0")
    //    implementation("androidx.wear:wear:1.3.0")
    //    androidTestImplementation("androidx.test.ext:junit:1.1.5")
    //    androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
    //    androidTestImplementation("androidx.test.uiautomator:uiautomator:2.3.0")
    //    androidTestImplementation("com.google.truth:truth:1.4.2")
    //    androidTestImplementation("junit:junit:4.13.2")
}

لمزيد من المعلومات عن التبعيات، يُرجى الاطّلاع على دليل إضافة وحدة 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 في نشاطك، أضِف دالة ردّ اتصال واضبط سلوكها لتنفيذ إجراء الإغلاق اللازم كما هو موضّح أدناه:

Kotlin

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


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

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

    // ...
}

      

جافا

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

    // ...
}

      

إضافة خريطة

استخدِم طريقة ردّ الاتصال 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))
}

      

جافا

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

      

تفعيل "وضع الاستراحة"

تتوافق حزمة تطوير البرامج بالاستناد إلى بيانات خرائط Google للتطبيقات المتوافقة مع Android مع وضع عدم النشاط للتطبيقات القابلة للارتداء. تُسمّى التطبيقات التي تتوافق مع "وضع الاستراحة" أحيانًا تطبيقات قيد التشغيل دائمًا. يتم تفعيل "وضع الاستراحة" عندما لا يعود المستخدم يستخدم التطبيق بنشاط، ويسمح هذا الوضع ببقاء التطبيق مرئيًا على الجهاز القابل للارتداء.

توفّر حزمة تطوير البرامج بالاستناد إلى بيانات خرائط Google للتطبيقات المتوافقة مع Android عرضًا مبسطًا للخريطة بألوان قليلة لاستخدامه في وضع عدم النشاط، ويتم تعديل نمط الخريطة تلقائيًا عندما ينتقل الجهاز من الوضع التفاعلي إلى وضع عدم النشاط. تختفي جميع العلامات والكائنات وعناصر التحكّم في واجهة المستخدم في "وضع الاستراحة". يقلّل ذلك من استهلاك تطبيقك للطاقة ويضمن مظهرًا وإحساسًا متّسقَين مع التطبيقات الأخرى في "وضع الاستراحة"، مثل واجهات الساعة.

اتّبِع الخطوات التالية لضمان استخدام تطبيقك "وضع الاستراحة" للخريطة:

  1. حدِّث حزمة تطوير برامج Android لتضمين منصة Android 6.0 (المستوى 23 من واجهة برمجة التطبيقات) أو منصة أعلى، والتي توفّر واجهات برمجة التطبيقات التي تسمح للأنشطة بالانتقال إلى "وضع الاستراحة". لمعرفة كيفية تحديث حزمة تطوير البرامج (SDK)، يُرجى الاطّلاع على مستندات Android حول إضافة حِزم SDK.
  2. تأكَّد من أنّ مشروعك يستهدف Android 6.0 أو إصدارًا أعلى، وذلك من خلال ضبط الـ targetSdkVersion على 23 أو إصدار أعلى في بيان التطبيق.
  3. أضِف التبعيات القابلة للارتداء إلى ملف build.gradle.kts في تطبيقك. يُرجى الاطّلاع على الـ مثال في هذه الصفحة.
  4. أضِف إدخال المكتبة المشترَكة القابلة للارتداء إلى بيان التطبيق القابل للارتداء، كما هو موضّح في صف Android التدريبي حول إبقاء تطبيقك مرئيًا.
  5. أضِف إذن WAKE_LOCK إلى بيانَي التطبيق القابل للارتداء والتطبيق المحمول، كما هو موضّح في صف Android التدريبي حول إبقاء تطبيقك مرئيًا.
  6. في طريقة onCreate() لنشاطك، استخدِم طريقة AmbientModeSupport.attach(). يُعلم ذلك نظام التشغيل بأنّ التطبيق قيد التشغيل دائمًا، لذا يجب أن ينتقل إلى "وضع الاستراحة" بدلاً من العودة إلى واجهة الساعة عند إيقاف تشغيل الجهاز.
  7. نفِّذ واجهة AmbientModeSupport.AmbientCallbackProvider في نشاطك لكي يتمكّن من تلقّي تغييرات حالة "وضع الاستراحة".
  8. اضبط خريطتك لتتوافق مع "وضع الاستراحة". يمكنك إجراء ذلك عن طريق ضبط السمة map:ambientEnabled="true" في ملف تنسيق XML للنشاط، أو يمكنك إجراء ذلك برمجيًا عن طريق ضبط GoogleMapOptions.ambientEnabled(true). يُعلم هذا الإعداد واجهة برمجة التطبيقات بأنّ عليها تحميل مربّعات الخريطة اللازمة مسبقًا لاستخدامها في "وضع الاستراحة".
  9. عندما ينتقل النشاط إلى "وضع الاستراحة"، يستدعي النظام طريقة الـ onEnterAmbient() في الـ AmbientCallback التي تقدّمها. ألغِ onEnterAmbient() واستخدِم SupportMapFragment.onEnterAmbient(ambientDetails) أو MapView.onEnterAmbient(ambientDetails). تنتقل واجهة برمجة التطبيقات إلى عرض غير تفاعلي للخريطة بألوان قليلة.
  10. وبالمثل، في onExitAmbient()، استخدِم SupportMapFragment.onExitAmbient() أو MapView.onExitAmbient(). تنتقل واجهة برمجة التطبيقات إلى العرض العادي للخريطة.

تُفعِّل عينة التعليمات البرمجية التالية وضع عدم النشاط في النشاط:

Kotlin

class AmbientActivity : AppCompatActivity(), AmbientModeSupport.AmbientCallbackProvider {

    private lateinit var mapFragment: SupportMapFragment

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

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

      

جافا

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 التدريبي حول إبقاء تطبيقك مرئيًا.

استخدام ميزة "التجوّل الافتراضي" على Wear OS

تتوافق الأجهزة القابلة للارتداء بشكلٍ كامل مع ميزة "التجوّل الافتراضي".

للسماح للمستخدمين بالخروج من التطبيق عند عرض صورة بانورامية في "التجوّل الافتراضي"، استخدِم واجهة StreetViewPanorama.OnStreetViewPanoramaLongClickListener للاستماع إلى إيماءة النقر مع الاستمرار. عندما ينقر المستخدم مع الاستمرار في مكان ما على صورة "التجوّل الافتراضي"، ستتلقّى حدث onStreetViewPanoramaLongClick(StreetViewPanoramaOrientation). استخدِم DismissOverlayView.show() لعرض زر الخروج.

نموذج الرموز البرمجية

يتوفّر نموذج تطبيق على GitHub، ويمكنك استخدامه كنقطة بداية لتطبيقك. يوضّح لك النموذج كيفية إعداد "خريطة Google" أساسية على Wear OS.

الوظائف المتوافقة في Maps API على Wear OS

يُبرز هذا القسم الاختلافات في الوظائف المتوافقة للخرائط على الأجهزة القابلة للارتداء مقارنةً بالأجهزة المحمولة (الهواتف والأجهزة اللوحية). يجب أن تعمل جميع ميزات واجهة برمجة التطبيقات غير المذكورة أدناه كما هو موضّح في مستندات واجهة برمجة التطبيقات الكاملة.

الوظائف
الوضع التفاعلي الكامل والوضع البسيط

يمكنك استخدام حزمة تطوير البرامج بالاستناد إلى بيانات خرائط Google للتطبيقات المتوافقة مع Android في وضع التفاعل الكامل أو في الوضع البسيط. ننصحك باستخدام الوضع البسيط إذا كنت تريد تحسين الأداء على الجهاز القابل للارتداء ولا يحتاج تطبيقك إلى دعم التفاعل، مثل الإيماءات أو تحريك الخريطة وتكبيرها وتصغيرها.

في الوضع البسيط، يتم إيقاف هدف بدء تطبيق "خرائط Google" للأجهزة الجوّالة عندما ينقر المستخدم على الخريطة، ولا يمكن تفعيله على جهاز قابل للارتداء.

للاطّلاع على قائمة كاملة بالاختلافات بين الوضع البسيط والوضع التفاعلي الكامل ، يُرجى الرجوع إلى مستندات الوضع البسيط.

شريط أدوات الخريطة يتم إيقاف شريط أدوات الخريطة ولا يمكن تفعيله على جهاز قابل للارتداء.
عناصر التحكّم في واجهة المستخدم يتم إيقاف عناصر التحكّم في واجهة المستخدم تلقائيًا على الأجهزة القابلة للارتداء. ويشمل ذلك عناصر التحكّم في التكبير/التصغير والبوصلة والموقع الجغرافي. يمكنك تفعيلها باستخدام الفئة UiSettings كالمعتاد.
الإيماءات تعمل إيماءات اللمس بإصبع واحد على النحو المتوقّع. تشمل الأمثلة النقر مع السحب لتحريك الخريطة، والنقر مرّتين للتكبير، والنقر بإصبعَين للتصغير. يختلف الدعم لإيماءات اللمس المتعدد حسب جهاز المستخدم. تشمل أمثلة إيماءات اللمس المتعدد الدفع بإصبعَين لإمالة الخريطة، التصغير بإصبعَين، والتدوير بإصبعَين.
الخرائط الداخلية والمباني يتم إيقاف الخرائط الداخلية تلقائيًا على الجهاز القابل للارتداء. يمكنك تفعيلها عن طريق استدعاء GoogleMap.setIndoorEnabled(true). إذا كانت الخرائط الداخلية مفعّلة، ستعرض الخريطة مستوى الطابق التلقائي. لا تتوافق الأجهزة القابلة للارتداء مع عنصر واجهة المستخدم الخاص بمحدّد الـ مستوى.
تراكبات مربّعات لا تتوافق الأجهزة القابلة للارتداء مع تراكبات المربّعات.

أفضل الممارسات للتطوير باستخدام Maps API على Wear OS

كيفية تقديم أفضل تجربة للمستخدم في تطبيقك:

  • يجب أن تشغل الخريطة جزءًا كبيرًا من الشاشة. هذا ضروري لتحسين سهولة استخدام الخريطة على عامل الشكل الصغير للجهاز القابل للارتداء.
  • عند تصميم تجربة المستخدم في تطبيقك، ضَع في الاعتبار أنّ الجهاز القابل للارتداء لديه طاقة بطارية منخفضة. سيؤثر إبقاء الشاشة نشطة والخريطة مرئية في أداء البطارية.