المسار إلى وجهة واحدة

اتبع هذا الدليل لرسم مسار داخل تطبيقك إلى وجهة واحدة، باستخدام حزمة SDK للتنقل لنظام Android.

نظرة عامة

  1. ادمج حزمة تطوير البرامج (SDK) للتنقّل في تطبيقك، كما هو موضَّح في دليل الضبط.
  2. أضِف NavigationFragment أو NavigationView إلى تطبيقك. يؤدي عنصر واجهة المستخدم هذا إلى إضافة الخريطة التفاعلية وواجهة مستخدم التنقّل باتّجاهات مفصّلة إلى نشاطك.
  3. استخدِم الفئة NavigationApi لإعداد حزمة تطوير البرامج (SDK).
  4. حدِّد Navigator للتحكّم في التنقّل باتّجاهات مفصّلة:

    • أضِف وجهة باستخدام setDestination().
    • بدء التنقّل باستخدام startGuidance().
    • واستخدِم getSimulator() لمحاكاة تقدّم المركبة على طول المسار من أجل اختبار تطبيقك وتصحيح الأخطاء وعرض التطبيق.
  5. إنشاء تطبيقك وتشغيله

الاطّلاع على الرمز

إضافة جزء تنقل

NavigationFragment هو مكوِّن واجهة مستخدم يعرض الناتج المرئي للتنقّل، بما في ذلك الخريطة التفاعلية والاتجاهات المفصّلة. يمكنك الإعلان عن الجزء في ملف تنسيق XML كما هو موضح أدناه:

<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    android:name="com.google.android.libraries.navigation.NavigationFragment"
    android:id="@+id/navigation_fragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

ويمكنك بدلاً من ذلك إنشاء الجزء آليًا، كما هو موضّح في مستندات Android.

بالنسبة إلى التطبيقات التي تستخدم إصدار الدعم من Fragment، توفّر حزمة SDK الخاصة بالتنقل إمكانية التوافق من خلال SupportNavigationFragment. يعمل هذا الجزء بشكل خاص مع NavigationFragment، ويمكنك إدارته بشكل آلي باستخدام FragmentActivity.getSupportFragmentManager().

كبديل للجزء، يتوفّر مكوِّن واجهة المستخدم أيضًا على شكل NavigationView. يرجى ملاحظة المعلومات الموجودة في الجزء العلوي من وصف الفئة، لا سيما بخصوص مطلب إعادة توجيه أساليب دورة الحياة.

طلب إذن تحديد الموقع الجغرافي

يجب أن يطلب التطبيق إذن تحديد الموقع الجغرافي لتحديد موقع الجهاز.

يقدّم هذا الدليل التوجيهي الرمز الذي تحتاجه لطلب إذن تحديد الموقع الجغرافي الدقيق. للحصول على مزيد من التفاصيل، يُرجى الاطّلاع على دليل أذونات Android.

  1. أضِف الإذن كعنصر ثانوي للعنصر <manifest> في بيان Android:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.navsdksingledestination">
        <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    </manifest>
    
  2. اطلب أذونات التشغيل في تطبيقك، ما يمنح المستخدم فرصة السماح بإذن تحديد الموقع الجغرافي أو رفضه. يتحقق الرمز التالي مما إذا كان المستخدم قد منحك إذن تحديد الموقع المناسب إذا لم يكن كذلك، سيطلب الإذن:

    if (ContextCompat.checkSelfPermission(this.getApplicationContext(),
            android.Manifest.permission.ACCESS_FINE_LOCATION)
                == PackageManager.PERMISSION_GRANTED) {
        mLocationPermissionGranted = true;
    } else {
        ActivityCompat.requestPermissions(this,
                new String[] { android.Manifest.permission.ACCESS_FINE_LOCATION },
                PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
    }
    
    if (!mLocationPermissionGranted) {
        displayMessage("Error loading Navigation SDK: "
                + "The user has not granted location permission.");
        return;
    }
    
  3. يمكنك إلغاء معاودة الاتصال بـ onRequestPermissionsResult() لمعالجة نتيجة طلب الإذن:

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[],
                                           @NonNull int[] grantResults) {
        mLocationPermissionGranted = false;
        switch (requestCode) {
            case PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION: {
                // If request is canceled, the result arrays are empty.
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    mLocationPermissionGranted = true;
                }
            }
        }
    }
    

إعداد حزمة تطوير البرامج (SDK) للتنقّل وإعداد رحلة

توفر الفئة NavigationApi منطق إعداد يسمح لتطبيقك باستخدام ميزة التنقّل في Google. توفر الفئة Navigator إمكانية التحكم في ضبط وبدء/إيقاف رحلة التنقل.

  1. عليك إعداد حزمة تطوير البرامج (SDK) للتنقّل وإلغاء معاودة الاتصال بـ onNavigatorReady() لبدء التنقّل عندما يكون برنامج التنقّل جاهزًا.

  2. (اختياري) اضبط الرقم الأخير من لوحة الترخيص لتفعيل القيود على الطرق في البلدان التي تتوفّر فيها الميزة (البرازيل وإندونيسيا حاليًا). وفي حال استخدام هذا الاستدعاء لأي رموز بلدان أخرى، ستتجاهله واجهة برمجة التطبيقات. يجب إجراء هذا الاستدعاء مرة واحدة فقط. ستستمر طلبات الاتجاهات اللاحقة في استخدامه.

    NavigationApi.getNavigator(this, new NavigationApi.NavigatorListener() {
                /**
                 * Sets up the navigation UI when the navigator is ready for use.
                 */
                @Override
                public void onNavigatorReady(Navigator navigator) {
                    displayMessage("Navigator ready.");
                    mNavigator = navigator;
                    mNavFragment = (NavigationFragment) getFragmentManager()
                            .findFragmentById(R.id.navigation_fragment);
    
                    // Set the last digit of the car's license plate to get route restrictions
                    // in supported countries. (optional)
                    // mNavigator.setLicensePlateRestrictionInfo(getLastDigit(), "BZ");
    
                    // Set the camera to follow the device location with 'TILTED' driving view.
                    mNavFragment.getCamera().followMyLocation(Camera.Perspective.TILTED);
    
                    // Set the travel mode (DRIVING, WALKING, CYCLING, TWO_WHEELER, or TAXI).
                    mRoutingOptions =  new RoutingOptions();
                    mRoutingOptions.travelMode(RoutingOptions.TravelMode.DRIVING);
    
                    // Navigate to a place, specified by Place ID.
                    navigateToPlace(SYDNEY_OPERA_HOUSE, mRoutingOptions);
                }
    
                /**
                 * Handles errors from the Navigation SDK.
                 * @param errorCode The error code returned by the navigator.
                 */
                @Override
                public void onError(@NavigationApi.ErrorCode int errorCode) {
                    switch (errorCode) {
                        case NavigationApi.ErrorCode.NOT_AUTHORIZED:
                            displayMessage("Error loading Navigation SDK: Your API key is "
                                    + "invalid or not authorized to use the Navigation SDK.");
                            break;
                        case NavigationApi.ErrorCode.TERMS_NOT_ACCEPTED:
                            displayMessage("Error loading Navigation SDK: User did not accept "
                                    + "the Navigation Terms of Use.");
                            break;
                        case NavigationApi.ErrorCode.NETWORK_ERROR:
                            displayMessage("Error loading Navigation SDK: Network error.");
                            break;
                        case NavigationApi.ErrorCode.LOCATION_PERMISSION_MISSING:
                            displayMessage("Error loading Navigation SDK: Location permission "
                                    + "is missing.");
                            break;
                        default:
                            displayMessage("Error loading Navigation SDK: " + errorCode);
                    }
                }
            });
    
  3. باستخدام Navigator الوارد أعلاه، حدِّد وجهة Waypoint لهذه الرحلة. بعد احتساب الاتجاهات، تعرض سمة NavigationFragment خطوطًا متعدّدة تمثّل المسار على الخريطة وعلامة للوجهة.

    private void navigateToPlace(String placeId, RoutingOptions travelMode) {
        Waypoint destination;
        try {
            destination = Waypoint.builder().setPlaceIdString(placeId).build();
        } catch (Waypoint.UnsupportedPlaceIdException e) {
            displayMessage("Error starting navigation: Place ID is not supported.");
            return;
        }
    
        // Create a future to await the result of the asynchronous navigator task.
        ListenableResultFuture<Navigator.RouteStatus> pendingRoute =
                mNavigator.setDestination(destination, travelMode);
    
        // Define the action to perform when the SDK has determined the route.
        pendingRoute.setOnResultListener(
                new ListenableResultFuture.OnResultListener<Navigator.RouteStatus>() {
                    @Override
                    public void onResult(Navigator.RouteStatus code) {
                        switch (code) {
                            case OK:
                                // Hide the toolbar to maximize the navigation UI.
                                if (getActionBar() != null) {
                                    getActionBar().hide();
                                }
    
                                // Enable voice audio guidance (through the device speaker).
                                mNavigator.setAudioGuidance(
                                        Navigator.AudioGuidance.VOICE_ALERTS_AND_GUIDANCE);
    
                                // Simulate vehicle progress along the route for demo/debug builds.
                                if (BuildConfig.DEBUG) {
                                    mNavigator.getSimulator().simulateLocationsAlongExistingRoute(
                                            new SimulationOptions().speedMultiplier(5));
                                }
    
                                // Start turn-by-turn guidance along the current route.
                                mNavigator.startGuidance();
                                break;
                            // Handle error conditions returned by the navigator.
                            case NO_ROUTE_FOUND:
                                displayMessage("Error starting navigation: No route found.");
                                break;
                            case NETWORK_ERROR:
                                displayMessage("Error starting navigation: Network error.");
                                break;
                            case ROUTE_CANCELED:
                                displayMessage("Error starting navigation: Route canceled.");
                                break;
                            default:
                                displayMessage("Error starting navigation: "
                                        + String.valueOf(code));
                        }
                    }
                });
    }
    

إنشاء تطبيقك وتشغيله

  1. وصِّل جهاز Android بجهاز الكمبيوتر. اتّبِع instructions لتفعيل خيارات المطوّرين على جهاز Android وضبط نظامك لاكتشاف الجهاز. (بدلاً من ذلك، يمكنك استخدام مدير جهاز Android الافتراضي (AVD) لإعداد جهاز افتراضي. عند اختيار المحاكي، تأكد من اختيار صورة تتضمن Google APIs).
  2. في "استوديو Android"، انقر على خيار القائمة تشغيل (أو على رمز زر التشغيل). اختَر جهازًا كما هو مطلوب.

نصائح لتحسين تجربة المستخدم

  • يجب على المستخدم قبول بنود خدمة التنقل في Google قبل أن يصبح التنقل متاحًا. هذا القبول مطلوب مرة واحدة فقط. وبشكلٍ تلقائي، تطلب حزمة SDK القبول في المرة الأولى التي يتم فيها استدعاء برنامج التنقّل. يمكنك إن أردت تفعيل مربّع الحوار "بنود خدمة التنقّل" في مرحلة مبكرة من مسار تجربة المستخدم في تطبيقك، مثلاً أثناء الاشتراك أو تسجيل الدخول، وذلك باستخدام showTermsAndConditionsDialog().
  • تتحسن جودة التنقل ودقة الوقت المقدر للوصول بشكل كبير إذا كنت تستخدم أرقام تعريف الأماكن لتهيئة نقطة وسيطة، بدلاً من وجهة خطوط الطول/العرض.
  • يستخلص هذا النموذج نقطة الطريق الوجهة من رقم تعريف مكان معين (لدار أوبرا سيدني). يمكنك استخدام أداة البحث عن رقم تعريف المكان للحصول على معرّفات الأماكن لمواقع جغرافية محدّدة أخرى. وبدلاً من ذلك، يمكنك أن تمنح المستخدم فرصة لاختيار وجهة عن طريق إضافة أداة اختيار مكان إلى تطبيقك. لتجربة عينة عملية من أداة اختيار الأماكن باستخدام حزمة SDK للتنقل، يُرجى الاطّلاع على التطبيق التجريبي الموصوف في المقدمة.

الخطوة التالية

تعرَّف على كيفية الانتقال إلى وجهات متعدّدة في رحلة واحدة. إذا كان عقدك مع Google يحدّد الفوترة لكل معاملة، عليك إعداد المعاملات القابلة للفوترة.