درخواست به‌روزرسانی مکان

استفاده مناسب از اطلاعات مکان می‌تواند برای کاربران برنامه‌تان مفید باشد. برای مثال، اگر برنامه‌تان به کاربر کمک می‌کند مسیرش را هنگام پیاده‌روی یا رانندگی پیدا کند، یا اگر برنامه‌تان مکان دارایی‌ها را ردیابی می‌کند، باید مکان دستگاه را در فواصل زمانی منظم دریافت کند. علاوه‌بر مکان جغرافیایی (طول و عرض جغرافیایی)، ممکن است بخواهید اطلاعات بیشتری مانند جهت (جهت افقی حرکت)، ارتفاع، یا سرعت دستگاه را به کاربر ارائه دهید. این اطلاعات و موارد دیگر در شیء Location دردسترس است که برنامه‌تان می‌تواند از ارائه‌دهنده مکان تلفیقی بازیابی کند. در پاسخ، میانای برنامه‌سازی کاربردی به‌طور دوره‌ای برنامه‌تان را با بهترین مکان دردسترس، براساس ارائه‌دهندگان مکان دردسترس فعلی مانند Wi-Fi و GPS (سامانه موقعیت‌یابی جهانی) به‌روز می‌کند. دقت مکان توسط ارائه‌دهندگان، اجازه‌های مکانی که درخواست کرده‌اید، و گزینه‌هایی که در درخواست مکان تنظیم کرده‌اید تعیین می‌شود.

این درس به شما نشان می‌دهد که چگونه بااستفاده از روش requestLocationUpdates() در ارائه‌دهنده مکان تلفیقی، به‌روزرسانی‌های منظم درباره مکان دستگاه را درخواست کنید.

دریافت آخرین مکان مشخص

آخرین مکان شناخته‌شده دستگاه مبنای مفیدی برای شروع ارائه می‌دهد و تضمین می‌کند که برنامه قبل‌از شروع به‌روزرسانی‌های دوره‌ای مکان، مکان شناخته‌شده‌ای دارد. درس دریافت آخرین مکان شناخته‌شده به شما نشان می‌دهد چگونه با فراخوانی getLastLocation() آخرین مکان شناخته‌شده را دریافت کنید. قطعه‌های موجود در بخش‌های زیر فرض می‌کنند که برنامه‌تان قبلاً آخرین مکان معلوم را بازیابی کرده و آن را به‌عنوان شیء Location در متغیر سراسری mCurrentLocation ذخیره کرده است.

درخواست مکان کردن

قبل‌از درخواست به‌روزرسانی مکان، برنامه‌تان باید به خدمات مکان متصل شود و درخواست مکان کند. درس مربوط به تغییر تنظیمات مکان نحوه انجام این کار را به شما نشان می‌دهد. وقتی درخواست مکان برقرار شد، می‌توانید به‌روزرسانی‌های منظم را با فراخوانی requestLocationUpdates() شروع کنید.

بسته به شکل درخواست، ارائه‌دهنده مکان تلفیقی یا روش فراخوانی متقابل LocationCallback.onLocationResult() را فراخوانی می‌کند و فهرستی از اشیاء Location را به آن ارسال می‌کند، یا یک PendingIntent صادر می‌کند که حاوی مکان در داده‌های گسترش‌یافته آن است. دقت و دفعات به‌روزرسانی‌ها تحت‌تأثیر اجازه‌های مکانی که درخواست کرده‌اید و گزینه‌هایی که در شیء درخواست مکان تنظیم کرده‌اید قرار می‌گیرد.

این درس به شما نشان می‌دهد که چگونه بااستفاده از رویکرد فراخوانی برگشتی LocationCallback به‌روزرسانی را دریافت کنید. requestLocationUpdates() را فراخوانی کنید، نمونه شیء LocationRequest و LocationCallback را به آن ارسال کنید. همان‌طور که در نمونه کد زیر نشان داده شده است، یک روش startLocationUpdates() تعریف کنید:

کاتلین

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

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

جاوا

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

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

توجه داشته باشید که تکه‌کد بالا به پرچم بولی، requestingLocationUpdates، اشاره دارد که برای ردیابی اینکه کاربر به‌روزرسانی‌های مکان را روشن یا خاموش کرده است استفاده می‌شود. اگر کاربران به‌روزرسانی‌های مکان را خاموش کرده باشند، می‌توانید آن‌ها را از الزامات مکان برنامه‌تان مطلع کنید. برای کسب اطلاعات بیشتر درباره حفظ مقدار پرچم بولی در نمونه‌های فعالیت، به ذخیره کردن وضعیت فعالیت مراجعه کنید.

تعریف فراخوانی برگشتی به‌روزرسانی مکان

ارائه‌دهنده مکان تلفیقی روش فراخوانی LocationCallback.onLocationResult() را فراخوانی می‌کند. آرگومان ورودی حاوی شیء فهرست Location است که طول و عرض جغرافیایی مکان را دربرمی‌گیرد. تکه‌کد زیر نحوه پیاده‌سازی میانای LocationCallback و تعریف روش را نشان می‌دهد، سپس مُهر زمان به‌روزرسانی مکان را دریافت می‌کند و عرض جغرافیایی، طول جغرافیایی، و مُهر زمان را در میانای کاربر برنامه شما نمایش می‌دهد:

کاتلین

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

جاوا

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 را به آن ارسال کنید، همان‌طور که در نمونه کد زیر نشان داده شده است:

کاتلین

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

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

جاوا

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

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

از بولی requestingLocationUpdates برای ردیابی اینکه آیا به‌روزرسانی‌های مکان درحال‌حاضر روشن است یا نه استفاده کنید. در روش onResume() فعالیت، بررسی کنید که آیا به‌روزرسانی‌های مکان درحال‌حاضر فعال هستند یا نه، و اگر فعال نیستند آن‌ها را فعال کنید:

کاتلین

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

جاوا

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

ذخیره کردن وضعیت فعالیت

تغییر در پیکربندی دستگاه، مانند تغییر در جهت صفحه یا زبان، می‌تواند باعث ازبین رفتن فعالیت فعلی شود. بنابراین، برنامه شما باید هر اطلاعاتی را که برای بازآفرینی فعالیت نیاز دارد ذخیره کند. یک راه برای انجام این کار ازطریق وضعیت نمونه ذخیره‌شده در شیء Bundle است.

نمونه کد زیر نحوه استفاده از onSaveInstanceState() فراخوانی برگشتی فعالیت را برای ذخیره کردن وضعیت نمونه نشان می‌دهد:

کاتلین

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

جاوا

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

یک روش updateValuesFromBundle() را برای بازیابی مقادیر ذخیره‌شده از نمونه قبلی فعالیت تعریف کنید، اگر دردسترس باشند. همان‌طور که در نمونه کد زیر نشان داده شده است، متد را از متد onCreate() فعالیت فراخوانی کنید:

کاتلین

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

جاوا

@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 Activity مراجعه کنید.

توجه: برای فضای ذخیره‌سازی پایدارتر، می‌توانید اولویت‌های کاربر را در SharedPreferences برنامه‌تان ذخیره کنید. اولویت مشترک را در روش onPause() فعالیتتان تنظیم کنید و اولویت را در onResume() بازیابی کنید. برای اطلاعات بیشتر درباره ذخیره کردن اولویت‌ها، ذخیره کردن مجموعه‌های کلید-مقدار را بخوانید.

منابع بیشتر

برای کسب اطلاعات بیشتر، از منابع زیر استفاده کنید:

نمونه‌ها