طلب تعديلات على الموقع الجغرافي

يمكن أن يكون الاستخدام المناسب لمعلومات عن الموقع الجغرافي للجهاز مفيدًا لمستخدمي تطبيقك. على سبيل المثال، إذا كان تطبيقك يساعد المستخدم في العثور على طريقه أثناء المشي أو القيادة، أو إذا كان تطبيقك يتتبّع الموقع الجغرافي لمواد العرض، يجب أن يحصل على الموقع الجغرافي للجهاز على فترات منتظمة. بالإضافة إلى الموقع الجغرافي (خط العرض وخط الطول)، قد ترغب في تزويد المستخدم بمزيد من المعلومات مثل الاتجاه (اتجاه السفر الأفقي) أو الارتفاع أو سرعة الجهاز. تتوفّر هذه المعلومات وغيرها في عنصر Location الذي يمكن لتطبيقك استرداده من موفِّر الموقع المدمج. في المقابل، تعدّل واجهة برمجة التطبيقات تطبيقك بشكل دوري بأفضل موقع جغرافي متاح، استنادًا إلى مقدّمي خدمة الموقع الجغرافي المتاحين حاليًا مثل شبكة WiFi ونظام تحديد المواقع العالمي (GPS). يتم تحديد دقة الموقع الجغرافي من خلال مقدّمي الخدمة وأذونات تحديد الموقع الجغرافي التي طلبتها والخيارات التي حدّدتها في طلب تحديد الموقع الجغرافي.

يوضّح لك هذا الدرس كيفية طلب تحديثات منتظمة حول الموقع الجغرافي لجهاز معيّن باستخدام طريقة requestLocationUpdates() في موفِّر الموقع المدمج.

الحصول على آخر موقع جغرافي معروف

يوفّر آخر موقع جغرافي معروف للجهاز قاعدة مفيدة للبدء منها، ما يضمن حصول التطبيق على موقع جغرافي معروف قبل بدء التعديلات الدورية للموقع الجغرافي. يوضّح لك الدرس حول الحصول على آخر موقع جغرافي معروف كيفية الحصول على آخر موقع جغرافي معروف من خلال استدعاء getLastLocation(). تفترض المقتطفات في الأقسام التالية أنّ تطبيقك قد استردّ آخر موقع جغرافي معروف وخزّنه كعنصر Location في المتغيّر العمومي mCurrentLocation.

تقديم طلب لمعرفة الموقع الجغرافي

قبل طلب إشعارات بشأن الموقع الجغرافي، يجب أن يتصل تطبيقك بخدمات الموقع الجغرافي وأن يقدّم طلبًا للحصول على الموقع الجغرافي. يوضّح لك الدرس حول تغيير إعدادات الموقع الجغرافي كيفية إجراء ذلك. بعد إرسال طلب الموقع الجغرافي، يمكنك بدء التحديثات المنتظمة من خلال استدعاء requestLocationUpdates().

استنادًا إلى شكل الطلب، يستدعي موفِّر الموقع المدمج طريقة رد الاتصال LocationCallback.onLocationResult() ويمرّر إليها قائمة بعناصر Location، أو يُصدر PendingIntent يحتوي على الموقع الجغرافي في بياناته الموسّعة. تتأثر دقة التعديلات ومعدّل تكرارها بأذونات تحديد الموقع الجغرافي التي طلبتها والخيارات التي حدّدتها في عنصر طلب الموقع الجغرافي.

يوضّح لك هذا الدرس كيفية الحصول على التحديث باستخدام طريقة معاودة الاتصال LocationCallback. استدعِ الدالة requestLocationUpdates()، ومرِّر إليها مثيل عنصر LocationRequest وLocationCallback. حدِّد طريقة startLocationUpdates() كما هو موضّح في عينة تعليمات برمجية التالية:

Kotlin

override fun onResume() {
    super.onResume()
    if (requestingLocationUpdates) startLocationUpdates()
}

private fun startLocationUpdates() {
    fusedLocationClient.requestLocationUpdates(locationRequest,
            locationCallback,
            Looper.getMainLooper())
}

Java

@Override
protected void onResume() {
    super.onResume();
    if (requestingLocationUpdates) {
        startLocationUpdates();
    }
}

private void startLocationUpdates() {
    fusedLocationClient.requestLocationUpdates(locationRequest,
            locationCallback,
            Looper.getMainLooper());
}

يُرجى ملاحظة أنّ مقتطف الرمز أعلاه يشير إلى علامة منطقية، requestingLocationUpdates، تُستخدَم لتتبُّع ما إذا كان المستخدم قد فعّل الإشعارات بشأن الموقع الجغرافي أو أوقفها. إذا أوقف المستخدمون الإشعارات بشأن الموقع الجغرافي، يمكنك إبلاغهم بمتطلبات الموقع الجغرافي لتطبيقك. لمزيد من المعلومات حول الاحتفاظ بقيمة العلامة المنطقية في جميع نُسخ النشاط، يُرجى الاطّلاع على حفظ حالة النشاط.

تحديد معاودة الاتصال لإشعار بشأن الموقع الجغرافي

يستدعي موفِّر الموقع المدمج طريقة رد الاتصال LocationCallback.onLocationResult(). تحتوي الوسيطة الواردة على كائن قائمة Location يحتوي على خط العرض وخط الطول للموقع الجغرافي. يوضّح المقتطف التالي كيفية تنفيذ واجهة LocationCallback وتحديد الطريقة، ثم الحصول على الطابع الزمني لإشعار بشأن الموقع الجغرافي وعرض خط العرض وخط الطول والطابع الزمني على واجهة مستخدم تطبيقك:

Kotlin

private lateinit var locationCallback: LocationCallback

// ...

override fun onCreate(savedInstanceState: Bundle?) {
    // ...

    locationCallback = object : LocationCallback() {
        override fun onLocationResult(locationResult: LocationResult?) {
            locationResult ?: return
            for (location in locationResult.locations){
                // Update UI with location data
                // ...
            }
        }
    }
}

Java

private LocationCallback locationCallback;

// ...

@Override
protected void onCreate(Bundle savedInstanceState) {
    // ...

    locationCallback = new LocationCallback() {
        @Override
        public void onLocationResult(LocationResult locationResult) {
            if (locationResult == null) {
                return;
            }
            for (Location location : locationResult.getLocations()) {
                // Update UI with location data
                // ...
            }
        }
    };
}

إيقاف الإشعارات بشأن الموقع الجغرافي

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

لإيقاف الإشعارات بشأن الموقع الجغرافي، يمكنك استدعاء removeLocationUpdates()، وتمرير LocationCallback، كما هو موضّح في عينة التعليمات البرمجية التالية:

Kotlin

override fun onPause() {
    super.onPause()
    stopLocationUpdates()
}

private fun stopLocationUpdates() {
    fusedLocationClient.removeLocationUpdates(locationCallback)
}

Java

@Override
protected void onPause() {
    super.onPause();
    stopLocationUpdates();
}

private void stopLocationUpdates() {
    fusedLocationClient.removeLocationUpdates(locationCallback);
}

استخدِم قيمة منطقية، requestingLocationUpdates، لتتبُّع ما إذا كانت الإشعارات بشأن الموقع الجغرافي مفعَّلة حاليًا. في طريقة onResume() للنشاط، تحقَّق مما إذا كانت الإشعارات بشأن الموقع الجغرافي نشطة حاليًا، وفعِّلها إذا لم تكن كذلك:

Kotlin

override fun onResume() {
    super.onResume()
    if (requestingLocationUpdates) startLocationUpdates()
}

Java

@Override
protected void onResume() {
    super.onResume();
    if (requestingLocationUpdates) {
        startLocationUpdates();
    }
}

حفظ حالة النشاط

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

تعرض عينة التعليمات البرمجية التالية كيفية استخدام دالة الاستدعاء onSaveInstanceState() للنشاط من أجل حفظ حالة المثيل:

Kotlin

override fun onSaveInstanceState(outState: Bundle?) {
    outState?.putBoolean(REQUESTING_LOCATION_UPDATES_KEY, requestingLocationUpdates)
    super.onSaveInstanceState(outState)
}

Java

@Override
protected void onSaveInstanceState(Bundle outState) {
    outState.putBoolean(REQUESTING_LOCATION_UPDATES_KEY,
            requestingLocationUpdates);
    // ...
    super.onSaveInstanceState(outState);
}

حدِّد طريقة updateValuesFromBundle() لاستعادة القيم المحفوظة من المثيل السابق للنشاط، إذا كانت متاحة. استدعِ الطريقة من طريقة onCreate() الخاصة بالنشاط، كما هو موضّح في عيّنة التعليمات البرمجية التالية:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    // ...
    updateValuesFromBundle(savedInstanceState)
}

private fun updateValuesFromBundle(savedInstanceState: Bundle?) {
    savedInstanceState ?: return

    // Update the value of requestingLocationUpdates from the Bundle.
    if (savedInstanceState.keySet().contains(REQUESTING_LOCATION_UPDATES_KEY)) {
        requestingLocationUpdates = savedInstanceState.getBoolean(
                REQUESTING_LOCATION_UPDATES_KEY)
    }

    // ...

    // Update UI to match restored state
    updateUI()
}

Java

@Override
public void onCreate(Bundle savedInstanceState) {
    // ...
    updateValuesFromBundle(savedInstanceState);
}

private void updateValuesFromBundle(Bundle savedInstanceState) {
    if (savedInstanceState == null) {
        return;
    }

    // Update the value of requestingLocationUpdates from the Bundle.
    if (savedInstanceState.keySet().contains(REQUESTING_LOCATION_UPDATES_KEY)) {
        requestingLocationUpdates = savedInstanceState.getBoolean(
                REQUESTING_LOCATION_UPDATES_KEY);
    }

    // ...

    // Update UI to match restored state
    updateUI();
}

لمزيد من المعلومات حول حفظ حالة المثيل، يُرجى الاطّلاع على مرجع فئة نشاط Android.

ملاحظة: لتوفير مساحة تخزين أكثر استدامة، يمكنك تخزين الإعدادات المفضّلة للمستخدم في SharedPreferences الخاصة بتطبيقك. اضبط الإعدادات المفضّلة المشتركة في إجراء onPause() الخاص بالنشاط، واسترجع الإعدادات المفضّلة في onResume(). لمزيد من المعلومات حول حفظ الإعدادات المفضّلة، يُرجى الاطّلاع على مقالة حفظ مجموعات المفاتيح والقيم.

مراجع إضافية

لمزيد من المعلومات، يمكنك الاستفادة من المراجع التالية:

نماذج

  • نموذج تطبيق لتوضيح كيفية تلقّي إشعارات بشأن الموقع الجغرافي في Android