0Pricing
Android Academy · درس

الحصول على موقع المستخدم

أساسيات موفّر الموقع المدمج

الحصول على موقع المستخدم درس مجاني في Android Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Android Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Android Academy 4 دروس في المجموع.

أين يوجد المستخدم؟

تبدأ معظم التطبيقات التي تعتمد على الموقع بسؤال واحد: أين يوجد الجهاز الآن؟ يجيب Android عن ذلك من خلال Fused Location Provider، وهو جزء من Google Play services.

في هذا الدرس ستضيف الاعتمادية، وتطلب موقعًا واحدًا، وتصغي إلى التحديثات المستمرة، وتعرض النتيجة في Compose.

لماذا نستخدم Fused Provider؟

يمتلك Android عدة مصادر للموقع: GPS وشبكات Wi-Fi وأبراج الاتصالات. ويدمج Fused Location Provider هذه المصادر بذكاء ليمنحك أفضل موقع مع أقل استهلاك للبطارية.

نادرًا ما تستخدم LocationManager الخام مباشرةً في الوقت الحالي — فالعميل الموحّد أبسط وأكثر ذكاءً.

// build.gradle.kts (module)
dependencies {
    implementation("com.google.android.gms:play-services-location:21.3.0")
}

التصريح بالإذن

الموقع مورد حساس. صرّح بالإذن في AndroidManifest.xml. استخدم ACCESS_FINE_LOCATION لتحديد الموقع بدقة، أو ACCESS_COARSE_LOCATION للحصول على موقع تقريبي.

التصريح بالإذن ليس سوى الخطوة الأولى — يجب أيضًا طلبه في وقت التشغيل (وسيتناول درس لاحق ذلك).

<!-- AndroidManifest.xml -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

إنشاء العميل الموحّد

احصل على FusedLocationProviderClient من LocationServices. في Compose، احصل على السياق باستخدام LocalContext.current وتذكّر العميل حتى لا يُعاد إنشاؤه عند كل إعادة تركيب.

import com.google.android.gms.location.LocationServices

@Composable
fun rememberFusedClient() = run {
    val context = LocalContext.current
    remember {
        LocationServices.getFusedLocationProviderClient(context)
    }
}

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

أسرع إجابة هي lastLocation — أحدث إحداثية خزّنها النظام مؤقتًا. وهي تُرجع Task، لذا أضف مستمعًا للنجاح.

قد تكون النتيجة null إذا لم يطلب أي تطبيق الموقع مؤخرًا، لذلك تحقّق دائمًا من عدم كونها null.

@SuppressLint("MissingPermission")
fun fetchLastLocation(
    client: FusedLocationProviderClient,
    onResult: (Location?) -> Unit
) {
    client.lastLocation
        .addOnSuccessListener { location -> onResult(location) }
        .addOnFailureListener { onResult(null) }
}

انتظار المهمة باستخدام Coroutines

تتداخل دوال ردّ النداء بسرعة. تضيف مكتبة kotlinx-coroutines-play-services الدالة .await()، بحيث يمكنك قراءة الموقع باستخدام كود تعليق واضح.

import kotlinx.coroutines.tasks.await

@SuppressLint("MissingPermission")
suspend fun currentLastLocation(
    client: FusedLocationProviderClient
): Location? {
    return client.lastLocation.await()
}

طلب موقع حديث

قد تكون قيمة lastLocation قديمة. للحصول على إحداثية حديثة، استدعِ getCurrentLocation مع تحديد مستوى الأولوية. يستخدم PRIORITY_HIGH_ACCURACY نظام GPS، بينما يوفّر PRIORITY_BALANCED_POWER_ACCURACY طاقة البطارية.

import com.google.android.gms.location.Priority
import com.google.android.gms.location.CurrentLocationRequest

@SuppressLint("MissingPermission")
suspend fun freshLocation(
    client: FusedLocationProviderClient
): Location? {
    val request = CurrentLocationRequest.Builder()
        .setPriority(Priority.PRIORITY_HIGH_ACCURACY)
        .build()
    return client.getCurrentLocation(request, null).await()
}

تحديثات الموقع المستمرة

تحتاج إلى تدفّق من التحديثات عند استخدام الملاحة أو التتبع. أنشئ LocationRequest مع تحديد فاصل زمني، ثم سجّل LocationCallback باستخدام requestLocationUpdates.

أوقف التحديثات دائمًا عند الانتهاء لتوفير طاقة البطارية.

import com.google.android.gms.location.LocationRequest
import com.google.android.gms.location.LocationResult
import com.google.android.gms.location.LocationCallback

val request = LocationRequest.Builder(
    Priority.PRIORITY_HIGH_ACCURACY,
    5000L // 5 seconds
).build()

val callback = object : LocationCallback() {
    override fun onLocationResult(result: LocationResult) {
        result.lastLocation?.let { /* use it */ }
    }
}

التحديثات بوصفها Flow

يغلّف النمط النظيف التحديثات داخل callbackFlow، بحيث يجمع المستهلكون المواقع، وتتوقف التحديثات تلقائيًا عند انتهاء الجمع من خلال awaitClose.

import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.callbackFlow

@SuppressLint("MissingPermission")
fun FusedLocationProviderClient.locationFlow(request: LocationRequest) = callbackFlow {
    val cb = object : LocationCallback() {
        override fun onLocationResult(result: LocationResult) {
            result.lastLocation?.let { trySend(it) }
        }
    }
    requestLocationUpdates(request, cb, Looper.getMainLooper())
    awaitClose { removeLocationUpdates(cb) }
}

عرض الموقع في Compose

اجمع النتيجة داخل مكوّن قابل للتركيب باستخدام LaunchedEffect لقراءة تُنفّذ مرة واحدة، أو باستخدام collectAsStateWithLifecycle لتدفّق مستمر. ثم اعرض الإحداثيات.

@Composable
fun LocationLabel(client: FusedLocationProviderClient) {
    var location by remember { mutableStateOf<Location?>(null) }
    LaunchedEffect(Unit) {
        location = freshLocation(client)
    }
    Text(
        location?.let { "Lat ${it.latitude}, Lng ${it.longitude}" }
            ?: "Locating..."
    )
}

الموازنة بين البطارية والدقة

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

تستنزف الدقة العالية والتحديثات المتكررة البطارية بسرعة — لذلك خصّصهما للملاحة النشطة.

اختبار سريع

تحتاج إلى الموقع الحالي الأكثر دقة مرة واحدة، باستخدام دالة تعليق. ما الأسلوب الأنسب؟

مراجعة

يمكنك الآن قراءة موقع الجهاز:

  • أضف play-services-location وصرّح بـ ACCESS_FINE/COARSE_LOCATION.
  • احصل على FusedLocationProviderClient من LocationServices.
  • استخدم lastLocation للحصول على إحداثية مخزّنة مؤقتًا، وgetCurrentLocation للحصول على إحداثية حديثة.
  • تلقَّ التحديثات عبر requestLocationUpdates أو callbackFlow، وأوقفها لتوفير طاقة البطارية.

التالي: رسم العلامات وتحريك الكاميرا إلى تلك الإحداثيات.

الأسئلة الشائعة

هل درس «الحصول على موقع المستخدم» مجاني؟

نعم — نص درس «الحصول على موقع المستخدم» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Android Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Android Academy 4 دروس في المجموع.

ماذا ستتعلم في «الحصول على موقع المستخدم»؟

أساسيات موفّر الموقع المدمج تتمرن على Android Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Android Academy؟

لا تُشترط خبرة سابقة. Android Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.

كم من الوقت يستغرق درس «الحصول على موقع المستخدم»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Android Academy هذا؟

نعم. كل درس في Android Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. عرض خريطة
  2. الحصول على موقع المستخدم
  3. العلامات والكاميرا
  4. أذونات الموقع بالطريقة الصحيحة
← العودة إلى Android Academy